How to install and set up Nginx and Gunicorn to Serve a Website

This post is part of a series. This list contains all of the posts:

Nginx and Gunicorn Installation Tutorial

It is very popular to use Nginx and Gunicorn to host a Python website. This guide shows how to install them quickly and correctly.

I used the following sources of information for this post: https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-centos-7 https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-centos-7

How to install Gunicorn

Make sure pip and virtualenv are installed.

virtualenv blog
cd blog
source bin/activate
pip install gunicorn

To get Gunicorn to start at system boot we can use the systemctl command, which is an alternative to supervisord or upstart. Open up this new file:

sudo vi /etc/systemd/system/blog.service

Enter the following:

[Unit]
Description=Gunicorn instance to serve blog
After=network.target

[Service]
User=myuser
Group=nginx
WorkingDirectory=/apps/blog/blog
Environment="PATH=/apps/blog/bin"
#ExecStart=/apps/blog/bin/gunicorn -w 3 --bind 0.0.0.0:5000 run:app
ExecStart=/apps/blog/bin/gunicorn -w 3 --bind unix:blog.sock -m 007 run:app
Restart=always

[Install]
WantedBy=multi-user.target

To get systemctl to restart a process if it crashed, add Restart=always like above. With it set to always, even a kill to the process won't stop it from restarting. You could alternatively set it to Restart=on-failure to prevent restarting on a kill command.

To start it and enable starting on boot:

sudo systemctl start blog
sudo systemctl enable blog

I at first had some trouble getting gunicorn to start. To debug, issue this command to look at the journal, and hit shift+G to skip to the end:

journalctl

It is working if you see messages like this:

Sep 12 00:41:12 myhost gunicorn[22015]: [2016-09-12 00:41:12 +0000] [22015] [INFO] Starting gunicorn 19.6.0
Sep 12 00:41:12 myhost gunicorn[22015]: [2016-09-12 00:41:12 +0000] [22015] [INFO] Listening at: http://0.0.0.0:5000 (22015)
Sep 12 00:41:12 myhost gunicorn[22015]: [2016-09-12 00:41:12 +0000] [22015] [INFO] Using worker: sync
Sep 12 00:41:12 myhost gunicorn[22015]: [2016-09-12 00:41:12 +0000] [22020] [INFO] Booting worker with pid: 22020
Sep 12 00:41:12 myhost gunicorn[22015]: [2016-09-12 00:41:12 +0000] [22021] [INFO] Booting worker with pid: 22021
Sep 12 00:41:12 myhost gunicorn[22015]: [2016-09-12 00:41:12 +0000] [22022] [INFO] Booting worker with pid: 22022

Nginx

A few yum operations are necessary:

# Add CentOS 7 EPEL repo
sudo yum install epel-release -y

sudo yum install nginx -y

sudo systemctl start nginx
sudo systemctl enable nginx

sudo vi /etc/nginx/nginx.conf

In /etc/nginx/nginx.conf, add the following. Note that this is for an http server. Check out the follow up post on Let's Encrypt and SSL certificates with Ngnix.

user nginx;
# ...
http {
    server {
        #...
        location / {
            #proxy_pass http://localhost:5000/ ;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://unix:/apps/blog/blog/blog.sock;

        }
        location /static/ {
            autoindex on;
            alias /apps/blog/blog/static/ ;
        }
    }
}

This post is part of a series. This list contains all of the posts:


Comments

Add Comment

Name

Email

Comment

Are you human? * three = 12