This document is created with reference to the corresponding tutorial.
I checked that all of the following works correctly in the two system configurations.
One is a local environment, one is a cloud environment.
- Local
Ubuntu 20.04+Python 3.8.10+PostgreSQL 12.12
- Oracle Cloud
Ubuntu 22.04+Python 3.10.6+PostgreSQL 14.5
The configuration below is the same for all environments.
- Django 4.1.2
- Gunicorn 20.1.0
- Nginx 1.18.0
$ sudo apt-get update
$ sudo apt-get upgradeThis document uses PostgreSQL as the database.
$ sudo apt-get install python-is-python3 python3-pip python3-venv python3-dev
$ sudo apt-get install libpq-dev postgresql postgresql-contrib$ echo "export PATH=\$PATH:\$HOME/.local/bin" >> ~/.bashrc
$ source ~/.bashrc$ mkdir project_dir
$ cd project_dir$ mkdir project
$ mkdir sock
$ sudo chown {user_name}:www-data sockNow, create a virtual environment and install the required pip modules.
$ python -m venv venv
$ source venv/bin/activate(venv) $ pip install django gunicorn
(venv) $ pip install psycopg2-binary(venv) $ cd project
(venv) $ django-admin startproject conf .(venv) $ sudo -u postgres psqlpostgres=# CREATE DATABASE project_db;
postgres=# CREATE USER project_user WITH PASSWORD 'password';
postgres=# ALTER ROLE project_user SET client_encoding TO 'utf8';
postgres=# ALTER ROLE project_user SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE project_user SET timezone TO 'UTC';
postgres=# GRANT ALL PRIVILEGES ON DATABASE project_db TO project_user;
postgres=# \q
(venv) $ vi conf/settings.pyEnter the server address or domain that can connect to Django.
Addresses are separated by commas.
ALLOWED_HOSTS = ['*']Now modify the database information.
As mentioned earlier, this document uses PostgreSQL.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'project_db',
'USER': 'project_user',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}Add the contents below under STATIC_URL = 'static/'.
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')Now we can use the manage.py script to migrate the database schema to the PostgreSQL database.
(venv) $ python manage.py makemigrations
(venv) $ python manage.py migrateCreate a project manager using the commands below.
(venv) $ python manage.py createsuperuserStatic contents (js, css ...) can be collected using the command below.
(venv) $ python manage.py collectstaticIf you are using cloud services, please follow the instructions below.
Open 8000 ports in the cloud, and the server also generates exceptions for 8000 ports.
(venv) $ sudo ufw allow 8000
(venv) $ sudo ufw allow 8000/tcpVerify that the django server is working well.
(venv) $ python manage.py runserver 0.0.0.0:8000First, make sure that you can serve the application through the Gunicorn test.
(venv) $ gunicorn --bind 0.0.0.0:8000 conf.wsgiIf it works well, exits the virtual environment.
(venv) $ deactivateCreate a Gunicorn service file in the path below.
$ sudo vi /etc/systemd/system/gunicorn.serviceWrite the following content.
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User={user_name}
Group=www-data
WorkingDirectory=/home/{user_name}/project_dir/project
ExecStart=/home/{user_name}/project_dir/venv/bin/gunicorn \
--workers 2 \
--bind unix:/home/{user_name}/project_dir/sock/gunicorn.sock \
conf.wsgi:application
[Install]
WantedBy=multi-user.targetStart the Gunicorn service, and check the status.
$ sudo systemctl daemon-reload
$ sudo systemctl enable gunicorn
$ sudo systemctl start gunicorn
$ sudo systemctl status gunicornInstall Nginx and create an Nginx configuration file in the path below.
$ sudo apt install nginx
$ sudo vi /etc/nginx/site-available/project.confWrite the following content.
server {
listen 80;
server_name {your_ip_address}; # your ip or domain address
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/{user_name}/project_dir/project;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/{user_name}/project_dir/sock/gunicorn.sock;
}
}
Attach a symbolic link to the Nginx configuration file and test it to see if it works.
$ sudo ln -s /etc/nginx/sites-available/project.conf /etc/nginx/sites-enabled/
$ sudo nginx -t # testThe results should be as follows.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulRestart the Nginx, and check the status.
$ sudo systemctl enable nginx
$ sudo systemctl restart nginxNow you can access your Django application without having to access the development server.
Instead, you need to open a firewall for normal traffic on port 80.
You may also remove exceptions for port 8000.
$ sudo ufw allow 'Nginx Full'
$ sudo ufw delete allow 8000
$ sudo ufw delete allow 8000/tcpNow enjoy your jango application!