Cómo configurar Django con Postgres, Nginx y Gunicorn en Ubuntu 18.04

By fcetina April 27, 2022, 7:50 p.m. Deploy Django

1 Instalar los paquetes desde los repositorios de Ubuntu

Como primer paso es necesario actualizar el indice de paquetes local e instalar los repositorios necesarios.

Si usas Python3

sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

Si usas Python2

sudo apt update
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl

2 Crear la base de datos

Ahora crearemos una base de datos en postgresql para nuestro projecto de django

Inicia sesion con el usuario sudo a postgresql

sudo -u postgres psql

Crea una base datos

CREATE DATABASE django_db;

Crea un usuario de base de datos

CREATE USER myprojectuser WITH PASSWORD 'password';

Configuraremos el codigo predeterminado, el esquema de aislamiento de transacciones y la zona horario de la base de datos:

ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser SET timezone TO 'UTC';

Asignamos permisos a la base de datos para el usuario que creamos

GRANT ALL PRIVILEGES ON DATABASE django_db TO myprojectuser;

Al terminar podemos cerrar la linea de comandos de postgres con

\q

3 Crear un entorno virtual

Ya tenemos la base de datos, ahora es momento de crear un entorno virtual para instalar y aislar los componentes que usaremos en nuestro proyecto de django

Si usa Python3

sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv

Si usa Python2

sudo -H pip install --upgrade pip
sudo -H pip install virtualenv

Una vez instalado, comenzaremos a darle estructura a nuestro projecto.

Cree un directorio par aguardar todo lo necesario y muevase a el

mkdir ~/myprojectdir
cd ~/myprojectdir

Cree un entorno virtual con el siguiente comando:

virtualenv myprojectenv

Esto creará internamente una version de Python que usaremos en nuestro projecto, con este podemos instalar los paquetes necesarios a nuestro porjecto de manera ailada

Para activar el entorno usaremos este comando:

source myprojectenv/bin/activate

Para desactivar el entorno usa:

deactivate

Al activar el entorno su linea de comandos cambiará para indicar que ahora realiza operaciones bajo el entorno virtual, la linea de comando quedará así siempre que active el entorno virtual

(myprojectenv)user@host:~/myprojectdir$.

Lo siguiente es instalar Django, Gunicorn y el adaptador psycopg2 de PostgreSQL en el entorno con la instalacia local de pip


NOTA

Cuando active el entorno y use la instancia pip siempre que este activado el entorno deberá usar pip y no pip3, incluso si usas python3. Ya que la copia del entorno virtual siempre es llamada pip


Instale con pip

(myprojectenv) pip install django gunicorn psycopg2-binary

4 Crear y configurar un nuevo proyecto de Django

Con el entorno activado inicie un proyecto de django

(myprojectenv) django-admin.py startproject myproject ~/myprojectdir

Configure el settings.py

Conecte la base de datos

Edite el archivo settings.py

nano ~/myprojectdir/myproject/settings.py

Encuentre la variable DATABASES y modifiquela por:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'djando_db',
        'USER': 'myprojectuser',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

Dirigase el final del archivo y agregue estas lineas que indican donde se almacenarán los estaticos del proyecto

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

5 Completar la configuracion inicial del proyecto de Django

Ahora es necesario hacer migraciones

(myprojectenv) $ ~/myprojectdir/manage.py makemigrations
(myprojectenv) $  ~/myprojectdir/manage.py migrate

Cree un superusuario

(myprojectenv) $ ~/myprojectdir/manage.py createsuperuser

Se le solicitara un username, email y password

Realize un collectstatic

(myprojectenv) $ ~/myprojectdir/manage.py collectstatic

Puedes probar su proyecto iniciando el server en el puerto 8000 con el siguiente comando

(myprojectenv) $ ~/myprojectdir/manage.py runserver 0.0.0.0:8000

Puede abrir en un navegador web y poner la ip de su computadora seguido de :8000 para abrir el proyecto

http://server_domain_or_IP:8000

Deberá ver algo como esto:

django_index.png

Si agrega /admin a la url inicial, deberá ver el admin de django el cual le pedira el usuario y contraseña creado con createsuperuser

6 Probando Gunicorn

Podemos poner a prueba gunicorn con los siguientes comandos:

(myprojectenv) $ cd ~/myprojectdir
(myprojectenv) $ gunicorn --bind 0.0.0.0:8000 myproject.wsgi

Ahora puede abrir nuevamente el proyecto en el navegador web y verá que el proyecto esta corriendo


NOTA

Corriendo con gunicorn si abre el panel admin, verás que no carga los archivos CSS, esto se debe a que no cargan los estaticos de admin por que gunicorn no tiene manera de encontrarlos, depués veremos como solucionar este inconveniente


7 Socket y service para gunicorn

Ahora debemos poder parar y reiniciar nuestro proyecto de gunicorn con systemd.

Cree un archivo socket de systemd.

sudo nano /etc/systemd/system/my_proyecto.socket

Agregue lo siguiente:

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/my_proyecto.sock

[Install]
WantedBy=sockets.target

Ahora crearemos el servicio my_proyecto.service

Agregue lo siguiente remplazando las rutas por la ruta de tus proyectos.

[Unit]
Description=gunicorn daemon
Requires=my_proyecto.socket
After=network.target

[Service]
User=fernando
Group=www-data
WorkingDirectory=/home/fernando/myprojectdir
ExecStart=/home/fernando/myprojectdir/myprojectenv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/my_proyecto.sock \
          myproject.wsgi:application

[Install]
WantedBy=multi-user.target

Ahora podemos habilitar e iniciar el socket

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

Envia una peticion al socket para activar my_proyecto.service con el siguiente comando

curl --unix-socket /run/my_proyecto.sock localhost

8 Configurar Nginx

Crea el sitio my_proyecto en nginx

sudo nano /etc/nginx/sites-available/my_proyecto

Agrega el siguiente contenido (remplaza la ruta /home/fernando por la ruta de tu proyecto y server_name por tu ip o dominio):

server {
    listen 80;
    server_name server_name_or_ip;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/fernando/myprojectdir;
    }


    location / {
        include proxy_params;
        proxy_pass http://unix:/run/my_proyecto.sock;
    }

}

Crea un enlace simbolico de my_proyecto a sites-enabled

sudo ln -s /etc/nginx/sites-available/my_proyecto /etc/nginx/sites-enabled

Reinicia nginx

sudo systemctl restart nginx

Por ultimo abre en tu navegador nuevamente tu proyecto sin puerto y debes poder ver el proyecto.

http://server_domain_or_IP