How to Install Django Framework on Debian 11
This tutorial exists for these OS versions
- Debian 12 (Bookworm)
- Debian 11 (Bullseye)
- Debian 10 (Buster)
On this page
Django is a free and open-source web development framework written in Python. It is used for developing complex and database-driven Python applications. It comes with a set of Python scripts for creating Python projects. It can be run on any operating system that can run Python including, Windows, macOS, Linux/Unix, and Solaris. It helps developers to write less code and create a new website in a short amount of time.
In this tutorial, I will explain how to set up Django in Python virtual environment using the PostgreSQL database on Debian 11. We will then install and configure Nginx as a reverse proxy for Django.
Prerequisites
- A server running Debian 11.
- A valid domain name pointed with your server IP.
- A root password is configured on the server.
Getting Started
Before starting, it is a good idea to update your system packages to the latest version. You can do it using the following command:
apt-get update -y
Once all the packages are updated, install other Python tools and Nginx package with the following command:
apt-get install python3-pip python3-dev libpq-dev curl nginx -y
Once all the required packages are installed, you can proceed to the next step.
Install PostgreSQL Database Server
Here, we will use PostgreSQL as a database backend. So let's install it using the following command:
apt-get install postgresql postgresql-contrib -y
Once the PostgreSQL is installed, connect to the PostgreSQL shell with the following command:
su - postgres
psql
Next, create a database and user for Django with the following command:
CREATE DATABASE django;
CREATE USER django WITH PASSWORD 'password';
Next, grant some required roles with the following command:
ALTER ROLE django SET client_encoding TO 'utf8';
ALTER ROLE django SET default_transaction_isolation TO 'read committed';
ALTER ROLE django SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE django TO django;
Next, exit from the PostgreSQL shell using the following command:
\q
exit
At this point, the PostgreSQL database is ready for Django. You can now proceed to the next step.
Create a Python Virtual Environment
Next, you will need to create a Python virtual environment to create a Django project.
First, upgrade the PIP package to the latest version using the following command:
pip3 install --upgrade pip
Next, verify the PIP version using the following command:
pip --version
Sample output:
pip 21.2.4 from /usr/local/lib/python3.9/dist-packages/pip (python 3.9)
Next, install the Virtual environment package using the following command:
pip3 install virtualenv
Next, create a directory for the Django project and create a Django virtual environment:
mkdir ~/djangoapp
cd ~/djangoapp
virtualenv djangoenv
Next, activate the Django virtual environment using the command below:
source djangoenv/bin/activate
Next, install the Django, Gunicorn, and other packages using the following command:
pip install django gunicorn psycopg2-binary
At this point, Django is installed in the Python virtual environment. Now, you can proceed to the next step.
Install and Configure Django
Django provides a django-admin.py script to create a project. You can run the following command to create a Django project:
django-admin.py startproject djangoapp ~/djangoapp
Next, you will need to edit the settings.py and define your database settings:
nano ~/djangoapp/djangoapp/settings.py
Change the following line with your domain name:
ALLOWED_HOSTS = ['django.example.com', 'localhost']
Uncomment the default database backend and add the PostgreSQL database settings:
#DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': BASE_DIR / 'db.sqlite3', # } #} DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'django', 'USER': 'django', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } }
Add the following lines at the end of the file:
STATIC_URL = '/static/' import os STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Save and close the file then migrate the initial database schema to the PostgreSQL database:
./manage.py makemigrations
./manage.py migrate
Sample outputL:
Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying auth.0012_alter_user_first_name_max_length... OK Applying sessions.0001_initial... OK
Next, create a superuser account for Django with the following command:
./manage.py createsuperuser
Set your admin username and password as shown below:
Username (leave blank to use 'root'): dadmin Email address: [email protected] Password: Password (again): Superuser created successfully.
Next, gather all the static content into the directory:
./manage.py collectstatic
Run the Django Development Server
At this point, Django is installed and configured. You can now start the Django development server using the following command:
./manage.py runserver 0.0.0.0:8000
If everything is fine, you should get the following output:
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). August 27, 2021 - 10:02:05 Django version 3.2.6, using settings 'djangoapp.settings' Starting development server at http://0.0.0.0:8000/ Quit the server with CONTROL-C.
Now, open your web browser and access your Django project using the URL http://django.example.com:8000/admin/. You will be redirected to the Django login page:
Provide your admin username, password and click on the Login. You should see the Django dashboard on the following page:
Now, go back to your terminal and press CTRL + C to stop the Django development server.
Verify Django with Gunicorn
Next, you will also need to test whether the Gunicorn can serve the Django or not. You can start the Django using the Gunicorn server with the following command:
gunicorn --bind 0.0.0.0:8000 djangoapp.wsgi
If everything is fine, you should get the following output:
[2021-08-27 10:04:22 +0000] [47383] [INFO] Starting gunicorn 20.1.0 [2021-08-27 10:04:22 +0000] [47383] [INFO] Listening at: http://0.0.0.0:8000 (47383) [2021-08-27 10:04:22 +0000] [47383] [INFO] Using worker: sync [2021-08-27 10:04:22 +0000] [47384] [INFO] Booting worker with pid: 47384
Press CTRL + C to stop the Gunicorn server.
Next, deactivate from Python virtual environment with the following command:
deactivate
Create a Systemd Service File for Gunicorn
Next, you will need to create a systemd service file for the Gunicorn to start and stop the Django application server.
You can create a Gunicorn with the following command:
nano /etc/systemd/system/gunicorn.socket
Add the following lines:
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target
Save and close the file then create a service file for Gunicorn:
nano /etc/systemd/system/gunicorn.service
Add the following lines that match your Django project path:
[Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=root Group=www-data WorkingDirectory=/root/djangoapp ExecStart=/root/djangoapp/djangoenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock djangoapp.wsgi:application [Install] WantedBy=multi-user.target
Save and close the file then set proper permission to the Django project directory:
chown -R www-data:root ~/djangoapp
Next, reload the systemd daemon with the following command:
systemctl daemon-reload
Next, start the Gunicorn service and enable it to start at system reboot:
systemctl start gunicorn.socket
systemctl enable gunicorn.socket
Next, check the status of the Gunicorn using the command below:
systemctl status gunicorn.socket
You should get the following output:
? gunicorn.socket - gunicorn socket Loaded: loaded (/etc/systemd/system/gunicorn.socket; disabled; vendor preset: enabled) Active: active (listening) since Fri 2021-08-27 10:05:46 UTC; 6s ago Triggers: ? gunicorn.service Listen: /run/gunicorn.sock (Stream) CGroup: /system.slice/gunicorn.socket Aug 27 10:05:46 debian11 systemd[1]: Listening on gunicorn socket.
Configure Nginx as a Reverse Proxy For Django
Next, you will need to configure Nginx as a reverse proxy to serve Django.
To do so, create an Nginx configuration file:
nano /etc/nginx/conf.d/django.conf
Add the following lines:
server { listen 80; server_name django.example.com; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /root/djangoapp; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; } }
Save and close the file then verify the Nginx for any configuration error:
nginx -t
Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Finally, restart the Nginx service to apply the changes:
systemctl restart nginx
To check the status of the Nginx, run:
systemctl status nginx
Sample output:
? nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2021-08-27 10:06:59 UTC; 6s ago Docs: man:nginx(8) Process: 47494 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 47495 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 47496 (nginx) Tasks: 2 (limit: 2341) Memory: 2.5M CPU: 49ms CGroup: /system.slice/nginx.service ??47496 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; ??47497 nginx: worker process Aug 27 10:06:59 debian11 systemd[1]: Starting A high performance web server and a reverse proxy server... Aug 27 10:06:59 debian11 systemd[1]: nginx.service: Failed to parse PID from file /run/nginx.pid: Invalid argument Aug 27 10:06:59 debian11 systemd[1]: Started A high performance web server and a reverse proxy server.
Now, you can access the Django application using the URL http://django.example.com/admin. You can also access the Django application using the URL http://django.example.com/.
Conclusion
Congratulations! you have successfully installed a Django application with Gunicorn and Nginx as a reverse proxy. You can now start deploying your Python application using the Django framework.