Gcon Technologies Blog

Welcome. Bookmark to dive into tech.
Home   Django    Python   

How to host or deploy a django application on VPS

Oct. 26, 2019   Deepak   15 min read   Django
Hosting VPS Django Deploy

We'll be using the following services and packages to deploy/host our Django application in the production environment.

  1. Digital Ocean as VPS
  2. Ubuntu 18.04 
  3. Nginx Server
  4. Gunicorn
  5. Supervisor

Step 1. Create a Digital Ocean Account

Sign up and get $50 for free on Digital Ocean

  • You'll get an IP address for your droplet(ubuntu machine) and a password on your mail.
  • SSH to the machine. 
    • $ ssh root@ip.of.your.droplet 
  • You'll be prompted to change the default password. Do it.
  • Next, add a user with sudo privileges.
    • $ adduser username
    • $ usermod -aG sudo username   # adding a user to the sudo group
    • $ su - username    # switch to t
  • Update the machine
    • $ sudo apt update && sudo apt -y upgrade

 

Step 2. Installing the necessary packages

  •    Install Nginx
    • $ sudo apt-get -y install nginx
  • Install Supervisor
    • $ sudo apt-get -y install supervisor
  • Enable and start the supervisor
    • $ sudo systemctl enable supervisor
    • $ sudo systemctl start supervisor
  • Install Virtual Environment
    • $ sudo apt install -y python3-venv

 

Step 3. Application setup

  • create a virtualenv 
    • $ virtualenv project-venv 
    • $ cd project-venv 
    • $ source bin/activate
  • copy your project source folder inside the project-venv directory.
  • Install the requirements
    • $ pip3 install -r requirements.txt
  • Make migrations
    • $ python manage.py migrate
    • $ python manage.py collectstatic
    • $ python manage.py runserver 0.0.0.0:8000
  • Test your app by opening the IP in your browser.
  • HIT Ctrl + C to stop the Django development server.

 

Step 4. Configure Gunicorn, Supervisor

  • Install Gunicorn inside the virtualenv
    • $ pip install gunicorn
  • Create a file gunicorn_start inside the bin/ folder
    • $ nano bin/gunicorn_start
  • Add the following bash code to the gunicorn_start (/home/username/project-venv/bin/gunicorn_start)
    • #!/bin/bash

      NAME="mysite"
      DIR=/home/username/project-venv/mysite
      USER=username
      GROUP=username
      WORKERS=3
      BIND=unix:/home/username/project-venv/run/gunicorn.sock
      DJANGO_SETTINGS_MODULE=mysite.settings
      DJANGO_WSGI_MODULE=mysite.wsgi
      LOG_LEVEL=error

      cd $DIR
      source ../bin/activate

      export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
      export PYTHONPATH=$DIR:$PYTHONPATH 

      exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
        --name $NAME \
        --workers $WORKERS \
        --user=$USER \
        --group=$GROUP \
        --bind=$BIND \
        --log-level=$LOG_LEVEL \
        --log-file=-

  • Make the gunicorn_start file is executable:
    • $ chmod u+x bin/gunicorn_start
  • Create a directory named run, for the unix socket file:
    • $ mkdir run
    Create logs inside the virtualenv:
    • $ mkdir logs
  • Create a file for logging application errors:
    • $ touch logs/gunicorn-error.log
  • Configure Supervisor
    • Now what we want to do is configure Supervisor to take care of running the gunicorn server.
    • Create a new Supervisor configuration file (/etc/supervisor/conf.d/mysite.conf):
    • $ sudo nano /etc/supervisor/conf.d/mysite.conf
    • Put the following bash inside the mysite.conf file.
      • [program:mysite]
        command=/home/username/project-venv/bin/gunicorn_start
        user=username
        autostart=true
        autorestart=true
        redirect_stderr=true
        stdout_logfile=/home/username/project-venv/logs/gunicorn-error.log
    • Reread Supervisor configuration files and make the new program available:
      • $ sudo supervisorctl reread
        $ sudo supervisorctl update
    • Check the status:
      • $ sudo supervisorctl status mysite
          mysite                    RUNNING   pid 29678, uptime 04:18:44
    • Now you can control your application using Supervisor. If you want to update the source code of your application with a new version, you can pull the code from GitHub and then restart the process:
      • $ sudo supervisorctl restart mysite

 

Step 5. Configure NGINX

  • Add a new configuration file named mysite inside /etc/nginx/sites-available/:
    • $ sudo nano /etc/nginx/sites-available/mysite
    • Put the following bash inside the mysite file
      • upstream app_server {
            server unix:/home/username/project-venv/run/gunicorn.sock fail_timeout=0;
        }
        server {
            listen 80;
            # add here the ip address of your server
            # or a domain pointing to that ip (like example.com or www.example.com)
            server_name ip.address.of.your.droplet;
            keepalive_timeout 5;
            client_max_body_size 4G;
            access_log /home/username/project-venv/logs/nginx-access.log;
            error_log  /home/username/project-venv/logs/nginx-error.log;
            location /static/ {
                alias /home/username/project-venv/mysite/static/;
            }
        location /media/ {
                alias /home/username/project-venv/mysite/media/;
            }
            # checks for static file, if not found proxy to app
            location / {
                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://app_server;
            }
        }
  • Create a symbolic link to the sites-enabled dir:
    • $ sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
  • Remove the NGINX default website:
    • $ sudo rm /etc/nginx/sites-enabled/default
  • Restart the nginx server
    • $ sudo service nginx restart