Skip to content
Browse files

Site updated at 2013-06-27 22:03:45 UTC

  • Loading branch information...
1 parent e1fe744 commit 39dbbfec6cdd123ac49b696dcdf422cc2d6f5076 @dcramer committed
View
18 2013/06/27/serving-python-web-applications/index.html
@@ -79,12 +79,12 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
<p><strong>I am going to convince you that nginx + uwsgi is the best, and only way you
should be serving your Python web application, with a slight twist.</strong></p>
-<h2>Serving Strategies</h2>
+<h1>Serving Strategies</h1>
<p>There&#8217;s quite a number of ways you can run a Python application. I&#8217;ll
illustrate a few for you.</p>
-<h1>mod_wsgi</h1>
+<h2>mod_wsgi</h2>
<p>Pretty straight forward. Install mod_wsgi with Apache, and either serve it
embedded or use a wsgi daemon process.</p>
@@ -95,7 +95,7 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
<p>We&#8217;ll skip going into configuration methodologies for mod_wsgi, as it&#8217;s not
the focus of this article.</p>
-<h1>gunicorn</h1>
+<h2>gunicorn</h2>
<p>When you move past mod_wsgi your solutions are basically only Python web
servers. One of the most popular (read: trendy) methods has been gunicorn
@@ -115,7 +115,7 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
never work anywhere in Python, so unless you&#8217;re sitting in the fairytale land
where they&#8217;re working, it provides you no advantages here.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>The only alternative, in my opinion, to gunicorn is uwsgi. It&#8217;s slightly more
performant, has too many configuration options to every understand, and also
@@ -137,7 +137,7 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
<p>(For what it&#8217;s worth, Disqus runs single threaded, but I&#8217;m cheap, and I wanted
to keep Sentry as lean as possible, which means squeezing capacity out of nodes)</p>
-<h2>Iterating to Success</h2>
+<h1>Iterating to Success</h1>
<p>I was pretty proud when we got API response times down to 40ms on average. When
I say API I&#8217;m only talking about the time it takes from it hitting the Python
@@ -159,13 +159,13 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
<p><img src="/images/posts/consistent-api-times.png" alt="API Times" /></p>
-<h2>Putting It Together</h2>
+<h1>Putting It Together</h1>
<p>Because I like when people do more than talk, I wanted to leave everyone with
some snippets of code from our Chef recipes which we used to actually set all
of this up on the servers (with minimal effort).</p>
-<h1>nginx</h1>
+<h2>nginx</h2>
<p>The first piece of configuration is Nginx. We need to actually programatically
add backends based on the number of uwsgi processes we&#8217;re running, so things
@@ -259,7 +259,7 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
web processes, started at port 9000. It&#8217;s also been configured to serve
uwsgi using it&#8217;s socket protocol.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>On the other side of things, we&#8217;re using supervisor to control our uwsgi
processes, so things are pretty straightforward here as well:</p>
@@ -301,7 +301,7 @@ <h1 class="title">You Should Be Using Nginx + UWSGI</h1>
</span></code></pre></td></tr></table></div></figure>
-<h2>One Way, and Only One Way</h2>
+<h1>One Way, and Only One Way</h1>
<p>Unless someone comes up with an extremely convincing argument why there should
be another way (or a situation where this can&#8217;t work), I hope to hear this
View
20 atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[David Cramer's Blog]]></title>
<link href="http://justcramer.com/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
@@ -26,12 +26,12 @@ the most peformance out of your web boxes.</p>
<p><strong>I am going to convince you that nginx + uwsgi is the best, and only way you
should be serving your Python web application, with a slight twist.</strong></p>
-<h2>Serving Strategies</h2>
+<h1>Serving Strategies</h1>
<p>There&#8217;s quite a number of ways you can run a Python application. I&#8217;ll
illustrate a few for you.</p>
-<h1>mod_wsgi</h1>
+<h2>mod_wsgi</h2>
<p>Pretty straight forward. Install mod_wsgi with Apache, and either serve it
embedded or use a wsgi daemon process.</p>
@@ -42,7 +42,7 @@ I gave up on tuning this long ago.</p>
<p>We&#8217;ll skip going into configuration methodologies for mod_wsgi, as it&#8217;s not
the focus of this article.</p>
-<h1>gunicorn</h1>
+<h2>gunicorn</h2>
<p>When you move past mod_wsgi your solutions are basically only Python web
servers. One of the most popular (read: trendy) methods has been gunicorn
@@ -62,7 +62,7 @@ it through nginx or Apache.</p>
never work anywhere in Python, so unless you&#8217;re sitting in the fairytale land
where they&#8217;re working, it provides you no advantages here.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>The only alternative, in my opinion, to gunicorn is uwsgi. It&#8217;s slightly more
performant, has too many configuration options to every understand, and also
@@ -84,7 +84,7 @@ try and max CPU on my servers. There were two goals here:</p>
<p>(For what it&#8217;s worth, Disqus runs single threaded, but I&#8217;m cheap, and I wanted
to keep Sentry as lean as possible, which means squeezing capacity out of nodes)</p>
-<h2>Iterating to Success</h2>
+<h1>Iterating to Success</h1>
<p>I was pretty proud when we got API response times down to 40ms on average. When
I say API I&#8217;m only talking about the time it takes from it hitting the Python
@@ -106,13 +106,13 @@ separate uwsgi processes.</p>
<p><img src="http://justcramer.com/images/posts/consistent-api-times.png" alt="API Times" /></p>
-<h2>Putting It Together</h2>
+<h1>Putting It Together</h1>
<p>Because I like when people do more than talk, I wanted to leave everyone with
some snippets of code from our Chef recipes which we used to actually set all
of this up on the servers (with minimal effort).</p>
-<h1>nginx</h1>
+<h2>nginx</h2>
<p>The first piece of configuration is Nginx. We need to actually programatically
add backends based on the number of uwsgi processes we&#8217;re running, so things
@@ -206,7 +206,7 @@ became a bit more complicated.</p>
web processes, started at port 9000. It&#8217;s also been configured to serve
uwsgi using it&#8217;s socket protocol.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>On the other side of things, we&#8217;re using supervisor to control our uwsgi
processes, so things are pretty straightforward here as well:</p>
@@ -248,7 +248,7 @@ processes, so things are pretty straightforward here as well:</p>
</span></code></pre></td></tr></table></div></figure>
-<h2>One Way, and Only One Way</h2>
+<h1>One Way, and Only One Way</h1>
<p>Unless someone comes up with an extremely convincing argument why there should
be another way (or a situation where this can&#8217;t work), I hope to hear this
View
2 categories/ci/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: ci | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/ci/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/disqus/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: disqus | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/disqus/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/django/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: django | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/django/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/git/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: git | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/git/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/heroku/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: heroku | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/heroku/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/howto/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: howto | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/howto/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/ops/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: ops | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/ops/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/osx/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: osx | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/osx/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/postgresql/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: postgresql | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/postgresql/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
20 categories/python/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: python | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/python/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
@@ -26,12 +26,12 @@ the most peformance out of your web boxes.</p>
<p><strong>I am going to convince you that nginx + uwsgi is the best, and only way you
should be serving your Python web application, with a slight twist.</strong></p>
-<h2>Serving Strategies</h2>
+<h1>Serving Strategies</h1>
<p>There's quite a number of ways you can run a Python application. I'll
illustrate a few for you.</p>
-<h1>mod_wsgi</h1>
+<h2>mod_wsgi</h2>
<p>Pretty straight forward. Install mod_wsgi with Apache, and either serve it
embedded or use a wsgi daemon process.</p>
@@ -42,7 +42,7 @@ I gave up on tuning this long ago.</p>
<p>We'll skip going into configuration methodologies for mod_wsgi, as it's not
the focus of this article.</p>
-<h1>gunicorn</h1>
+<h2>gunicorn</h2>
<p>When you move past mod_wsgi your solutions are basically only Python web
servers. One of the most popular (read: trendy) methods has been gunicorn
@@ -62,7 +62,7 @@ it through nginx or Apache.</p>
never work anywhere in Python, so unless you're sitting in the fairytale land
where they're working, it provides you no advantages here.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>The only alternative, in my opinion, to gunicorn is uwsgi. It's slightly more
performant, has too many configuration options to every understand, and also
@@ -84,7 +84,7 @@ try and max CPU on my servers. There were two goals here:</p>
<p>(For what it's worth, Disqus runs single threaded, but I'm cheap, and I wanted
to keep Sentry as lean as possible, which means squeezing capacity out of nodes)</p>
-<h2>Iterating to Success</h2>
+<h1>Iterating to Success</h1>
<p>I was pretty proud when we got API response times down to 40ms on average. When
I say API I'm only talking about the time it takes from it hitting the Python
@@ -106,13 +106,13 @@ separate uwsgi processes.</p>
<p><img src="/images/posts/consistent-api-times.png" alt="API Times" /></p>
-<h2>Putting It Together</h2>
+<h1>Putting It Together</h1>
<p>Because I like when people do more than talk, I wanted to leave everyone with
some snippets of code from our Chef recipes which we used to actually set all
of this up on the servers (with minimal effort).</p>
-<h1>nginx</h1>
+<h2>nginx</h2>
<p>The first piece of configuration is Nginx. We need to actually programatically
add backends based on the number of uwsgi processes we're running, so things
@@ -177,7 +177,7 @@ include uwsgi_params;
web processes, started at port 9000. It's also been configured to serve
uwsgi using it's socket protocol.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>On the other side of things, we're using supervisor to control our uwsgi
processes, so things are pretty straightforward here as well:</p>
@@ -203,7 +203,7 @@ processes, so things are pretty straightforward here as well:</p>
end
```</p>
-<h2>One Way, and Only One Way</h2>
+<h1>One Way, and Only One Way</h1>
<p>Unless someone comes up with an extremely convincing argument why there should
be another way (or a situation where this can't work), I hope to hear this
View
2 categories/sentry/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: sentry | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/sentry/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 categories/solr/atom.xml
@@ -4,7 +4,7 @@
<title><![CDATA[Category: solr | David Cramer's Blog]]></title>
<link href="http://justcramer.com/categories/solr/atom.xml" rel="self"/>
<link href="http://justcramer.com/"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
<author>
<name><![CDATA[David Cramer]]></name>
View
2 disqus.xml
@@ -2,7 +2,7 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<title>JustCramer</title>
<link href="http://justcramer.com/atom.xml" rel="self"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
View
2 django.xml
@@ -2,7 +2,7 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<title>JustCramer</title>
<link href="http://justcramer.com/atom.xml" rel="self"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
View
2 feeds/disqus.xml
@@ -2,7 +2,7 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<title>JustCramer</title>
<link href="http://justcramer.com/atom.xml" rel="self"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
View
2 feeds/django.xml
@@ -2,7 +2,7 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<title>JustCramer</title>
<link href="http://justcramer.com/atom.xml" rel="self"/>
- <updated>2013-06-27T15:01:47-07:00</updated>
+ <updated>2013-06-27T15:03:19-07:00</updated>
<id>http://justcramer.com/</id>
View
18 index.html
@@ -83,12 +83,12 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
<p><strong>I am going to convince you that nginx + uwsgi is the best, and only way you
should be serving your Python web application, with a slight twist.</strong></p>
-<h2>Serving Strategies</h2>
+<h1>Serving Strategies</h1>
<p>There&#8217;s quite a number of ways you can run a Python application. I&#8217;ll
illustrate a few for you.</p>
-<h1>mod_wsgi</h1>
+<h2>mod_wsgi</h2>
<p>Pretty straight forward. Install mod_wsgi with Apache, and either serve it
embedded or use a wsgi daemon process.</p>
@@ -99,7 +99,7 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
<p>We&#8217;ll skip going into configuration methodologies for mod_wsgi, as it&#8217;s not
the focus of this article.</p>
-<h1>gunicorn</h1>
+<h2>gunicorn</h2>
<p>When you move past mod_wsgi your solutions are basically only Python web
servers. One of the most popular (read: trendy) methods has been gunicorn
@@ -119,7 +119,7 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
never work anywhere in Python, so unless you&#8217;re sitting in the fairytale land
where they&#8217;re working, it provides you no advantages here.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>The only alternative, in my opinion, to gunicorn is uwsgi. It&#8217;s slightly more
performant, has too many configuration options to every understand, and also
@@ -141,7 +141,7 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
<p>(For what it&#8217;s worth, Disqus runs single threaded, but I&#8217;m cheap, and I wanted
to keep Sentry as lean as possible, which means squeezing capacity out of nodes)</p>
-<h2>Iterating to Success</h2>
+<h1>Iterating to Success</h1>
<p>I was pretty proud when we got API response times down to 40ms on average. When
I say API I&#8217;m only talking about the time it takes from it hitting the Python
@@ -163,13 +163,13 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
<p><img src="/images/posts/consistent-api-times.png" alt="API Times" /></p>
-<h2>Putting It Together</h2>
+<h1>Putting It Together</h1>
<p>Because I like when people do more than talk, I wanted to leave everyone with
some snippets of code from our Chef recipes which we used to actually set all
of this up on the servers (with minimal effort).</p>
-<h1>nginx</h1>
+<h2>nginx</h2>
<p>The first piece of configuration is Nginx. We need to actually programatically
add backends based on the number of uwsgi processes we&#8217;re running, so things
@@ -263,7 +263,7 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
web processes, started at port 9000. It&#8217;s also been configured to serve
uwsgi using it&#8217;s socket protocol.</p>
-<h1>uwsgi</h1>
+<h2>uwsgi</h2>
<p>On the other side of things, we&#8217;re using supervisor to control our uwsgi
processes, so things are pretty straightforward here as well:</p>
@@ -305,7 +305,7 @@ <h1 class="title"><a href="/2013/06/27/serving-python-web-applications">You Shou
</span></code></pre></td></tr></table></div></figure>
-<h2>One Way, and Only One Way</h2>
+<h1>One Way, and Only One Way</h1>
<p>Unless someone comes up with an extremely convincing argument why there should
be another way (or a situation where this can&#8217;t work), I hope to hear this

0 comments on commit 39dbbfe

Please sign in to comment.
Something went wrong with that request. Please try again.