Ésta va a ser rápida. Es solo un recordatorio personal de cómo configurar varias instancias de gunicorn en una máquina con systemd. De modo que si no sabes qué es unicorn o systemd es muy posible que no te vaya interesar nada de lo que vaya a contar.
Si aun sigues ahí a pesar de tu desconocimiento, te diré que systemd es un sistema de gestión de servicios y procesos para Linux, lo que significa que se encarga de iniciar, supervisar y detener servicios (programas que se ejecutan en segundo plano) durante el arranque y el funcionamiento de tu computadora. Piensa en systemd como el director de una orquesta que, al inicio de un concierto (cuando enciendes tu computadora), indica a cada músico (servicio) cuándo y cómo debe empezar a tocar su parte. Además, durante el concierto, se asegura de que todos sigan tocando correctamente y, si algún músico tiene problemas, puede ayudar a solucionarlo o decidir reemplazarlo. De esta manera, systemd ayuda a que tu sistema operativo Linux funcione de manera organizada y eficiente desde el momento en que lo enciendes hasta que lo apagas.
Por otro lado, gunicorn es como un amable portero que abre la puerta de un club exclusivo (tu aplicación web) para permitir que los visitantes (usuarios en internet) entren y disfruten. Se asegura de que todo el mundo pase de manera ordenada y eficiente, gestionando el flujo de visitantes hacia dentro y fuera de la aplicación. O sea un servidor HTTP.
Desde hace no mucho me ha dado por desarrollar aplicaciones con la plataforma Django, a la que aconsejan servir con gunicorn. Y desconocía si un solo servicio de gunicorn soportaba varias aplicaciones, o si cada una debía contar con el suyo propio.
Resulta que, como sospechaba, se recomienda que solo corra un servicio de gunicorn en una máquina. ¿Y entonces, cómo sirvo las diferentes aplicaciones a través de nginx? Para quién no sepa qué es nginx, es como un eficiente repartidor de correo que se encarga de dirigir el tráfico de internet hacia los sitios web correctos, asegurándose de que cada solicitud de usuario llegue al destino adecuado. Además, actúa como un guardia de seguridad, protegiendo a los sitios web de visitas no deseadas o perjudiciales.
No entro en el proceso de instalación de gunicorn y nginx, este no es el objetivo del artículo. Si no recuerdo mal usé apt para instalar ambas aplicaciones en mi Kubuntu.
La solución pasa por la creación de un «target» u objetivo, que se utilizará para tratar ambas instancias de las aplicaciones como un único servicio.
Pongamos que tus aplicaciones se encuentran en /home/marisol/app/. Y cuentas con una llamada foo y otra bar. Por tanto una está en /home/marisol/app/foo y la otra en /home/marisol/app/bar
Lo primero que tenemos que hacer es crear una fichero, gunicorn.target en /etc/systemd/system/gunicorn.target:
1 2 3 4 5 6 |
[Unit] Description=Gunicorn Documentation=https://example.com/path/to/your/docs [Install] WantedBy=multi-user.target |
Ya está, ya has creado un «objetivo» que, cuando esté «habilitado» ( sudo systemctl enable gunicorn.target), se iniciará en el arranque. Ahora vamos con los /etc/systemd/system/[email protected], el archivo de plantilla:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[Unit] Description=gunicorn daemon After=network.target PartOf=gunicorn.target ReloadPropagatedFrom=gunicorn.target [Service] User=marisol Group=www-data WorkingDirectory=/home/marisol/app/%i ExecStart=/home/marisol/.local/bin/gunicorn --access-logfile - --workers 3 --reload --bind unix:/home/marisol/app/%i/gunicorn.sock %i.wsgi:application [Install] WantedBy=gunicorn.target |
%i es el código del elemento de entrada (placeholder en inglés), que captará el texto a continuación de la arroba en el nombre del servicio. Por tanto estos serían los comandos para habilitar los servicios de las aplicaciones foo y bar.
1 2 |
systemctl enable gunicorn@foo systemctl disable gunicorn@bar |
Para iniciar o detener todas las instancias de gunicorn a la vez, simplemente ejecutaremos:
1 2 |
systemctl start gunicorn.target systemctl stop gunicorn.target |
También podemos detener e iniciar un servicio específico por sí solo:
1 2 3 |
systemctl start gunicorn@foo systemctl stop gunicorn@foo systemctl restart gunicorn@foo |
Por último éste es un ejemplo de configuración de nginx usando uno de esos servicios con Django en el backend y react en el front:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
server { listen 80; server_name foo.local; root /home/marisol/app/foo/front/build; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { alias /home/marisol/app/foo/front/build/static/; } location /assets/ { alias /home/marisol/app/foo/api/static/; } location /api/ { include proxy_params; proxy_pass http://unix:/home/marisol/app/foo/gunicorn.sock; } location / { try_files $uri $uri/ /index.html; } } |
Fácil, ¿no?