Notas de Luis

¡Esta es una revisión vieja del documento!


Nivel superior

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.

computing/web/flask_app_2.1768382169.txt.gz · Última modificación: por alfabeto