How to deploy django to production (Part-2)

IN THE PART 2 OF THIS TUTORIAL, WE WILL BE LOOKING AT HOW TO DEPLOY DJANGO TO PRODUCTION

In part-1 of this tutorial, we looked at how we can set-up a DigitalOcean project and run Django webapp on it. In this part of the tutorial, we are going to see how to deploy Django to production. We will be using the previously set-up DigitalOcean for this tutorial. However, the process should be the same for any server running on Ubuntu 18.04 x64 environment.

Install necessary packages from Ubuntu Repositories

If you have already installed the necessary packages in the earlier part of the tutorial, you can skip this step. If you haven’t installed it then you can do so by using the following commands:

  • sudo apt-get update
  • sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx python3-django

Create PostgreSQL Database and User

By Default Django uses sqlite database. This is good enough for development. However, for production, we will need a more robust database. We will be using PostgreSQL Database for production for our Django application. During the Postgres installation, an operating system user named postgres was created to correspond to the postgres PostgreSQL administrative user. We need to use this user to perform administrative tasks. The steps needed to do for creating PostgreSQL Database for our Django application to use are as follow:

  1. Log into an interactive Postgres session
    sudo -u postgres psql
  2. Create a Database for your project
    CREATE DATABASE mydatabase;
    You can replace mydatabase with your desired Database name.
  3. Create a Database user for your project
    CREATE USER newuser WITH PASSWORD 'password';
    You can replace newuser with your desired username for the Database and ‘password’ with some secure password.
  4. Optimize PostgreSQL’s configuration according to the recommendations from the Django project
    ALTER ROLE newuser SET client_encoding TO 'utf8';
    ALTER ROLE newuser SET default_transaction_isolation TO 'read committed';
    SET timezone TO 'UTC';
  5. Grant the new user with all access to the created Database
    GRANT ALL PRIVILEGES ON DATABASE mydatabase TO newuser;

Once complete, exit the interactive Postgres session by typing \q.

Install Django, Gunicorn, and psycopg2

We will install virtualenv and install necessary python modules on the virtualenv.

  1. Install virtualenv
    sudo -H pip3 install --upgrade pip
    sudo -H pip3 install virtualenv
  2. Create a Python virtual environment
    virtualenv env
    You can replace env with your desired environment name

  3. Activate the virtual environment
    source env/bin/activate
  4. Install the necessary python modules
    pip install django gunicorn psycopg2

Configure the Django project

  • On the settings.py, set DEBUG=Fals
  • On settings.py again, make sure your ip-address/domain name is on the ALLOWED_HOSTS list. For eg: ALLOWED_HOSTS = ["142.93.83.203"]
  • Change the settings with your PostgreSQL database information. On settings.py, locate database and change it to
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'mydatabase',
            'USER': 'newuser',
            'PASSWORD': 'password',
            'HOST': 'localhost',
            'PORT': '',
        }
    }

    Change Name, User and Password to match your Database name, Database User name and Database User password respectively.

  • Next, on the settings.py, define STATIC_ROOT and MEDIA_ROOT so that Nginx can handle requests for static and media files. Add the following lines to settings.py
    STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
    
    MEDIA_URL = '/media/'
    MEDIA_ROOT = os.path.join(BASE_DIR,'media/')

http://142.93.83.203/Create a Gunicorn systemd Service File

  • Create and open a systemd service file for Gunicorn using the command sudo nano /etc/systemd/system/gunicorn.service and add the following lines to it:

    [Unit]
    Description=gunicorn daemon
    After=network.target

    [Service]
    User=pytorials
    Group=www-data
    WorkingDirectory=/home/pytorials/mysite
    ExecStart=/home/pytorials/mysite/env/bin/gunicorn –access-logfile – –workers 3 –bind unix:/home/pytorials/mysite/mysite.sock mysite.wsgi:application

    [Install]
    WantedBy=multi-user.target

    Replace User=pytorials with your Ubuntu user, working directory with directory to your Django project and ExecStart with location to your virtualenv gunicorn, and your django project directory accordingly.

  • Start and enable gunicorn service using the commands:
    sudo systemctl start gunicorn
    sudo systemctl enable gunicorn

Configure Nginx to Proxy Pass to Gunicorn

Now that gunicorn is set up, next step is to configure Nginx.

  • Start by creating opening a new server block in Nginx’s sites-available directory using the command below:
    sudo nano /etc/nginx/sites-available/mysite
  • Add the following lines to the newly created file:

    server {
    listen 80;
    server_name 142.93.83.203;
    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
    root /home/pytorials/mysite;
    }

    location /media/ {
    root /home/pytorials/media;
    }

    location / {
    include proxy_params;
    proxy_pass http://unix:/home/pytorials/mysite/mysite.sock;
    }
    }

  • Save and close the file when you are finished. Now, enable the file by linking it to the sites-enabled directory using the command sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled
  • Check if there are any errors by typing the command sudo nginx -t. You should see an output that looks like:

    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

  • Restart Nginx using the command sudo systemctl restart nginx
  • Allow firewall to normal traffic on port 80 using the command sudo ufw allow 'Nginx Full'

You should be able to view your Django application on the web browser now. Navigate to [your-ip-address], in the demo 142.93.83.203, and you will see the index page of your application. If you followed along with the article and have not configured any URLs then you need to set DEBUG=TRUE in the settings.py. However, setting DEBUG=TRUE is not recommended for the production environment.

If static files are not loading properly, you need to run the command: python3 manage.py collectstatic

This brings us to the end of the tutorial How to deploy Django to production. If you ran into any errors following the steps, please let me know in the comments below.



About Aryal Bibek 20 Articles
Learner and practitioner of Machine Learning and Deep Learning. Ph.D. student at The University of Texas at El Paso. Admin and Founder at python36.com

Be the first to comment

Leave a Reply

Your email address will not be published.




This site uses Akismet to reduce spam. Learn how your comment data is processed.