How to Deploy Django with Nginx, Gunicorn and Postgres on Ubuntu
Django application is great but hosting it with the normal web servers isn't so great an idea. Django works awesome with Gunicorn and Nginx along with Postgres in the database end. We will install this setup in Ubuntu 22.04 LTS which will mostly be applicable to further Ubuntu versions as well.
Step 1 : Installing Packages
You can install the required packages for database and python related files from Ubuntu apt repository. First you need to update the package indexes before downloading and installing any other packages, with the following command in terminal:
sudo apt update
Please ensure that python3 is installed before proceeding further:
python3 -V
The above command should show the version installed like Python 3.10.6 If you need to update to different Python version you can update using deadsnakes repository:
sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.11
Please run the following command to install Postgres, Nginx and related python files:
sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl
If you update to higher python versions say 3.11 then you can also install the related files similarly, else you can proceed further to the next step.
sudo apt install python3.11-venv python3.11-dev
Step 2: PostgreSQL Database and User Creation
An administrative user in the name of postgres was created during postgresql installation both in linux system and in postgresql database. This user will be needed further to perform administrative tasks in postgressql. You can log in as postgres user using sudo and start the postgresql tasks.
sudo -u postgres psql
You can create the database in the logged in prompt of PostgreSQL.
CREATE DATABASE django_project_1;
Then create a database user for this project with a strong password.
CREATE USER dj_project_1_user WITH PASSWORD 'password';
Then set the default database encoding expected by Django.
ALTER ROLE dj_project_1_user SET client_encoding TO 'utf8';
Then set the default transaction isolation scheme to read committed to ensure the reading from committed transactions only.
ALTER ROLE dj_project_1_user SET default_transaction_isolation TO 'read committed';
Then set the timezone to UTC which is generally used in Django based projects. ALTER ROLE dj_project_1_user SET timezone TO 'UTC';
Finally provide all the privileges of managing the created database to the newly created database user.
GRANT ALL PRIVILEGES ON DATABASE django_project_1 TO dj_project_1_user;
Thereafter you can logout from database console by typing \q and pressing enter. The above steps successfully configured PostgreSQL with database ready for connection.
Step 3: Creation of Python Virtual Environment
We will create the python virtual environment at /var/www/ for our first django project and will create more folders for subsequent django projects as well. You can also keep you files in /var/www/html/ folder or any other folder as you like it.
cd /var/www mkdir django_project_1
Then create the virtual environment inside the project folder.
cd django_project_1 python3 -m venv venv
You can give a different name to your virtual environment folder. I keep it as venv for simplicity of use. You can use higher version python here if you need.
python3.11 -m venv venv_name
Activate your virtual environment.
source venv/bin/activate
Install Django, Gunicorn and PostgreSQL adapter in the virtual environment.
pip install django gunicorn psycopg2-binary
Step 4: Django Project
Now in your project's activated virtual environment, you can start the django project. You can start the project normally as you do for django projects.
django-admin startproject django_pro_1
I generally rename this project directory as src to know that it is the source directory. You may rename it or keep it as you like, but you need to use the same path hereafter in further steps. You can rename as below.
mv django_pro_1 src
You will further need to add localhost and you server IP in the ALLOWED_HOSTS section in the settings.py file of you Django project. You can update it via nano editor or any other editor.
nano src/django_pro_1/settings.py
Once done, press Ctrl+O to save and Ctrl+X to exit for nano editor.
Here add your server IP and localhost.
ALLOWED_HOSTS = ['server domain name or IP', 'another server domain name or IP', 'localhost', '127.0.0.1']
Next, you need to update the database name and database user name that you created above, in settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'django_project_1', 'USER': 'django_project_1_user', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } }
Next, you need to mention where the static files of django project will be kept through settings.py, which will help NGINX to server the same.
from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent.parent STATIC_ROOT = BASE_DIR.parent / 'static'
Thereafter you can perform migrations and create a super user for you django project, and collect the static files, using commands below.
python src/manage.py makemigrations python src/manage.py migrate python src/manage.py createsuperuser python src/manage.py collectstatic
Create a temporary firewall exception in firewall for port 8000 for testing purpose.
sudo ufw allow 8000
You can now run the Django development server to test the Django application.
python src/manage.py runserver 0.0.0.0:8000
Now check your Django website through your IP:
http://your_server_domain_or_IP:8000
You must receive the default Django page up and running. You can check your superadmin account as well from /admin URL. Press Ctrl+C to stop the development server
You can now test Gunicorn web server from your virtual environment.
gunicorn --bind 0.0.0.0:8000 src/django_pro_1.wsgi
The static files will not be served in the above case as gunicorn does not server static files. In our case we will setup Nginx to server static stuff. Press Ctrl+C to stop the development server
You can now deactivate the virtual environment.
deactivate
The virtual environment will be closed.
Step 5: Creating System Files for Gunicorn
In order to use Gunicorn server that we have installed in the virtual environment, we need to create systemd socket and service files for the project. Similarly for multiple projects we can further create their own systemd socket and service files. We will now first create the gunicorn socket by the name guncorn_django_pro_1 to identify it as the socket file for our first django project.
sudo nano /etc/systemd/system/gunicorn_django_pro_1.socket
Inside the file, we need to mention the name of the socket unit and the socket file for listening. Please enter the below details.
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn_django_pro_1.sock [Install] WantedBy=sockets.target
Once the socket file has been saved, we need to create the gunicorn service file.
sudo nano /etc/systemd/system/gunicorn_django_pro_1.service
Inside the service file, we need to mention the path details of our project and virtual environment, along with the socket details. Please enter the details as below.
[Unit] Description=gunicorn daemon Requires=gunicorn_django_pro_1.socket After=network.target
[Service] User=root Group=root WorkingDirectory=/var/www/django_project_1/src ExecStart=/var/www/django_project_1/venv/bin/gunicorn \ --access-logfile - \ --workers 3 \ --env DJANGO_SETTINGS_MODULE=django_pro_1.settings \ --bind unix:/run/gunicorn_django_pro_1.sock \ django_pro_1.wsgi
[Install] WantedBy=multi-user.target
Once the socket and service has be created we can start and enable them so that they are started every time the system starts. Please enter the commands below for socket.
sudo systemctl start gunicorn_django_pro_1.socket sudo systemctl enable gunicorn_django_pro_1.socket
Please enter the commands below for gunicorn service files.
sudo systemctl start gunicorn_django_pro_1 sudo systemctl enable gunicorn_django_pro_1
You can check the status of the gunicorn socket using command below.
sudo systemctl status gunicorn_django_pro_1.socket
You can check existence of the socket file by command below.
file /run/gunicorn_django_pro_1.sock
You can check the status of the gunicorn service using command below.
sudo systemctl status gunicorn_django_pro_1
You can also test the web service of gunicorn by sending a request using curl.
curl --unix-socket /run/gunicorn_django_pro_1.sock localhost
You can then see the output status using command below.
sudo systemctl status gunicorn_django_pro_1
You can restart the gunicorn service using the command below.
sudo systemctl restart gunicorn_django_pro_1
Step 6: Configuring Nginx
We will configure Nginx to proxy pass requests to Gunicorn server. You can add the detail of the Django projects inside sites-available directory of Nginx, by creating individual files for each Django project. We will start by adding the details of our Django project.
sudo nano /etc/nginx/sites-available/django_pro_1
Please enter the details inside the file as below.
server { listen 80; server_name your_domain_name_or_IP;
location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /var/www/django_project_1/static; }
location / { include proxy_params; proxy_pass http://unix:/run/gunicorn_django_pro_1.sock; } }
Once completed, we need to create a sym link of the file to the sites-enabled directory, using the command below.
sudo ln -s /etc/nginx/sites-available/django_pro_1 /etc/nginx/sites-enabled
You can test the Nginx settings using the commands below.
sudo nginx -t
If all is ok, then you can restart Nginx.
sudo systemctl restart nginx
Please remove the 8000 port from firewall and allow Nginx Full to serve both http and https traffic.
sudo ufw delete allow 8000 sudo ufw allow 'Nginx Full'
Now you have successfully setup and deployed your Django project using Nginx, Gunicorn and PostgreSQL. Whenever you need to make any changes, you can do so and then restart the gunicorn and nginx service as required, using the commands below.
sudo systemctl restart gunicorn_django_pro_1 sudo nginx -t sudo systemctl restart nginx
I hope you enjoyed the tutorial. If you need further consultation services for the same, you can most welcome. Please leave a positive review, if this tutorial helped you.
Popular Tags