How to Deploy Your Django App on Centos 7 Server with Nginx and Gunicorn
Setting up a server with black and white screen seems scary. You are not alone, I was like that too. But don’t worry, if you follow the steps below, you will be fine. Believe me, it’s not as scary as it seems. Without further a do, let’s get started! This time, we are going to use Centos 7 as the server. So make sure you are using this exact linux distro.
A. Preparations
For security reason I usually don’t use root user to deploy my apps, so let’s start with creating a new linux user.
# adduser your_username
Then give it the ability to become sudoer.
# usermod -a -G wheel your_username
Also create a new password for this new linux user.
# passwd your_username
To make life easy let’s create the ssh key!# cd /home/your_username
# mkdir .ssh
# cd .ssh
# nano authorized_keys
(you may need to install nano beforehand, or you may use vi instead)
Copy paste the ~/.ssh/id_rsa.pub
from your computer, then save. After that, exit from your root terminal, and relogin using your new linux user. Voilaa! Let’s continue to the next step!
B. Software Installation
In this section we are going to install the necessary software such as Python 3, Nginx, GCC, and MariaDB. Here are the steps:
- Enable the EPEL repository
$ sudo yum install epel-release
- Update linux packages
$ sudo yum update
- Install Python 3 and Nginx
$ sudo yum install python3-pip python3-devel nginx
- Install GCC and MariadB
$ sudo yum install gcc mariadb-server mariadb-devel
$ sudo systemctl start mariadb
$ sudo systemctl enable mariadb
$ sudo mysql_secure_installation
- After the MariaDB installation, we need to create a new database for the app, along with the database user.
Run this command from your terminal:$ mysql -u root -p
Create a new database and a new user with mysql:mysql> CREATE DATABASE your_db_name;
mysql> CREATE USER your_db_username@localhost IDENTIFIED BY ‘your_db_password’;
mysql> GRANT ALL PRIVILEGES ON your_db_name.* TO your_db_username@localhost;
mysql> FLUSH PRIVILEGES;
- Copy your django app into your home directory. Or you may clone your app from github (you need to install git to do it).
- Create virtual environment inside your project.
$ python -m venv ./venv
- Then activate the virtual environment.
$ source venv/bin/activate
- Install the required packages into your virtual environment by using pip. This time, we are going to install gunicorn, mysqlclient, and Django 3.1.
(venv)$ python -m pip install gunicorn mysqlclient Django==3.1
- And then you need to do some configuration to your app, like your database setting, makemigrations, migrate and createsuperuser.
C. Gunicorn Configuration
Let’s start with testing the gunicorn.(venv)$ gunicorn — bind <ip:port> your_main_app.wsgi:application
If you open the app with the ip and port in your browser, and it shows your app (though a bit messy/without styling) then congrats. Continue to the next step!
Since we’re gonna configure gunicorn, so let’s first deactivate the virtual environment.(venv)$ deactivate
Create gunicorn service file.$ sudo nano /etc/systemd/system/gunicorn.service
Then paste this script below, and adjust accordingly.
Then start the gunicorn.$ sudo systemctl start gunicorn
$ sudo systemctl enable gunicorn
D. Nginx Configuration
First, open the nginx configuration file.$ sudo nano /etc/nginx/nginx.conf
Then find the http section, and then nested inside it, there would be server section.
Paste the script below or replace the server {} (like the highlighted in the picture), and adjust accordingly.
With that our nginx is good, we only need a bit more to do. Let’s continue!
Run this on your terminal:$ sudo usermod -a -G your_linux_user nginx
$ chmod 710 /home/your_linux_user
Then do nginx test:$ sudo nginx -t
If no errors, start nginx:$ sudo systemctl start nginx
$ sudo systemctl enable nginx
Finally, our app is running!
If you have done all of the instructions above, and yet, your app is still not running. It is probably because the SELinux is blocking the access. If you don’t know how to configure your SELinux, you may as well set it into permissive. Here is how:$ sudo setenforce 0
If you want to learn in depth about SELinux configuration for nginx you can use this blog from nginx.com as reference.
Okay, I hope it helps. Good luck!