Serving a request from gunicorn

Chris Dutrow picture Chris Dutrow · Oct 12, 2012 · Viewed 23.3k times · Source

Trying to setup a server on Rackspace.com.

Have done the following things:

  • Installed Centos 6.3
  • Installed Python 2.7
  • Installed gunicorn using the "Quick Start" on their home page: gunicorn.org/

In the quick start, a "hello world" application seems to be initialized:

Create file "myapp.py":

(tutorial) $ vi myapp.py
(tutorial) $ cat myapp.py

Contents of "myapp.py"

def app(environ, start_response):
   data = "Hello, World!\n"
   start_response("200 OK", [
       ("Content-Type", "text/plain"),
       ("Content-Length", str(len(data)))
   ])
   return iter([data])

Since I know very little about servers, I do not know what to do next. I tried typing the server's IP address into the browser, but that seemed to result in a timeout.

I'm not sure if there is:

  • something else that needs to be installed. Nginx is mentioned under "deploy" on the gunicorn website. Looks like Nginx is a proxy server which is confusing to me because I thought gunicorn was a server. Not sure why I need two servers?
  • something that needs to be configured in gunicorn
  • something that needs to be configured on the server itself
  • something that else entirely that needs to be done in order to actually serve a request

What are the next steps?

Thanks so much!

Answer

andrefsp picture andrefsp · Oct 12, 2012

since gunicorn is a Web server on your case Nginx will act as a back proxy passing the an HTTP request from Nginx to gunicorn.

So, I will put here the steps to take for a simple Nginx and Gunicorn configuration running on the same machine.

  • Starting with nginx configuration

Go to your /etc/nginx/nginx.conf and under the http{} make sure you have: include /etc/nginx/site-enabled/*;

http{
    # other configurations (...)
    include /etc/nginx/sites-enabled/*;
}

now, include a file on /etc/nginx/sites-enabled/mysite.conf where you will proxy your requests to your gunicorn app.

server {
    listen 80 default; # this means nginx will be 
                       # listening requests on port 80 and 
                       # this will be the default nginx server
    server_name localhost;

    # declare proxy params and values to forward to your gunicorn webserver
    proxy_pass_request_headers on;
    proxy_pass_request_body on;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_read_timeout 120s;

    location / {
        # here is where you declare that every request to / 
        # should be proxy to 127.0.0.1:8000 (which is where
        # your gunicorn will be running on)          
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 10;

        proxy_pass http://127.0.0.1:8000/; # the actual nginx directive to 
                                           # forward the request
    }
}

Ok, at this point all you have is an Nginx acting as a proxy where all the requests going to 127.0.0.1:80 will be passed to 127.0.0.1:8000.

  • Now is time to configure your Gunicorn webserver:

Usually the way I do I use a configuration file, Gunicorn config file can be an ordinary python file. So now, create a file at any location you like, I will assume this file will be /etc/gunicorn/mysite.py

workers = 3              # number of workers Gunicorn will spawn 

bind = '127.0.0.1:8000'  # this is where you declare on which address your 
                         # gunicorn app is running.
                         # Basically where Nginx will forward the request to

pidfile = '/var/run/gunicorn/mysite.pid' # create a simple pid file for gunicorn. 

user = 'user'          # the user gunicorn will run on

daemon = True          # this is only to tell gunicorn to deamonize the server process

errorlog = '/var/log/gunicorn/error-mysite.log'    # error log

accesslog = '/var/log/gunicorn/access-mysite.log'  # access log

proc_name = 'gunicorn-mysite'            # the gunicorn process name

Ok, all set in configuration. Now all you have to do its to start the servers.

Starting the gunicorn and telling it which app to use and which config file. from the command line and the folder where your myapp.py file is located run:

gunicorn -c /etc/gunicorn/mysite.py mysite:app

Now, only start nginx.

/etc/init.d/nginx start 

or

service nginx start

Hope this helps.