Introducción
Django es un marco web que facilita el lanzamiento de aplicaciones Python o un sitio web. Django incluye un servidor de desarrollo para probar el código localmente.
En este tutorial veremos cómo instalar y configurar Django con una base de datos PostgreSQL en un servidor Gunicorn que interactúa con aplicaciones escritas en Python. Finalmente instalaremos Nginx como proxy inverso para Gunicorn.
Ubuntu 18.04 LTS.
Prerrequisitos
Antes de comenzar esta guía, debe tener un usuario no root con privilegios sudo configurado en su servidor. Siga esta guía: Configuración inicial en Ubuntu 18.04 LTS
Instalar Python PostgreSQL Nginx
Descargue todos los paquetes necesarios para continuar con este tutorial, puede usar los repositorios oficiales de Ubuntu directamente. Actualice el índice del paquete apt local y luego descargue e instale los paquetes necesarios. Desde la terminal:
sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl
Configurar PostgreSQL
Durante la fase de instalación de Postgres un nuevo usuario del sistema Postgres se creará el cual tendrá el mismo nombre que el usuario de administración de PostgreSQL. Debemos utilizar este usuario para realizar tareas administrativas. Luego inicie sesión con el nuevo usuario con la opción -u:
sudo -u postgres psql
Cree una base de datos para nuestra aplicación:
CREATE DATABASE myapp;
Cree un usuario para nuestra nueva base de datos:
CREATE USER myappuser WITH PASSWORD 'TUA_PASSWORD';
Establezca algunos parámetros recomendados para la nueva base de datos:
ALTER ROLE myappuser SET client_encoding TO 'utf8';
ALTER ROLE myappuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myappuser SET timezone TO 'UTC';
Otorgue al nuevo usuario privilegios de administrador a la base de datos:
GRANT ALL PRIVILEGES ON DATABASE myapp TO myappuser;
Salga del indicador de PostgreSQL:
\q
Crea un entorno virtual en Python para administrar nuestra App
Instale virtualenv usando pip:
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv
Cree una nueva carpeta para nuestra aplicación:
mkdir ~/myappdir
Ingrese a la carpeta recién creada:
cd ~/myappdir
Crea un entorno virtual en Python:
virtualenv myappenv
Este comando creará un directorio llamado myappenv dentro del directorio myappdir. En el interior, instalará una versión local de Python y una versión local de pip. Podemos usarlo para instalar y configurar un entorno Python aislado para nuestro proyecto.
Activar el entorno virtual:
source myappenv/bin/activate
Su mensaje debería cambiar para indicar que ahora está operando dentro de un entorno virtual de Python. Ejemplo:
(myappenv) user@host:~/myappdir$.
Cuando el entorno virtual está activado, use pip en lugar de pip3, incluso si está usando Python 3.
Instale los requisitos de Python de nuestro proyecto:
pip install django gunicorn psycopg2-binary
Crea una aplicación Django
Como ya tenemos un directorio de proyecto, le diremos a Django que instale los archivos en el mismo directorio:
django-admin.py startproject myapp ~/myappdir
Cambie las configuraciones en el archivo settings.py
nano ~/myappdir/myapp/settings.py
Busque la entrada ALLOWED_HOSTS, esta entrada define una lista de direcciones IP de servidor o nombres de dominio que se pueden usar para conectarse a la instancia de Django. Cualquier solicitud que llegue con un encabezado de Host que no esté presente en esta lista generará una excepción.
Entre corchetes, enumere las direcciones IP o los nombres de dominio asociados con su servidor Django. Cada dirección IP o nombre de dominio debe escribirse entre comillas con entradas separadas por una coma. Ejemplo:
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['NOME_DOMINIO', 'INDIRIZZO_IP',..., 'localhost']
Luego busque la entrada DATABASES para configurar el acceso a nuestra base de datos PostgreSQL
Cambie la configuración con la información de su base de datos PostgreSQL:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myapp',
'USER': 'myappuser',
'PASSWORD': 'TUA_PASSWORD',
'HOST': 'localhost',
'PORT': '',
}
}...
A continuación, vaya al final del archivo y agregue una configuración que indique dónde deben colocarse los archivos estáticos. Esto es necesario para que Nginx maneje las solicitudes:
...
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Migre el esquema de base de datos inicial a nuestra base de datos PostgreSQL:
~/myappdir/manage.py makemigrations
~/myappdir/manage.py migrate
Cree un usuario administrador para nuestro proyecto:
~/myappdir/manage.py createsuperuser
Ingrese toda la información necesaria para crear el nuevo usuario administrador.
Mueva todos los archivos estáticos a una carpeta llamada estática dentro de nuestro proyecto:
~/myappdir/manage.py collectstatic
Si tiene el firewall (UFW) activo, debe habilitar el puerto 8000:
sudo ufw allow 8000
Prueba la aplicación
Inicie la aplicación desde la terminal:
~/myappdir/manage.py runserver 0.0.0.0:8000
Abra el navegador y conéctese a la dirección IP del servidor o al nombre de dominio:
http://DOMINIO_OPPURE_IP:8000
Para ingresar al panel de administración, agregue /admin al final del enlace:
http://DOMINIO_OPPURE_IP:8000/admin
Inicie sesión con el usuario y la contraseña generados con el comando createuperuser.
Para cerrar la aplicación y apagar el servidor presione CTRL-C en la terminal.
Pruebe la aplicación usando Gunicorn
Ingrese a nuestro directorio de proyectos y use gunicorn para cargar el módulo WSGI del proyecto:
cd ~/myappdir
gunicorn --bind 0.0.0.0:8000 myapp.wsgi
La interfaz de administración no tendrá ningún estilo ya que Gunicorn no sabe cómo encontrar contenido CSS estático.
Presione CTRL-C en la ventana del terminal para detener Gunicorn.
Podemos salir de nuestro entorno virtual escribiendo:
deactivate
Cree los sockets y los archivos de servicio systemd para Gunicorn El zócalo Gunicorn se creará al inicio y escuchará las conexiones. Cuando se produce una conexión, systemd iniciará automáticamente el proceso de Gunicorn para administrar la conexión.
Cree y abra un archivo de socket systemd para Gunicorn:
sudo nano /etc/systemd/system/gunicorn.socket
Inserte las siguientes líneas de código:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Guarde y cierre el archivo.
A continuación, cree y abra un archivo de servicio systemd para Gunicorn. El nombre del archivo de servicio debe coincidir con el nombre del archivo de socket con la excepción de la extensión:
sudo nano /etc/systemd/system/gunicorn.service
Especifique el usuario y el grupo que queremos usar para la ejecución. Ingrese las siguientes líneas de código, modificando los campos necesarios con sus datos:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=TUO_UTENTE
Group=www-data
WorkingDirectory=/home/TUO_UTENTE/myappdir
ExecStart=/home/TUO_UTENTE/myappdir/myappenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myapp.wsgi:application
[Install]
WantedBy=multi-user.target
Guarde y cierre el archivo
Ahora podemos iniciar y habilitar el socket Gunicorn. Esto creará el archivo de socket en /run/gunicorn.sock ahora y al inicio. Cuando se realiza una conexión a este socket, systemd iniciará automáticamente gunicorn.service para manejarlo:
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
Verifique el estado del archivo de socket Gunicorn:
sudo systemctl status gunicorn.socket
Compruebe la existencia del archivo gunicorn.sock:
file /run/gunicorn.sock
Debería recibir un mensaje de salida similar al siguiente:
/run/gunicorn.sock: socket
Si el comando systemctl status indica que se ha producido un error o que el archivo gunicorn.sock no se encuentra en el directorio, es una indicación de que el socket Gunicorn no se pudo crear correctamente. Verifique los registros de socket de Gunicorn escribiendo:
Para comprobar los registros de sockets, incluidos los errores:
sudo journalctl -u gunicorn.socket
Posteriormente, después de haber activado gunicorn.socket también debes activar gunicorn.service con este comando:
curl --unix-socket /run/gunicorn.sock localhost
Para comprobar el estado del servicio Gunicorn:
sudo systemctl status gunicorn
Debería recibir un mensaje de salida similar al siguiente:
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2018-07-09 20:00:40 UTC; 4s ago
Main PID: 1157 (gunicorn)
Tasks: 4 (limit: 1153)
CGroup: /system.slice/gunicorn.service
├─1157 /home/noviello/myappdir/myappenv/bin/python3 /home/noviello/myappdir/myappenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myapp.wsgi:application
├─1178 /home/noviello/myappdir/myappenv/bin/python3 /home/noviello/myappdir/myappenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myapp.wsgi:application
├─1180 /home/noviello/myappdir/myappenv/bin/python3 /home/noviello/myappdir/myappenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myapp.wsgi:application
└─1181 /home/noviello/myappdir/mypmyappenvrojectenv/bin/python3 /home/noviello/myappdir/myappenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myapp.wsgi:application
Jul 09 20:00:40 django1 systemd[1]: Started gunicorn daemon.
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.sock (1157)
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
Jul 09 20:00:41 django1 gunicorn[1157]: - - [09/Jul/2018:20:00:41 +0000] "GET /HTTP/1.1" 200 16348 "-" "curl/7.58.0"
Para comprobar el estado de cualquier error:
sudo journalctl -u gunicorn
Si se realiza un cambio en el archivo /etc/systemd/system/gunicorn.service, los procesos de Gunicorn deberán reiniciarse:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
Configurar Nginx
Crea un nuevo bloque de servidor en Nginx:
sudo nano /etc/nginx/sites-available/myapp
Configure el archivo de esta manera, asegurándose de cambiar los campos necesarios con sus datos:
server {
listen 80;
server_name DOMINIO_OPPURE_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/{
root /home/TUO_UTENTE/myappdir;
}
location /{
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
Configuramos Nginx para encontrar archivos estáticos en nuestro directorio creado previamente y agregamos los parámetros proxy_params y proxy_pass para pasar el tráfico directamente al socket Gunicorn.
Guarde y cierre el archivo.
Habilite el bloque de servidor recién creado:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled
Verifique las configuraciones de nginx:
sudo nginx -t
Si no hay errores, reinicie nginx:
sudo systemctl restart nginx
Si usa el firewall de Ubuntu (Ufw), ahora es necesario cambiar las reglas:
sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
La instalación y configuración de Django con Postgres Nginx y Gunicorn en Ubuntu 18.04 ha finalizado.