Cómo servir aplicaciones Flask con Gunicorn y Nginx en Ubuntu 22.04

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: Instalación de los componentes desde los repositorios de Ubuntu
  • Paso 2: creación de un entorno virtual de Python
  • Paso 3: Configuración de una aplicación Flask
    1. Creación de una aplicación de muestra
    2. Creación del punto de entrada WSGI
  • Paso 4: Configuración de Gunicorn
  • Paso 5: Configuración de Nginx para procesar solicitudes
  • Paso 6: Proteger la aplicación
  • Conclusión
  • Kathleen Juell escribió una versión anterior de este tutorial .

    Introducción

    En esta guía, creará una aplicación Python utilizando el microframework Flask en Ubuntu 22.04. La mayor parte de este tutorial tratará sobre cómo configurar el servidor de aplicaciones Gunicorn y cómo iniciar la aplicación y configurar Nginx para que actúe como un proxy inverso de interfaz.

    Prerrequisitos

    Antes de comenzar esta guía, debes tener:

    • Un servidor con Ubuntu 22.04 instalado y un usuario no root con privilegios sudo. Siga nuestra guía de configuración inicial del servidor para obtener orientación.

    • Nginx instalado, siguiendo los pasos 1 y 2 de Cómo instalar Nginx en Ubuntu 22.04 .

    • Un nombre de dominio configurado para apuntar a su servidor. Puede comprar uno en Namecheap u obtener uno gratis en Freenom . Puede aprender a apuntar dominios a DigitalOcean siguiendo la documentación relevante sobre dominios y DNS . Asegúrese de crear los siguientes registros DNS:

      • Un registro A que your_domainapunta a la dirección IP pública de su servidor.
      • Un registro A que apunta a la dirección IP pública de su servidor.www.your_domain
    • Familiaridad con la especificación WSGI, que el servidor Gunicorn utilizará para comunicarse con su aplicación Flask. Esta discusión cubre WSGI con más detalle.

    Paso 1: Instalación de los componentes desde los repositorios de Ubuntu

    El primer paso será instalar todos los componentes necesarios de los repositorios de Ubuntu. Esto incluye pipel administrador de paquetes de Python, que administrará los componentes de Python. También obtendrá los archivos de desarrollo de Python necesarios para compilar algunos de los componentes de Gunicorn.

    En primer lugar, actualice el índice de paquetes locales e instale los paquetes que le permitirán crear su entorno Python. Estos incluirán python3-pip, junto con algunos paquetes más y herramientas de desarrollo necesarias para un entorno de programación sólido:

    1. sudo apt update
    2. sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

    Con estos paquetes en su lugar, el siguiente paso es crear un entorno virtual para su proyecto.

    Paso 2: creación de un entorno virtual de Python

    A continuación, configurará un entorno virtual para aislar la aplicación Flask de los demás archivos Python en su sistema.

    Comience instalando el python3-venvpaquete, que instalará el venvmódulo:

    1. sudo apt install python3-venv

    cdA continuación, crea un directorio principal para tu proyecto Flask. Después de crearlo, ingresa al directorio con el comando:

    1. mkdir ~/myproject
    2. cd ~/myproject

    Cree un entorno virtual para almacenar los requisitos de Python de su proyecto Flask escribiendo:

    1. python3 -m venv myprojectenv

    Esto instalará una copia local de Python pipen un directorio llamado myprojectenvdentro del directorio de su proyecto.

    Antes de instalar aplicaciones dentro del entorno virtual, es necesario activarlo. Para ello, escriba:

    1. source myprojectenv/bin/activate

    El mensaje cambiará para indicar que ahora está trabajando en el entorno virtual. Se verá así: .(myprojectenv)user@host:~/myproject$

    Paso 3: Configuración de una aplicación Flask

    Ahora que estás en tu entorno virtual, puedes instalar Flask y Gunicorn y comenzar a diseñar tu aplicación.

    Primero, instale wheelcon la instancia local de pippara asegurarse de que sus paquetes se instalarán incluso si faltan archivos wheel:

    1. pip install wheel

    Nota

    Independientemente de la versión de Python que estés usando, cuando se activa el entorno virtual, debes usar el pipcomando (no pip3).

    A continuación, instale Flask y Gunicorn:

    1. pip install gunicorn flask

    Creación de una aplicación de muestra

    Ahora que tienes Flask disponible, puedes crear una aplicación sencilla. Flask es un microframework. No incluye muchas de las herramientas que sí incluyen los frameworks con más funciones y existe principalmente como un módulo que puedes importar a tus proyectos para ayudarte a inicializar una aplicación web.

    Si bien su aplicación puede ser más compleja, crearemos nuestra aplicación Flask en un solo archivo, llamado myproject.py:

    1. nano ~/myproject/myproject.py

    El código de la aplicación se almacenará en este archivo. Importará Flask y creará una instancia de un objeto Flask. Puede usarlo para definir las funciones que se deben ejecutar cuando se solicita una ruta específica:

    ~/miproyecto/miproyecto.py

    from flask import Flaskapp = Flask(__name__)@app.route("/")def hello():    return "h1 style='color:blue'Hello There!/h1"if __name__ == "__main__":    app.run(host='0.0.0.0')

    Básicamente, esto define qué contenido se debe presentar cuando se accede al dominio raíz. Guarde y cierre el archivo cuando haya terminado.

    Si siguió la guía de configuración inicial del servidor, debería tener habilitado un firewall UFW. Para probar la aplicación, debe permitir el acceso al puerto 5000:

    1. sudo ufw allow 5000

    Ahora puedes probar tu aplicación Flask escribiendo:

    1. python myproject.py

    Verá un resultado como el siguiente, incluida una advertencia útil que le recordará que no debe utilizar esta configuración de servidor en producción:

    Output* Serving Flask app "myproject" (lazy loading) * Environment: production   WARNING: Do not use the development server in a production environment.   Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

    Visita la dirección IP de tu servidor seguida de :5000en tu navegador web:

    http://your_server_ip:5000

    Deberías ver algo como esto:

    Cuando haya terminado, presione CTRL-Cen su ventana de terminal para detener el servidor de desarrollo Flask.

    Creación del punto de entrada WSGI

    A continuación, crea un archivo que servirá como punto de entrada para tu aplicación. Esto le indicará al servidor Gunicorn cómo interactuar con la aplicación.

    Llamar al archivo wsgi.py:

    1. nano ~/myproject/wsgi.py

    En este archivo, importe la instancia de Flask desde nuestra aplicación y luego ejecútela:

    ~/miproyecto/wsgi.py

    from myproject import appif __name__ == "__main__":    app.run()

    Guarde y cierre el archivo cuando haya terminado.

    Paso 4: Configuración de Gunicorn

    Ahora tu aplicación está escrita con un punto de entrada establecido. Ahora puedes continuar con la configuración de Gunicorn.

    Antes de continuar, verifique que Gunicorn pueda servir la aplicación correctamente.

    Puede hacerlo pasándole el nombre del punto de entrada de la aplicación. Esto se construye como el nombre del módulo (menos la .pyextensión), más el nombre del elemento invocable dentro de la aplicación. En este caso, es wsgi:app.

    Especifique también la interfaz y el puerto a enlazar mediante el 0.0.0.0:5000argumento para que la aplicación se inicie en una interfaz disponible públicamente:

    1. cd ~/myproject
    2. gunicorn --bind 0.0.0.0:5000 wsgi:app

    Debería ver un resultado como el siguiente:

    Output[2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4[2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419)[2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync[2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

    Visita :5000nuevamente la dirección IP de tu servidor adjunta al final en tu navegador web:

    http://your_server_ip:5000

    Deberías ver el resultado de tu aplicación:

    Cuando hayas confirmado que funciona correctamente, presiona CTRL-Cen tu ventana de terminal.

    Cuando haya terminado de utilizar el entorno virtual, puede desactivarlo:

    1. deactivate

    Cualquier comando Python ahora utilizará nuevamente el entorno Python del sistema.

    A continuación, cree el archivo de unidad de servicio systemd. La creación de un archivo de unidad systemd permitirá que el sistema de inicio de Ubuntu inicie automáticamente Gunicorn y sirva la aplicación Flask cada vez que se inicie el servidor.

    Cree un archivo de unidad que termine .servicedentro del /etc/systemd/systemdirectorio para comenzar:

    1. sudo nano /etc/systemd/system/myproject.service

    En el interior, comenzará con la [Unit]sección que se utiliza para especificar metadatos y dependencias. Agregue una descripción de su servicio aquí e indique al sistema de inicio que lo inicie solo después de que se haya alcanzado el objetivo de red:

    /etc/systemd/system/miproyecto.servicio

    [Unit]Description=Gunicorn instance to serve myprojectAfter=network.target

    A continuación, agregue una [Service]sección. Esto especificará el usuario y el grupo bajo los cuales desea que se ejecute el proceso. Otorgue a su cuenta de usuario habitual la propiedad del proceso, ya que posee todos los archivos relevantes. Otorgue también la propiedad del grupo al www-datagrupo para que Nginx pueda comunicarse fácilmente con los procesos de Gunicorn. Recuerde reemplazar el nombre de usuario aquí con su nombre de usuario:

    /etc/systemd/system/miproyecto.servicio

    [Unit]Description=Gunicorn instance to serve myprojectAfter=network.target[Service]User=sammyGroup=www-data

    A continuación, mapee el directorio de trabajo y configure la PATHvariable de entorno para que el sistema de inicio sepa que los ejecutables del proceso se encuentran dentro de nuestro entorno virtual. También especifique el comando para iniciar el servicio. Este comando hará lo siguiente:

    • Iniciar 3 procesos de trabajo (aunque debe ajustar esto según sea necesario)
    • Crea y vincula un archivo de socket de Unix, myproject.sock, dentro de nuestro directorio de proyecto. Estableceremos un valor de umask de 007modo que se cree el archivo de socket y se otorgue acceso al propietario y al grupo, mientras se restringe el acceso a otros.
    • Especifique el nombre del archivo del punto de entrada WSGI, junto con el objeto invocable de Python dentro de ese archivo ( wsgi:app)

    Systemd requiere que proporciones la ruta completa al ejecutable Gunicorn, que está instalado dentro de tu entorno virtual.

    Recuerde reemplazar el nombre de usuario y las rutas del proyecto con su propia información:

    /etc/systemd/system/miproyecto.servicio

    [Unit]Description=Gunicorn instance to serve myprojectAfter=network.target[Service]User=sammyGroup=www-dataWorkingDirectory=/home/sammy/myprojectEnvironment="PATH=/home/sammy/myproject/myprojectenv/bin"ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

    Por último, agregue una [Install]sección. Esto le indicará a systemd a qué vincular este servicio si lo habilita para que se inicie en el arranque. Querrá que este servicio se inicie cuando el sistema multiusuario normal esté en funcionamiento:

    /etc/systemd/system/miproyecto.servicio

    [Unit]Description=Gunicorn instance to serve myprojectAfter=network.target[Service]User=sammyGroup=www-dataWorkingDirectory=/home/sammy/myprojectEnvironment="PATH=/home/sammy/myproject/myprojectenv/bin"ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app[Install]WantedBy=multi-user.target

    Con esto, el archivo de servicio systemd está completo. Guárdelo y ciérrelo ahora.

    Ahora puedes iniciar el servicio Gunicorn que creaste y habilitarlo para que se inicie en el arranque:

    1. sudo systemctl start myproject
    2. sudo systemctl enable myproject

    Comprobemos el estado:

    1. sudo systemctl status myproject

    Deberías ver un resultado como este:

    Output● myproject.service - Gunicorn instance to serve myproject     Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled)     Active: active (running) since Tue 2022-05-10 19:40:41 UTC; 9s ago   Main PID: 17300 (gunicorn)      Tasks: 4 (limit: 2327)     Memory: 56.0M        CPU: 514ms     CGroup: /system.slice/myproject.service             ├─17300 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app             ├─17301 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app             ├─17302 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app             └─17303 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:appMay 10 19:40:41 r systemd[1]: Started Gunicorn instance to serve myproject.. . .

    Si ve algún error, asegúrese de resolverlo antes de continuar con el tutorial.

    Paso 5: Configuración de Nginx para procesar solicitudes

    Ahora, el servidor de aplicaciones Gunicorn debería estar en funcionamiento y esperando solicitudes en el archivo de socket del directorio del proyecto. Ahora, puede configurar Nginx para que pase solicitudes web a ese socket haciendo algunas pequeñas modificaciones en su archivo de configuración.

    Comience por crear un nuevo archivo de configuración de bloque de servidor en sites-availableel directorio de Nginx. Llámelo myprojectpara seguir el resto de la guía:

    1. sudo nano /etc/nginx/sites-available/myproject

    Abra un bloque de servidor y dígale a Nginx que escuche en el puerto predeterminado 80. Indíquele también que use este bloque para las solicitudes del nombre de dominio de nuestro servidor:

    /etc/nginx/sites-available/miproyecto

    server {    listen 80;    server_name your_domain www.your_domain;}

    A continuación, agregue un bloque de ubicación que coincida con cada solicitud. Dentro de este bloque, incluirá el proxy_paramsarchivo que especifica algunos parámetros de proxy generales que deben configurarse. Luego, pasará las solicitudes al socket que definió mediante la proxy_passdirectiva:

    /etc/nginx/sites-available/miproyecto

    server {    listen 80;    server_name your_domain www.your_domain;    location / {        include proxy_params;        proxy_pass http://unix:/home/sammy/myproject/myproject.sock;    }}

    Guarde y cierre el archivo cuando haya terminado.

    Para habilitar la configuración del bloque del servidor Nginx que acaba de crear, vincule el archivo al sites-enableddirectorio:

    1. sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

    Con el archivo en ese directorio, puedes comprobar si hay errores de sintaxis:

    1. sudo nginx -t

    Si esto regresa sin indicar ningún problema, reinicie el proceso Nginx para leer la nueva configuración:

    1. sudo systemctl restart nginx

    Por último, vuelve a ajustar el firewall. Ya no necesitas acceso a través del puerto 5000, por lo que puedes eliminar esa regla. Luego puedes permitir el acceso total al servidor Nginx:

    1. sudo ufw delete allow 5000
    2. sudo ufw allow 'Nginx Full'

    Ahora debería poder navegar al nombre de dominio de su servidor en su navegador web:

    http://your_domain

    Deberías ver el resultado de tu aplicación:

    Nota : Recibirá un error de puerta de enlace HTTP 502 si Nginx no puede acceder al archivo de socket de Gunicorn. Por lo general, esto se debe a que el directorio de inicio del usuario no permite que otros usuarios accedan a los archivos que contiene.

    Si el archivo de socket se llama /home/sammy/myproject/myproject.sock, asegúrese de que /home/sammytenga un mínimo de 0755permisos. Puede utilizar una herramienta como chmodpara cambiar los permisos de esta manera:

    1. sudo chmod 755 /home/sammy

    Luego vuelva a cargar la página para ver si el error HTTP 502 desaparece.

    Si encuentra algún error, intente comprobar lo siguiente:

    • sudo less /var/log/nginx/error.log:comprueba los registros de errores de Nginx.
    • sudo less /var/log/nginx/access.log:comprueba los registros de acceso de Nginx.
    • sudo journalctl -u nginx:comprueba los registros del proceso Nginx.
    • sudo journalctl -u myproject:comprueba los registros Gunicorn de tu aplicación Flask.

    Paso 6: Proteger la aplicación

    Para garantizar que el tráfico a su servidor permanezca seguro, obtengamos un certificado SSL para su dominio. Hay varias formas de hacerlo, incluida la obtención de un certificado gratuito de Let’s Encrypt , la generación de un certificado autofirmado o la compra de uno de otro proveedor y la configuración de Nginx para usarlo siguiendo los pasos 2 a 6 de Cómo crear un certificado SSL autofirmado para Nginx en Ubuntu 22.04 . Usaremos la opción uno (Let’s Encrypt) por conveniencia.

    Instale el paquete Nginx de Certbot con apt:

    1. sudo apt install python3-certbot-nginx

    Certbot ofrece una variedad de formas de obtener certificados SSL a través de complementos. El complemento Nginx se encargará de reconfigurar Nginx y recargar la configuración cuando sea necesario. Para usar este complemento, escriba lo siguiente:

    1. sudo certbot --nginx -d your_domain -d www.your_domain

    Esto se ejecuta certbotcon el --nginxcomplemento, que se utiliza -dpara especificar los nombres para los cuales queremos que sea válido el certificado.

    Si es la primera vez que ejecuta certbot, se le solicitará que ingrese una dirección de correo electrónico y que acepte los términos del servicio. Después de hacerlo, certbotse comunicará con el servidor Let’s Encrypt y luego ejecutará un desafío para verificar que controla el dominio para el que está solicitando un certificado.

    Si esto tiene éxito, certbotle preguntará cómo desea configurar sus ajustes HTTPS:

    OutputPlease choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.-------------------------------------------------------------------------------1: No redirect - Make no further changes to the webserver configuration.2: Redirect - Make all requests redirect to secure HTTPS access. Choose this fornew sites, or if you're confident your site works on HTTPS. You can undo thischange by editing your web server's configuration.-------------------------------------------------------------------------------Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

    Seleccione su opción y luego presione ENTER. La configuración se actualizará y Nginx se recargará para recoger la nueva configuración. certbotfinalizará con un mensaje que le indicará que el proceso fue exitoso y dónde se almacenan sus certificados:

    OutputIMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at:   /etc/letsencrypt/live/your_domain/fullchain.pem   Your key file has been saved at:   /etc/letsencrypt/live/your_domain/privkey.pem   Your cert will expire on 2020-08-18. To obtain a new or tweaked   version of this certificate in the future, simply run certbot again   with the "certonly" option. To non-interactively renew *all* of   your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot   configuration directory at /etc/letsencrypt. You should make a   secure backup of this folder now. This configuration directory will   also contain certificates and private keys obtained by Certbot so   making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by:   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate   Donating to EFF:                    https://eff.org/donate-le

    Si siguió las instrucciones de instalación de Nginx en los requisitos previos, ya no necesitará la asignación de perfil HTTP redundante:

    1. sudo ufw delete allow 'Nginx HTTP'

    Para verificar la configuración, navegue nuevamente a su dominio, utilizando https://:

    https://your_domain

    Debería ver nuevamente el resultado de su aplicación, junto con el indicador de seguridad de su navegador, que debería indicar que el sitio está protegido.

    Conclusión

    En esta guía, creó y protegió una aplicación Flask simple dentro de un entorno virtual Python. Creó un punto de entrada WSGI para que cualquier servidor de aplicaciones compatible con WSGI pueda interactuar con él y, luego, configuró el servidor de aplicaciones Gunicorn para proporcionar esta función. Después, creó un archivo de servicio systemd para iniciar automáticamente el servidor de aplicaciones al arrancar. También creó un bloque de servidor Nginx que pasa el tráfico del cliente web al servidor de aplicaciones, retransmite solicitudes externas y protege el tráfico a su servidor con Let’s Encrypt.

    Flask es un marco de trabajo muy simple pero extremadamente flexible, diseñado para brindarle funcionalidad a sus aplicaciones sin ser demasiado restrictivo en cuanto a estructura y diseño. Puede usar la pila general descrita en esta guía para brindar servicio a las aplicaciones Flask que diseñe.

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion