Despliegue de aplicaciones Django con uWSGI

Introducción

En los apartados anteriores desplegamos la aplicación Django usando apache2 con el módulo mod_wsgi, que ejecutaba la aplicación directamente dentro del servidor web. En esta práctica vamos a hacerlo de otra forma: usaremos un servidor de aplicaciones independiente, uWSGI, encargado de ejecutar Django, y un servidor web (apache2 o nginx) que actuará como proxy inverso.

Instalación de uWSGI

Para mantener las dependencias aisladas, uWSGI se instalará dentro del entorno virtual del proyecto.

source /home/debian/venv/django/bin/activate
pip install uwsgi

Comprobamos la instalación:

uwsgi --version

Configuración de uWSGI con modo HTTP

En lugar de exponer Django directamente a Internet, lo habitual es ejecutar uWSGI escuchando en un puerto interno (por ejemplo, 8080) y hacer que apache2 o nginx actúen como proxy inverso. El proxy recibe las peticiones HTTP en el puerto 80 o 443 y las reenvía localmente a uWSGI.

De esta forma:

  • uWSGI sigue siendo el servidor de aplicaciones que ejecuta Django.
  • apache o nginx se encargan de la gestión de clientes, archivos estáticos, HTTPS, etc.
  • El puerto 8080 no se expone al exterior, solo se usa para comunicación interna.

Archivo de configuración de uWSGI

Creamos el archivo /home/debian/guestbook_project/uwsgi.ini con el siguiente contenido:

[uwsgi]
http = 127.0.0.1:8080
chdir = /home/debian/guestbook_project
wsgi-file = guestbook_project/wsgi.py
processes = 4
threads = 2
master = true
  • http = 127.0.0.1:8080: uWSGI escucha conexiones HTTP solo en localhost, no accesibles desde fuera del servidor.
  • chdir: Directorio donde se encuentra el proyecto Django.
  • wsgi-file: Archivo wsgi.py del proyecto, punto de entrada de la aplicación.
  • processes: Número de procesos de trabajo concurrentes.
  • threads:Número de hilos por proceso.
  • master: Habilita el proceso maestro (gestiona los trabajadores).

Ejecución de prueba

Ejecutamos uWSGI con la configuración anterior:

uwsgi --ini /home/debian/guestbook_project/uwsgi.ini

uWSGI quedará escuchando localmente en el puerto 8080. Si queremos comprobar que está funcionando, podemos hacer una petición desde el propio servidor:

curl http://127.0.0.1:8080

Esto debería devolver el contenido de la página principal de la aplicación Django.

:::caution[Ejercicio]

  1. Realiza la implementación de la aplicación guestbook_django con uWSGI con modo HTTP.
  2. Haz una ejecución de prueba para comprobar que está funcionando.
  3. ¿Se ve la hoja de estilo? ¿Por qué? :::

Unidad de sistema (systemd)

Para que uWSGI se ejecute automáticamente y se integre con el sistema, creamos un servicio systemd.

Archivo: /etc/systemd/system/guestbook_uwsgi.service

[Unit]
Description=uWSGI service for Django Guestbook
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/home/debian/guestbook_project
Environment="PATH=/home/debian/venv/django/bin"
ExecStart=/home/debian/venv/django/bin/uwsgi --ini /home/debian/guestbook_project/uwsgi.ini

Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Activamos el servicio:

sudo systemctl daemon-reload
sudo systemctl enable guestbook_uwsgi
sudo systemctl start guestbook_uwsgi
sudo systemctl status guestbook_uwsgi

A partir de ahora, uWSGI se ejecutará automáticamente al arrancar el sistema y gestionará nuestra aplicación Django.

:::caution[Ejercicio]

  1. Configura la unidad de systemd para controlar el servicio uWSGI.
  2. Comprueba la salida de systemctl status guestbook_uwsgi para no obtener errores.
  3. Prueba acceder al puerto para comprobar que funciona la página. :::

Configuración del proxy inverso con apache2

En esta configuración, Apache actúa como proxy inverso HTTP: recibe las peticiones en el puerto 80 y las reenvía a 127.0.0.1:8080, donde uWSGI atiende las peticiones HTTP.

Instalamos y activamos los módulos necesarios:

sudo a2enmod proxy proxy_http

Creamos el archivo de configuración /etc/apache2/sites-available/guestbook_http.conf:

<VirtualHost *:80>
    ServerName guestbook.local
    ServerAdmin webmaster@localhost

    # Proxy inverso hacia uWSGI (modo HTTP)
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/

    # Archivos estáticos (CSS, JS, imágenes)
    Alias /static/ /home/debian/guestbook_project/static/
    <Directory /home/debian/guestbook_project/static>
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/guestbook_error.log
    CustomLog ${APACHE_LOG_DIR}/guestbook_access.log combined
</VirtualHost>

:::caution[Ejercicio]

  1. Configura un proxy inverso con apache2 para acceder a la aplicación con el nombre guestbook.tunombre.org. :::

Configuración del proxy inverso con nginx

nginx también puede actuar como proxy inverso en ambos casos: HTTP o socket. Solo cambia la directiva utilizada (proxy_pass o uwsgi_pass).

Creamos el archivo /etc/nginx/sites-available/guestbook_http:

server {
    listen 80;
    server_name guestbook.local;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /home/debian/guestbook_project/static/;
    }

    error_log /var/log/nginx/guestbook_error.log;
    access_log /var/log/nginx/guestbook_access.log;
}

:::caution[Ejercicio]

  1. Configura un proxy inverso con nginx para acceder a la aplicación con el nombre guestbook.tunombre.org. :::