My main question here is: Did I set it up right, or what would be the more preferable way of going about it regarding the directory structure, configs, whatever else I may just not know about for setting up a web server! Is there something I need to do to ensure it auto-restarts if the server crashes or something? I guess I could have asked this in a support ticket, but figured

I just recently got a server with WebFaction and started trying to set it up with using nginx+gunicorn+flask as my first project. I started by installing python 2.7.2 into lib/python2.7.2 and then installed distribute/pip/virtualenv/virtualenvwrapper for that python install and created a virualenv from it. I downloaded and extracted nginx-1.0.11 into webapps/nginx(which is a "custom app(listening)" in the control panel), and pip installed gunicorn+flask into my py27 virtualenv. I started up nginx and tested my url, which displayed the basic "nginx is working" page. I then opened up my nginx.conf to start trying to adjust it to work with gunicorn. This is the main part where I feel I could probably use some tips.

I read through a lot of the nginx docs, and understand the majority of the various settings/directives. I am not completely sure how the magic works with the upstream block or the named location for setting up the proxy(I used as a starting point and changed very little), but I was surprised I was able to set just any port on given this is a shared box? I probably just don't understand what all I have access to when using my WebFaction's server solution! The directives that are commented out are that way because that is the way they came and I don't know why/when I would need them yet.

This is my current webapps/nginx/conf/nginx.conf:

#user  nobody;
worker_processes  1;

pid logs/;
error_log logs/nginx.error.log;

events {
    worker_connections  1024;
    accept_mutex off;

http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log  logs/nginx.access.log  combined;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
    gzip_comp_level 2;
    gzip_types    text/plain text/html text/css
                  application/x-javascript text/xml
                  application/xml application/xml+rss

    upstream frontends {

    server {
        listen       port;

        keepalive_timeout 5;

        root html;

        location / {
            root   html;
            index  index.html index.htm;
        location /yo/ {
            #checks for static file, if not found proxy to app
            try_files $uri @proxy_to_app;

        location @proxy_to_app {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;

            proxy_pass http://frontends;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;

I then created the following webapps/nginx/conf/gunicorn.conf in the webapps/nginx/conf directory:

workers = 2
bind = ''
procname = ''
pidfile = '~/webapps/nginx/logs/'

I and then a simple flask app to test it all(, located within webapps/nginx/html with:

from flask import Flask
from flask import render_template_string
from werkzeug.contrib.fixers import ProxyFix

app = Flask(__name__)

def index():
    return render_template_string('yo!')

app.wsgi_app = ProxyFix(app.wsgi_app)

Given those files I start nginx by calling webapps/nginx/sbin/nginx, and then I start up gunicorn from the directory of the flask app by calling gunicorn -c ../conf/gunicorn.conf test:app. At this point if I go to it'll load the default "Welcome to nginx page!", and if I go to it will utilize the flask app and display "yo!'

Anyways my goal for this post is to hopefully get some tips from those with more experience on the best way to setup the nginx/gunicorn config, as well as hopefully give people trying to do this some guidance to at least get to the level of having a working site.

asked 27 Jan '12, 12:22

rdb's gravatar image

accept rate: 0%


A few things to cover,

Your python steps are OK, you likely did not need to build python from source, but it does not hurt.

For the guicorn app and frontend setting you need a second 'custom app' and you should be using its port. You can technically assign any port that is open on the server, however we will not promise that the port will not get assigned in the future, and if your are using it and not assigned to it we may stop the app and send you a warning.

Although it gives you an extra layer of configuration, which sometimes you want, you do not need to build your own nginx stack to deploy this. The front-end nginx server is already a proxy server that can have a port assigned to it.

I have a community post that deploys django using the front-end nginx server and guinicorn. The same general steps apply to other gunicorn apps.

permanent link

answered 27 Jan '12, 17:16

johns's gravatar image

johns ♦♦
accept rate: 23%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text]( "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:


question asked: 27 Jan '12, 12:22

question was seen: 7,445 times

last updated: 27 Jan '12, 17:16

Features & prices    Sign up    Contact us    Affiliate program    Support    Legal    Jobs    Blog    Control panel login
© Copyright 2003-2015 Swarma Limited - WebFaction is a service of Swarma Limited