¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Flask - 2 - Producción
Introduction
Tutorial de Desarrollo de una Aplicación con Flask y Gestión con systemd
Referencias: Flask mega tutorial
Preparación del Entorno de Producción en Linux Ubuntu
Instalación de Dependencias
En tu máquina de producción con Linux Ubuntu, instala las dependencias necesarias:
sudo apt update sudo apt install python3-pip nginx pipenv sudo systemctl enable nginx
Creamos directorio de producción.
mkdir /var/www/my_flask_app sudo chown -R www-data:www-data /var/www/my_flask_app sudo chmod -R 755 /var/www/my_flask_app
Debemos copiar todos los ficheros necesarios a nuevo entorno de producción.
Configuración de Nginx
Configura Nginx para servir la aplicación Flask. Crea un nuevo archivo de
configuración en /etc/nginx/sites-available/myflaskapp:
server { listen 80; server_name your_domain; access_log /var/log/nginx/my_flask_app.access.log; error_log /var/log/nginx/my_flask_app.error.log; location / { proxy_pass http://unix:/var/www/my_flask_app/my_flask_app.sock; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
- server_name is where the domain name goes. That is what you will use to access the web application.
- access_log and error_logs specify the path to the access and error logs.
- location block is where Nginx reverses proxy back to the Flask application.
Enable the website by creating a link to the sites-enabled directory. Reinicia Nginx:
sudo ln -s /etc/nginx/sites-available/my_flask_app /etc/nginx/sites-enabled sudo nginx -t sudo systemctl restart nginx sudo systemctl status nginx
Instalación de Gunicorn
Instala Gunicorn en el entorno virtual de producción. Se debe ejecutar export
PIPENVVENVIN_PROJECT=1 antes de hacer el pipenv install en el servidor, o el
servicio de systemd fallará al no encontrar la ruta de Gunicorn.
pipenv install gunicorn
While you are in the virtual environment check the path of gunicorn. Take note
of this path. You will need to know the path to gunicorn to configure the
systemd service file. My path is /var/www/myflaskapp/.venv/bin/gunicorn.
$ which gunicorn
/var/www/my_flask_app/.venv/bin/gunicorn
Testing with gunicorn
If you were able to run the Flask development server successfully use this command to test run the application using Gunicorn.
gunicorn --workers 4 --bind 0.0.0.0:5000 wsgi:app
* –workers N: Set the –workers to two times the number of cores in your server. Adjust the number later if you have any issues. Do not exceed 12. * –bind 0.0.0.0:5000: This will listen on all server networking interfaces on port 5000. * wsgi:app: wsgi is the file name without the .py extension. app is the instance of the Flask application within the file. You should see the similar output below.
$ gunicorn --workers 4 --bind 0.0.0.0:5000 wsgi:app
[2024-02-20 20:57:21 -0500] [4936] [INFO] Starting gunicorn 21.2.0 [2024-02-20 20:57:21 -0500] [4936] [INFO] Listening at: http://0.0.0.0:5000 (4936) [2024-02-20 20:57:21 -0500] [4936] [INFO] Using worker: sync [2024-02-20 20:57:21 -0500] [4937] [INFO] Booting worker with pid: 4937 [...]
Hacemos la comprobación:
curl -O - localhost:5000
Debemos obtener la salida de la página inicial de la aplicación.
Press CTRL+C to stop the Gunicorn server.
While you are in the virtual environment check the path of gunicorn. Take note of this path. You will need to know the path to gunicorn to configure the systemd service file. My path is /var/www/myflaskapp/.venv/bin/gunicorn.
The path depends if you have PIPENV\VENV\IN\_PROJECT=true set in your .bashrc file or not. If the variable is set to true pipenv will use the .venv in your project directory.
Creación del Servicio systemd
Crea un archivo de servicio systemd para gestionar la aplicación. Crea un
archivo /etc/systemd/system/myflaskapp.service con el siguiente contenido:
[Unit] Description=Gunicorn instance to serve my_flask_app After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/my_flask_app Environment="PATH=/var/www/my_flask_app/.venv/bin" Environment="FLASK_ENV=production" Environment="FLASK_APP=wsgi.py" ExecStart=/var/www/my_flask_app/.venv/bin/gunicorn --workers 3 --bind unix:/var/www/my_flask_app/my_flask_app.sock -m 007 wsgi:app [Install] WantedBy=multi-user.target
* User: Sets the user who has permission to the project directory. * Group: Sets the group who has permission to the project directory. * Environment: Sets the path to the bin directory inside the virtual environment. * WorkingDirectory: Sets the base directory where the code for the project is. * ExecStart: Sets the path to the gunicorn executable inside the virtual environment along with the gunicorn command line options.
Habilitar y Iniciar el Servicio
Habilita y inicia el servicio con los siguientes comandos:
sudo systemctl enable my_flask_app sudo systemctl start my_flask_app
/etc/hosts provisional
The Flask application is no longer accessible via the IP address since it is now being served by Gunicorn and Nginx. To access the Flask application you would need to use the name you set in the Nginx server block for the directive server_name in the Nginx configuration. To access the web page can edit the host file on your desktop/laptop to point the domain to the IP address of your server.
Edit the host file to add point the domain name to the server. Since my server's IP address is 192.168.12.34 I would add this line to the host file.
192.168.12.34 my_flask_app
Host file location for Linux: /etc/hosts
Now I can access the Flask application with a browser via the name.
http://my//flask//app.
You should see Hello World again.
Ahora la aplicación está probada y es posible modificar el DNS para que apunte a
la dirección pública del servidor, volviendo a dejar el fichero /etc/hosts
como estaba.
Alternativa Recomendada: Gestión Profesional de Permisos (User + Group)
En lugar de ceder toda la propiedad a www-data, utilizaremos un esquema de
permisos compartidos. Esto permite que tu usuario edite archivos y ejecute
pipenv sin usar sudo, mientras que www-data mantiene el acceso
necesario para servir la aplicación.
Configuración de Grupos
Añade tu usuario personal al grupo de Nginx para que ambos compartan privilegios:
# Añadir el usuario actual al grupo www-data sudo usermod -aG www-data $USER
Nota: Se debe cerrar sesión y volver a entrar (o reiniciar el servidor) para que este cambio se aplique.
Asignación de Propiedad y Bit de Grupo
Configuramos tu usuario como propietario y www-data como grupo responsable.
Aplicaremos el setgid bit, que garantiza que cualquier archivo nuevo creado
herede automáticamente el grupo www-data.
# Cambiar propietario al usuario actual y grupo a www-data sudo chown -R $USER:www-data /var/www/my_flask_app # Dar permisos de lectura/escritura/ejecución a dueño y grupo (775) sudo find /var/www/my_flask_app -type d -exec chmod 775 {} + sudo find /var/www/my_flask_app -type f -exec chmod 664 {} + # Aplicar el bit de grupo persistente (setgid) sudo chmod g+s /var/www/my_flask_app
Ajuste del Socket en Gunicorn
Para que Nginx pueda comunicarse con el socket creado por Gunicorn sin errores
de “Permission Denied”, es fundamental añadir la máscara de permisos -m 007 en
la configuración del servicio.
Modifica tu archivo /etc/systemd/system/myflaskapp.service:
[Service] ... # El flag -m 007 asegura que el socket (.sock) sea creado con permisos rwxrwx--- ExecStart=/var/www/my_flask_app/.venv/bin/gunicorn --workers 3 --bind unix:/var/www/my_flask_app/my_flask_app.sock -m 007 wsgi:app ...
Ventajas de este método
* Tu Usuario: Puedes usar git pull, pipenv install y editar código sin sudo.
* Nginx / www-data: Grupo (rwx).r Puede leer archivos estáticos y escribir en el socket o logs.
* Seguridad: Los usuarios que no pertenecen al grupo www-data no tienen acceso.
Verificación de permisos
Para confirmar que la configuración es correcta, ejecuta:
ls -la /var/www/my_flask_app
La salida debería mostrar los permisos como drwxrwxr-x y los dueños como
tu_usuario www-data.