loading...

How I deployed my Django app to Vultr VPS

ndemo profile image richard ndemo Updated on ・4 min read

Having developed my Django app, it was time to deploy it so that it can be live, such a thrilling feeling to have my own hosted website online. - I did a couple of searches and decided to host with vultr VPS. Let us jump to the whole process from setting up my server to actual running my website.

Creating a New Instance

I chose cloud compute:

Alt Text

Selecting the region for my server:

Alt Text

selecting server operating system:

Alt Text

Selecting the size of the server:

Alt Text

I chose to name the server Testserver for a practical purpose.

Alt Text

after creating the server:

Alt Text

after receiving the root password via email, I ssh into the server using the server IP Address.

Alt Text

Updating the server

First thing is to upgrade the server's packages:

apt-get update
apt-get upgrade

Creating Application User

It is always best practice not to work directly with the root user.so I created another user.

adduser django

since I am deploying a Django application, It is simple to use a simple name.
This is the output. There are few questions to be answered.

Adding user `django' ...
Adding new group `django' (1000) ...
Adding new user `django' (1000) with group `urban' ...
Creating home directory `/home/django' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for urban
Enter the new value, or press ENTER for the default
  Full Name []:
  Room Number []:
  Work Phone []:
  Home Phone []:
  Other []:
Is the information correct? [Y/n]

Adding the user to sudoers to be able to perform root functions:
gpassword -a django sudo

Now log in to the new user account.

Installing the necessary Dependencies:

Supervisor

This will be used to start the Django application server and manage it.

sudo apt-get install supervisor

Starting and enabling the supervisor:


sudo systemctl enable supervisor
sudo systemctl start supervisor

PostgreSQL

Installing the dependencies to be used by Postgresql and Django

sudo apt-get install build-essential libpq-dev python-dev

Installing PostgreSQL server:

sudo apt-get -y install postgresql postgresql-contrib

Creating and Configuring PostgreSQL database:
Switch users:

su - postgres

Creating a db user and database:


createuser django_project
createdb prod --owner django_project
psql -c "ALTER USER u_urban WITH PASSWORD '!@#fs_877#$cdfd@@'"

exit the postgreSQL user:

exit

Install and Configure Virtualenv

I used python3 that is already installed in ubuntu 16.04

First, install pip3:

sudo apt-get install python3-pip

Using pip install virtualenv:

pip3 install virtualenv

Then create virtualenv:

python3 -m venv django_env

Activating it:

cd to the virtualenvdirectory cd django_env

source bin/activate

I used GitHub to store my Django website, so I cloned it from the git repository.

git clone https://github.com/ndemo-richard/django_project.git

cd into project directory and install project dependencies:

pip install -r requirements.txt

changing the database credentials in the settings.py file in the project root directory:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'prod',
        'USER': 'django_project',
        'PASSWORD': '!@#fs_877#$cdfd@@',
        'HOST': 'localhost',
        'PORT': '',
    }
}
migrating the database:

python manage.py migrate

collect project static files:

python manage.py collectstatic

Install and configure Gunicorn

pip install gunicorn

create a file named gunicorn inside bin directory

vi bin/gunicorn
add this to the empty file:

#!/bin/bash

NAME="django_project"
DIR=/home/django/django_project
USER=django
GROUP=django
WORKERS=3
BIND=unix:/home/django/run/gunicorn.sock
DJANGO_SETTINGS_MODULE=django_project.settings
DJANGO_WSGI_MODULE=django_project.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 file executable

chmod u+x bin/gunicorn

create directory for the UNIX socket file:

mkdir run

Configure Supervisor

first, create a directory for log files:

mkdir logs

Create an empty log file inside the log directory:

touch logs/gunicorn-error.log

create a new supervisor config file:

sudo vi /etc/supervisor/conf.d/django_project.conf

django_project.conf

[program:django_project]
<code>
command=/home/django/django_project/bin/gunicorn
user=urban
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/django/logs/gunicorn-error.log

Reread the config file:


sudo supervisorctl reread
sudo supervisorctl update

Check the status:

sudo supervisorctl status django_project
django_project RUNNING pid 42173, uptime 0:00:13

NGINX

Installing Nginx web server, this will be used to run the Django application behind a proxy server

sudo apt-get install nginx

create new config file inside /etc/nginx/sites-available/:

sudo vim /etc/nginx/sites-available/django_project

/etc/nginx/sites-available/djago_project

upstream app_server {
    server unix:/home/urban/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 68.152.87.135;

    keepalive_timeout 5;
    client_max_body_size 4G;

    access_log /home/urban/logs/nginx-access.log;
    error_log /home/urban/logs/nginx-error.log;

    location /static/ {
        alias /home/urban/static/;
    }

    # 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;
    }
}

creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/django_project /etc/nginx/sites-enabled/django_project

Remove the default nginx website:
sudo rm /etc/nginx/sites-enabled/default

Restart nginx:
sudo service nginx restart

Now we are good to go. My website is online.

Discussion

pic
Editor guide
Collapse
tchi91 profile image
Fethi TChi

Thanks for this helpful post 🙏👏