Setting up Gunicorn as a service


Setting up a gunicorn service is super easy!

We’ll use systemd services as that is the most commonly found through systems for service management, there are others but we’ll stick with systemd for now.

Below you’ll find a quick template to edit. You’ll need to call the file example.service and you’ll need to put it in /etc/systemd/system/ fill it with:

[Unit]
Description=python based web application
After=network.target
 
[Service]
User=username
WorkingDirectory=/home/username/python_program
ExecStart=/home/username/python_program/venv/bin/gunicorn -b localhost:8000 -w 4 main:app
Restart=always
 
[Install]
WantedBy=multi-user.target

The important parts to notice here are that it start folder is where the program is located; the ExecStart part we can see, essentially, activates the virtual environment and runs the gunicorn command.

If you need environment options, eg if you are running a flask app, you can add them above ExecStart and use Environment=FLASK_CONFIG=production and Environment=DATABASE_URL=sqlite:////path/to/the/database.sqlite to set them.

NB: You wont need to set these if you run with a .env as they will still work either way, but if you don’t use an .env file you can set them here.

Once you got your file worked out and filled with the right commands, you can run sudo systemctl daemon-reload and then start the service by running sudo systemctl start example.

Setting up Nginx

With gunicorn working, you’ll probably want to visit the program’s url on port 80 rather than 8000 each time, so to solve this we will proxy_pass it to port 80 using nginx.

In your /etc/nginx/sites-enabled/default file you can edit the location / { } location and fill it with the details below:

location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

This will handle any url changes and make it so that all requests to port 80 get redirected to port 8000 internally without the user seeing any difference. Check your config, you see how to do that here, and the restart/start nginx. Go to your apps url and it should load up!