Django is a free, open-source and high-level web framework used for developing Python Web Applications. It comes with a set of tools that helps you to build secure and scalable web applications. Its main goal is to ease the creation of complex applications and takes care of the internal structure.
In this tutorial, we will learn how to install Django and configure Nginx as a reverse proxy for Django on CentOS 8.
Prerequisites
- A server running CentOS 8.
- A root password is configured on your server.
Install Required Packages
Django is a Python-based framework so you will need to install Python and PIP in your system. You can install them by running the following command:
dnf install python36 python3-pip -y
Once both packages are installed, you can proceed to the next step.
Install Django
You can install Django with PIP command as shown below:
pip3 install Django
After installing Django, you can check the version of Django with the following command:
django-admin --version
You should see the Django version in the following output:
3.0.3
Create a Django Project
At this point, Django is installed. Now, it's time to create a new Django application.
You can create a new Django application using the django-admin command inside the /opt directory as shown below:
cd /opt
django-admin startproject djangoproject
Once the django project has been created, change the directory to djangoproject and migrate the changes with the following command:
cd djangoproject
python3 manage.py migrate
You should get the following output:
Operations to perform: 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 sessions.0001_initial... OK
Next, you will need to create an admin user account for managing the Django project. You can create it with the following command:
python3 manage.py createsuperuser
You will be asked to provide your username, email and password. You can provide them as per your choice as shown below:
Username (leave blank to use 'root'): dadmin Email address: admin@example.com Password: Password (again): Superuser created successfully.
Once you are finished, you can proceed to the next step.
Start Django Application
By default, the Django application can not be accessed from the remote hosts. So you will need to allow Django for external hosts. You can do it by adding your server IP in settings.py:
nano /opt/djangoproject/djangoproject/settings.py
Change the following line:
ALLOWED_HOSTS = ['your-server-ip']
Save and close the file. Then, start the Django application with the following command:
cd /opt/djangoproject
python3 manage.py runserver 0.0.0.0:8000
You should see the following output:
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). March 03, 2020 - 02:31:19 Django version 3.0.3, using settings 'djangoproject.settings' Starting development server at http://0.0.0.0:8000/ Quit the server with CONTROL-C. Django application is now started and runs on port 8000.
At this point, the Django application is now started and runs on port 8000. You can now proceed to the next step.
Configure SELinux and Firewall
Next, you will need to allow port 8000 and 80 through firewalld. You can allow them with the following command:
firewall-cmd --permanent --add-port=8000/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
Next, configure SELinux with the following command:
setsebool httpd_can_network_connect on -P
Once you are finished, you can proceed to the next step.
Access Django Application
You can access the Django application by visiting the URL http://your-server-ip:8000. You should see the following page:
You can also access the Django admin interface using the URL http://your-server-ip:8000/admin. You should see the following page:
Provide your admin username, password and click on the Log in button. You should see the following page:
Install Nginx and Gunicorn
In this section, we will install Gunicorn to create and manage Django service, and Nginx to serve Django application.
First, install the Nginx with the following command:
dnf install nginx -y
Next, install Gunicorn using the PIP command as shown below:
pip3 install gunicorn
Once both packages are installed, start the Nginx service and enable it to start after system reboot with the following command:
systemctl start nginx
systemctl enable nginx
Next, change the ownership of /opt/djangoproject directory to Nginx as shown below:
chown -R nginx:nginx /opt/djangoproject
Create a Systemd Service File For Django
Next, create a systemd service file for managing Django service with the following command:
nano /etc/systemd/system/django.service
Add the following lines:
[Unit] Description=django daemon After=network.target [Service] User=nginx Group=nginx WorkingDirectory=/opt/djangoproject ExecStart=/usr/local/bin/gunicorn --workers 3 --bind unix:/opt/djangoproject/djangoproject.sock djangoproject.wsgi:application [Install] WantedBy=multi-user.target
Save and close the file then reload the systemd daemon with the following command:
systemctl daemon-reload
Next, start the Django service and enable it to start after system reboot with the following command:
systemctl start django
systemctl enable django
You can now check the status of Django service with the following command:
systemctl status django
You should see the following output:
? django.service - django daemon Loaded: loaded (/etc/systemd/system/django.service; disabled; vendor preset: disabled) Active: active (running) since Mon 2020-03-02 22:27:51 EST; 3min 32s ago Main PID: 960 (django) Tasks: 4 (limit: 25028) Memory: 95.2M CGroup: /system.slice/django.service ??960 /usr/bin/python3.6 /usr/local/bin/gunicorn --workers 3 --bind unix:/opt/djangoproject/djangoproject.sock djangoproject.wsgi:a> ??964 /usr/bin/python3.6 /usr/local/bin/gunicorn --workers 3 --bind unix:/opt/djangoproject/djangoproject.sock djangoproject.wsgi:a> ??965 /usr/bin/python3.6 /usr/local/bin/gunicorn --workers 3 --bind unix:/opt/djangoproject/djangoproject.sock djangoproject.wsgi:a> ??966 /usr/bin/python3.6 /usr/local/bin/gunicorn --workers 3 --bind unix:/opt/djangoproject/djangoproject.sock djangoproject.wsgi:a> Mar 02 22:27:51 centos8 systemd[1]: Started django daemon. Mar 02 22:27:52 centos8 django[960]: [2020-03-02 22:27:52 -0500] [960] [INFO] Starting django 20.0.4 Mar 02 22:27:52 centos8 django[960]: [2020-03-02 22:27:52 -0500] [960] [INFO] Listening at: unix:/opt/djangoproject/djangoproject.sock (960) Mar 02 22:27:52 centos8 django[960]: [2020-03-02 22:27:52 -0500] [960] [INFO] Using worker: sync Mar 02 22:27:52 centos8 django[960]: [2020-03-02 22:27:52 -0500] [964] [INFO] Booting worker with pid: 964 Mar 02 22:27:52 centos8 django[960]: [2020-03-02 22:27:52 -0500] [965] [INFO] Booting worker with pid: 965 Mar 02 22:27:52 centos8 django[960]: [2020-03-02 22:27:52 -0500] [966] [INFO] Booting worker with pid: 966 h pid: 966
Configure Nginx for Django
Next, you will need to configure Nginx as a reverse proxy for Django. To do so, create a new Nginx configuration file with the following command:
nano /etc/nginx/conf.d/django.conf
Add the following lines:
server { listen 80; server_name your-server-ip location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /opt/djangoproject; } location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://unix:/opt/djangoproject/djangoproject.sock; } }
Save and close the file when you are finished. Then, test the nginx for any syntax error with the following command:
nginx -t
If everything is fine, you should get the following output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Next, restart the Nginx service to implement the changes:
systemctl start nginx
You can also verify the Nginx with the following command:
systemctl status nginx
You should get the following output:
? nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) Active: active (running) since Mon 2020-03-02 22:28:13 EST; 4min 14s ago Process: 984 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS) Process: 982 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS) Process: 980 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS) Main PID: 985 (nginx) Tasks: 3 (limit: 25028) Memory: 5.5M CGroup: /system.slice/nginx.service ??985 nginx: master process /usr/sbin/nginx ??986 nginx: worker process ??987 nginx: worker process Mar 02 22:28:12 centos8 systemd[1]: Starting The nginx HTTP and reverse proxy server... Mar 02 22:28:12 centos8 nginx[982]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok Mar 02 22:28:12 centos8 nginx[982]: nginx: configuration file /etc/nginx/nginx.conf test is successful Mar 02 22:28:13 centos8 systemd[1]: Started The nginx HTTP and reverse proxy server.
You can now access your Django application using the URL http://your-server-ip.
Conclusion
In this guide, we learned how to install Django on CentOS 8. We also learned how to use Gunicorn to create and manage the Django service and configure Nginx as a reverse proxy to serve Django application.