Sistemas Nimbus

Diseño Web • Software a Medida • Soluciones Digitales

Puesta en producción de un servidor Django 2

Para la implementación en este tutorial utilizaremos Nginx, Virtualenv y Gunicorn en Ubuntu 18.04.

Paso 1: Actualizar paquetes

apt-get update: Actualiza el listado de paquetes disponibles junto a su últimas versiones. No descarga ningún paquete.

apt-get upgrade: Descarga las actualizaciones de los paquetes del listado actualizado con el comando anterior.

sudo apt-get update
sudo apt-get upgrade

Paso 2: Instalar paquetes necesarios y Python 3

La primer línea instala paquetes que contienen encabezados necesarios para desarrollos.

La siguiente línea instala Python 3 y archivos cabeceras necesarios para la creación de paquetes de Python.

sudo apt-get install build-essential libpq-dev libssl-dev openssl libffi-dev zlib1g-dev
sudo apt-get install python3-pip python3-dev software-properties-common python-software-properties

Paso 3: Instalar Virtualenv

¿Que es virtualenv?

Es una herramienta que se utiliza para crear entornos aislados de Python. Podemos instalar los paquetes que deseemos para el proyecto en el que trabajemos sin alterar la raíz de Python ni otros proyectos.

Instalación:

pip3 install virtualenv

Nos ubicamos en la carpeta donde vamos a guardar todo el proyecto y creamos el entorno. Por ejemplo "/home/proyecto".

cd /home/proyecto
virtualenv -p python3 venv
Con "-p python3" nos aseguramos de que el entorno será con Python 3

Activar el entorno:

source venv/bin/activate

La consola mostraría algo similar a esto:

(venv) root@server:/home/proyecto# 
El (venv) indica que ya estamos dentro de nuestro entorno.

Paso 3: Crear proyecto Django

En este tutorial crearemos un proyecto nuevo, pero en caso de tener un proyecto ya creado, solamente copien la carpeta de su proyecto a la de "/home/proyecto".

Instalación:
pip install django
Podemos usar pip o pip3 sin problema ya que sólo tendríamos Python 3 instalado y ambos "pips" instalarían el paquete sobre el mismo entorno.
Creación del proyecto:
# /home/proyecto
django-admin startproject miproyecto

Paso 4: Configurar settings.py

Dentro de la raíz del proyecto (/home/proyecto/miproyecto) se encuentra una carpeta llamada igual (miproyecto) que contiene el archivo settings.py. En este archivo van todas las configuraciones necesarias para nuestro proyecto.

Es necesario modificar el valor de ALLOWED_HOST:
# /home/proyecto/miproyecto/miproyecto/settings.py
ALLOWED_HOSTS = ['*']

Por dejecto Django viene configurado para conectar con una base de datos SQLITE, sugerimos cambiar la base de datos a Postgres. En este caso a modo de ejemplo continuaremos con SQLITE.

Migrar la base de datos: Tendremos que estar ubicado en la raíz del proyecto (/home/proyecto/miproyecto), que es donde se encuentra el archivo manage.py

# /home/proyecto/miproyecto
python manage.py migrate

Paso 5: Instalar gunicorn

Gurnicorn será el encargado de ejecutar nuestro proyecto y servirá de medidador para las solicitudes de la web.

Instalación:
pip install gunicorn

Antes de crear el archivo gunicorn.sh debemos crear las siguientes carpetas en el directorio del proyecto (/home/proyecto)

# /home/proyecto
mkdir logs
mkdir sock
La carpeta logs sirve para guardar todos los logs que va a registrar gunicorn y nginx, y sock es donde se generará el socket de nuestra web.

Dentro de /home/proyecto creamos el archivo gunicorn.sh

nano gunicorn.sh

Contenido de gunicorn.sh (/home/proyecto/gunicorn.sh)

#!/bin/bash

NAME="miproyecto"
DJANGODIR=/home/miproyecto/miproyecto
SOCKFILE=/home/miproyecto/sock/gunicorn.sock
LOGFILE=/home/miproyecto/logs/gunicorn.log
USER=root
GROUP=root
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=nimbus.settings
DJANGO_WSGI_MODULE=nimbus.wsgi

cd $DJANGODIR
source ../venv/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

gunicorn ${DJANGO_WSGI_MODULE}:application \
  --name $NAME\
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind=unix:$SOCKFILE \
  --log-level=debug \
  --log-file=$LOGFILE \
  --timeout=300

También creamos gunicorn_stop.sh para la detención del servicio.

gunicorn_stop.sh
#!/bin/bash
kill -9 `ps aux |grep gunicorn |grep miproyecto | awk '{ print $2 }'`

Les otorgamos los permisos de ejecución necesarios:
# /home/proyecto
chmod a+x gunicorn.sh
chmod a+x gunicorn_stop.sh

Paso 5.1: Crear servicio de Gunicorn

Creamos el servicio para que esté ejecutandose en todo momento.

Creamos el archivo del servicio:
nano /etc/systemd/system/miproyecto.service

Con el siguiente contenido:
# /etc/systemd/system/miproyecto.service
[Unit]
Description=Servicio de miproyecto

[Service]
ExecStart=/home/proyecto/gunicorn.sh
ExecStop=/home/proyecto/gunicorn_stop.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

Iniciar el servicio Gunicorn del proyecto
sudo systemctl status miproyecto
sudo systemctl daemon-reload
sudo systemctl restart miproyecto
sudo systemctl enable miproyecto.service

Paso 6: Instalar Nginx

Nginx va a ser utilizado como servidor web para conectar el socket de gunicorn a internet. Además puede ser utilizado para cachear nuestros archivos estáticos y proxy.

Instalación:
sudo apt-get install nginx

Una vez instalado creamos el archivo de configuración para nginx.

nano /etc/nginx/sites-enabled/miproyecto.conf

Contenido de miproyecto.conf:
upstream nimbus {
    server unix:/home/proyecto/sock/gunicorn.sock fail_timeout=10;
}

server {
    listen 80;
    server_name miproyecto.com www.miproyecto.com;
    
    gzip on;
    gzip_min_length 1000;
    gzip_proxied    expired no-cache no-store private auth;
    gzip_types      text/plain text/css application/javascript application/xml;

    proxy_connect_timeout  600;
	proxy_send_timeout    600;
	proxy_read_timeout    600;
	send_timeout      600;

    charset utf-8;

    client_max_body_size 4G;
    error_log /home/proyecto/logs/nginx_access_new.log;
    access_log /home/proyecto/logs/nginx_error_new.log;
    
    location / {
        proxy_pass http://unix:/home/proyecto/sock/gunicorn.sock;
        gzip on;
        gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
}

Para evitar inconvenientes sugiero que eliminen el archivo default contenido en /etc/nginx/sites-enabled/

sudo rm /etc/nginx/sites-enabled/default

Corroboramos que nginx no arroje ningún error
nginx -t

Si está todo en orden nos mostraría algo similar a lo siguiente:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Como último paso, reiniciamos nginx y nuestro sitio estaría en producción
sudo systemctl restart nginx

¡Y listo! Ya tenemos nuestro proyecto Django 2 en producción.

Ante cualquier duda, consulta o sugerencia no dudes en escribirnos. ¡Tu contacto será bienvenido!

Escrito por Diego Dopazo - 22 de Mayo de 2019 a las 19:29