DEV Community

richard ndemo
richard ndemo

Posted on • Updated on

How I deployed my Django app to Vultr VPS

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.

<code> adduser django</code>


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.
Enter fullscreen mode Exit fullscreen mode

Adding user django' ...
Adding new group
django' (1000) ...
Adding new user django' (1000) with groupurban' ...
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:
<code>gpassword -a django sudo</code>

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.

<code>sudo apt-get install supervisor</code>

######Starting and enabling the supervisor:


Enter fullscreen mode Exit fullscreen mode

sudo systemctl enable supervisor
sudo systemctl start supervisor



#####PostgreSQL 

Installing the dependencies to be used by Postgresql and Django

<code>sudo apt-get install build-essential libpq-dev python-dev</code>

######Installing PostgreSQL server:

<code>sudo apt-get -y install postgresql postgresql-contrib</code>

######Creating and Configuring PostgreSQL database:

#####Switch users:

<code>su - postgres</code>

Creating a db user and database:


Enter fullscreen mode Exit fullscreen mode

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



######exit the postgreSQL user:
<code>exit</code>

####Install and Configure Virtualenv

I used python3 that is already installed in ubuntu 16.04

######First, install pip3:

<code>sudo apt-get install python3-pip</code>

######Using pip install virtualenv:

<code>pip3 install virtualenv</code>

######Then create virtualenv:

<code>python3 -m venv django_env</code>

######Activating it:
cd to the virtualenvdirectory <code>cd django_env</code>

<code>source bin/activate</code>

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

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

cd into project directory and install project dependencies:

<code>pip install -r requirements.txt</code>

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

Enter fullscreen mode Exit fullscreen mode

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


#####migrating the database:
<code>python manage.py migrate</code>

#####collect project static files:
<code>python manage.py collectstatic</code>

####Install and configure Gunicorn

<code>pip install gunicorn</code>

create a file named gunicorn inside bin directory

<code> vi bin/gunicorn</code> 
add this to the empty file:

Enter fullscreen mode Exit fullscreen mode

!/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

<code>chmod u+x bin/gunicorn</code>

create directory for the UNIX socket file:

<code> mkdir run</code>

#####Configure Supervisor

 first, create a directory for log files:

<code>mkdir logs</code>

######Create an empty log file inside the log directory:

<code>touch logs/gunicorn-error.log</code>

create a new supervisor config file:

<code>sudo vi /etc/supervisor/conf.d/django_project.conf</code>

django_project.conf

Enter fullscreen mode Exit fullscreen mode

[program:django_project]




command=/home/django/django_project/bin/gunicorn
user=urban
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/django/logs/gunicorn-error.log


Enter fullscreen mode Exit fullscreen mode

Reread the config file:


sudo supervisorctl reread
sudo supervisorctl update

Enter fullscreen mode Exit fullscreen mode

Check the status:


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

Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

creating a symbolic link:


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

Enter fullscreen mode Exit fullscreen mode

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 (1)

Collapse
tchi91 profile image
Fethi TChi

Thanks for this helpful post 🙏👏