---
# System prepended metadata

title: Django Deployment Guide

---

Django Deployment Guide
===


Tools
----
* Gunicorn: Worker process management
* Systemd: Service management and monitoring
* Nginx: Reverse proxy server
* Certbot: SSL/TLS certificate deployment


Steps
----

1. Preparing basic enviroment, including:
    * Git / Subversion
    * Pyenv & Pipenv
    * MariaDB / PostgreSQL
    * Service User for running Gunicorn

2. Download the application repo

3. Add deployment settings to the application

4. Create the static file folder and copy static files to it
    ```
    $ mkdir -p STATIC_ROOT
    $ pipenv run ./manage.py collectstatic
    ```
    Replace STATIC_ROOT with the one in settings

5. Install Gunicorn and Gevent (Better to add these in Pipfile before deployment)

6. Add Systemd configurations

    * /etc/systemd/system/gunicorn.service
        ```
        [Unit]
        Description=gunicorn daemon
        Requires=gunicorn.socket
        After=network.target

        [Service]
        PIDFile=/run/gunicorn/pid
        User=SERVICE_USER
        Group=SERVICE_GROUP
        RuntimeDirectory=gunicorn
        WorkingDirectory=PROJECT_PATH
        Environment=PYTHONUNBUFFERED=True
        ExecStart=GUNICORN_EXECUTABLE \
                  --pid /run/gunicorn/pid \
                  --bind unix:/run/gunicorn.socket \
                  --worker-class gevent \
                  APP_NAME.wsgi
        ExecReload=/bin/kill -s HUP $MAINPID
        ExecStop=/bin/kill -s TERM $MAINPID
        PrivateTmp=true

        [Install]
        WantedBy=multi-user.target
        ```
        
    * /etc/systemd/system/gunicorn.socket
        ```
        [Unit]
        Description=gunicorn socket

        [Socket]
        ListenStream=/run/gunicorn.socket

        [Install]
        WantedBy=sockets.target
        ```

    * /etc/tmpfiles.d/gunicorn.conf
        ```
        d /run/gunicorn 0755 SERVICE_USER SERVICE_GROUP -
        ```
    
    Replace these variables to fit your situation:
    * APP_NAME
    * PROJECT_PATH
    * SERVICE_USER
    * SERVICE_GROUP
    * GUNICORN_EXECUTABLE
        
7. Start gunicorn service and enable autostart
    ```
    $ sudo systemctl start gunicorn.socket
    $ sudo systemctl enable gunicorn.socket
    ```
    
8. Install Nginx server

9. Modify Nginx configuration

    /etc/nginx/nginx.conf
    ```
    http {
        server {
            server_name APP_DOMAIN;
            location / {
                proxy_pass http://unix:/run/gunicorn.socket;
                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_set_header X-Forwarded-Proto $http_x_forwarded_proto;
            }
            location /static/ {
                alias STATIC_ROOT;
            }
        }
    }
    ```
    Replace these variables to fit your situation:
    * APP_DOMAIN
    * STATIC_ROOT

10. Start nginx service and enable autostart
    ```
    $ sudo systemctl start nginx.service
    $ sudo systemctl enable nginx.service
    ```
    
11. Install Certbot with nginx plugin

12. Get and serve a certificate for the application
    ```
    $ sudo certbot --nginx
    ```

13. Enable certbot autorenew for the certificates
