Cómo servir aplicaciones Flask con uWSGI y Nginx en Ubuntu 18.04

Introducción

Í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 uWSGI
    1. Prueba del servicio uWSGI
    2. Creación de un archivo de configuración uWSGI
  • Paso 5: Creación de un archivo de unidad systemd
  • Paso 6: Configuración de Nginx para procesar solicitudes
  • Paso 7: Proteger la aplicación
  • Conclusión
  • En esta guía, creará una aplicación Python utilizando el microframework Flask en Ubuntu 18.04. La mayor parte de este artículo tratará sobre cómo configurar el servidor de aplicaciones uWSGI y cómo iniciar la aplicación y configurar Nginx para que actúe como un proxy inverso de interfaz.

    Prerrequisitos

    Para completar este tutorial, necesitarás:

    • Un servidor con Ubuntu 18.04 instalado y un usuario no root con privilegios sudo y un firewall habilitado. 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 18.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 uWSGI, nuestro servidor de aplicaciones y la especificación WSGI. Este análisis de definiciones y conceptos analiza ambos conceptos en detalle.

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

    El primer paso es instalar todos los componentes que necesitas de los repositorios de Ubuntu. Instalarás pip, el administrador de paquetes de Python, para administrar tus componentes de Python. También obtendrás los archivos de desarrollo de Python necesarios para compilar uWSGI.

    Primero, actualice el índice del paquete local:

    1. sudo apt update

    A continuación, 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 install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

    Con estos paquetes en su lugar, puede pasar a crear un entorno virtual para su proyecto.

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

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

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

    1. sudo apt install python3-venv

    A continuación, crea un directorio principal para tu proyecto Flask:

    1. mkdir ~/myproject

    Luego muévete al directorio después de crearlo:

    1. cd ~/myproject

    Cree un entorno virtual para almacenar los requisitos de Python de su proyecto Flask ejecutando lo siguiente:

    1. python3.6 -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:

    1. source myprojectenv/bin/activate

    El mensaje cambiará para indicar que ahora está trabajando en el entorno virtual. Se leerá de la siguiente manera: .(myprojectenv) user@host:~/myproject$

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

    Ahora que está en su entorno virtual, puede instalar Flask y uWSGI y comenzar a diseñar su 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é utilizando, cuando se activa el entorno virtual, debe utilizar el pipcomando (no pip3).

    A continuación, instale Flask y uWSGI:

    1. pip install uwsgi flask

    Una vez completada la instalación, puedes comenzar a utilizar Flask.

    Creación de una aplicación de muestra

    Ahora que tienes Flask disponible, puedes crear una aplicación sencilla. Como recordarás, Flask es un microframework y no incluye muchas de las herramientas que sí incluyen los frameworks con más funciones. Flask 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, creará su aplicación Flask en un solo archivo. Puede crear el archivo con su editor de texto favorito. Para este ejemplo, lo usaremos nanoy le daremos el nombre siguiente 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')

    Esto define qué contenido se debe presentar cuando se accede al dominio raíz. Guarde y cierre el archivo cuando haya terminado. Si está utilizando, nanopuede hacerlo presionando CTRL + Xthen Yy ENTER.

    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 prueba tu aplicación Flask:

    1. python myproject.py

    Recibirá 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 lo siguiente:

    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, creará un archivo que servirá como punto de entrada para su aplicación. Esto le indicará al servidor uWSGI cómo interactuar con él.

    Primero crea y nombra el archivo wsgi.py:

    1. nano ~/myproject/wsgi.py

    En este archivo, importe la instancia de Flask desde su 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 uWSGI

    Ahora su aplicación está escrita con un punto de entrada establecido. Ahora puede continuar con la configuración de uWSGI.

    Prueba del servicio uWSGI

    Antes de realizar más cambios, puede ser útil probar que uWSGI puede servir a su aplicación.

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

    También deberá especificar el socket, de modo que se inicie en una interfaz disponible públicamente, así como el protocolo, de modo que utilice HTTP en lugar del uwsgiprotocolo binario. Utilice el mismo número de puerto, 5000, que abrió anteriormente:

    1. uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

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

    http://your_server_ip:5000

    Debería recibir nuevamente el resultado de su aplicación:

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

    Ahora que has terminado con tu entorno virtual, puedes desactivarlo:

    1. deactivate

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

    Creación de un archivo de configuración uWSGI

    Ha probado y verificado que uWSGI puede servir a su aplicación, pero en última instancia querrá algo más robusto para un uso a largo plazo. Puede crear un archivo de configuración de uWSGI con las opciones pertinentes para esto.

    Coloque ese archivo en el directorio de su proyecto y llámelo myproject.ini:

    1. nano ~/myproject/myproject.ini

    En el interior, comenzará con el [uwsgi]encabezado para que uWSGI sepa que debe aplicar la configuración. Especificará dos cosas: el módulo en sí, haciendo referencia al wsgi.pyarchivo sin la extensión, y el elemento invocable dentro del archivo app:

    ~/miproyecto/miproyecto.ini

    [uwsgi]module = wsgi:app

    A continuación, indique a uWSGI que se inicie en modo maestro y genere cinco procesos de trabajo para atender las solicitudes reales:

    ~/miproyecto/miproyecto.ini

    [uwsgi]module = wsgi:appmaster = trueprocesses = 5

    Cuando estabas haciendo pruebas, expusiste uWSGI en un puerto de red. Sin embargo, vas a usar Nginx para manejar las conexiones de clientes reales, que luego pasarán las solicitudes a uWSGI. Dado que estos componentes están funcionando en la misma computadora, es preferible un socket Unix porque es más rápido y más seguro. Llama al socket myproject.socky colócalo en este directorio.

    Cambie también los permisos del socket. Esto le otorga al grupo Nginx la propiedad del proceso uWSGI más adelante, así que asegúrese de que el propietario del grupo del socket pueda leer información de él y escribir en él. Además, limpie el socket cuando el proceso se detenga agregando la vacuumopción:

    ~/miproyecto/miproyecto.ini

    [uwsgi]module = wsgi:appmaster = trueprocesses = 5socket = myproject.sockchmod-socket = 660vacuum = true

    Lo último que harás es configurar la die-on-termopción. Esto puede ayudar a garantizar que el sistema de inicio y uWSGI tengan las mismas suposiciones sobre lo que significa cada señal de proceso. Al configurar esto, se alinean los dos componentes del sistema e implementan el comportamiento esperado:

    ~/miproyecto/miproyecto.ini

    [uwsgi]module = wsgi:appmaster = trueprocesses = 5socket = myproject.sockchmod-socket = 660vacuum = truedie-on-term = true

    Es posible que hayas notado que no especificaste un protocolo como lo hiciste desde la línea de comandos. Esto se debe a que, de manera predeterminada, uWSGI habla usando el uwsgiprotocolo , un protocolo binario rápido diseñado para comunicarse con otros servidores. Nginx puede hablar este protocolo de forma nativa, por lo que es mejor usarlo que forzar la comunicación por HTTP.

    Cuando haya terminado, guarde y cierre el archivo.

    Paso 5: Creación de un archivo de unidad systemd

    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 uWSGI y proporcione 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

    Dentro del archivo, comience con la [Unit]sección, que se utiliza para especificar metadatos y dependencias. Describa aquí su servicio e indique al sistema de inicio que solo se inicie después de que se haya alcanzado el objetivo de red:

    /etc/systemd/system/miproyecto.servicio

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

    A continuación, abra la [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 uWSGI. Recuerde reemplazar el nombre de usuario aquí con su nombre de usuario:

    /etc/systemd/system/miproyecto.servicio

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

    A continuación, trace 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 su entorno virtual. También especifique el comando para iniciar el servicio. Systemd requiere que proporcione la ruta completa al ejecutable uWSGI, que está instalado dentro de su entorno virtual. Pasará el nombre del .iniarchivo de configuración que creó en el directorio de su proyecto.

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

    /etc/systemd/system/miproyecto.servicio

    [Unit]Description=uWSGI 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/uwsgi --ini myproject.ini

    Luego, 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. Desea que este servicio se inicie cuando el sistema multiusuario normal esté en funcionamiento:

    /etc/systemd/system/miproyecto.servicio

    [Unit]Description=uWSGI 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/uwsgi --ini myproject.ini[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 uWSGI que creaste y habilitarlo para que se inicie en el arranque:

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

    Comprobar el estado:

    1. sudo systemctl status myproject

    Debería recibir un resultado como el siguiente:

    Output● myproject.service - uWSGI instance to serve myproject   Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset   Active: active (running) since Mon 2021-10-25 22:34:52 UTC; 14s ago Main PID: 9391 (uwsgi)    Tasks: 6 (limit: 1151)   CGroup: /system.slice/myproject.service           ├─9391 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.i           ├─9410 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.i           ├─9411 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.i           ├─9412 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.i           ├─9413 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.i           └─9414 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.i

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

    Paso 6: Configuración de Nginx para procesar solicitudes

    Ahora, el servidor de aplicaciones uWSGI debería estar en funcionamiento y esperando solicitudes en el archivo de socket del directorio del proyecto. Ahora, puede configurar Nginx para que envíe solicitudes web a ese socket mediante el uwsgiprotocolo.

    Comience por crear un nuevo archivo de configuración de bloque de servidor en sites-availableel directorio de Nginx. Asígnele un nombre myprojectque sea coherente con 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 su 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 uwsgi_paramsarchivo que especifica algunos parámetros uWSGI generales que deben configurarse. Luego, pasará las solicitudes al socket que definió mediante la uwsgi_passdirectiva:

    /etc/nginx/sites-available/miproyecto

    server {    listen 80;    server_name your_domain www.your_domain;    location / {        include uwsgi_params;        uwsgi_pass 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 ejecutando lo siguiente:

    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

    Ahora vuelve a ajustar el firewall. Ya no necesitas acceso a través del puerto 5000, por lo que puedes eliminar esa regla:

    1. sudo ufw delete allow 5000

    Después, permitirás el acceso al servidor Nginx:

    1. 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:

    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 uWSGI de su aplicación Flask.

    Paso 7: Proteger la aplicación

    Para garantizar que el tráfico a su servidor permanezca seguro, debe obtener 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 del 2 al 6 de Cómo crear un certificado SSL autofirmado para Nginx en Ubuntu 18.04 . Lo demostraremos con la opción uno por conveniencia. Para ver el tutorial completo, consulte Cómo proteger Nginx con Let’s Encrypt en Ubuntu 18.04 .

    Primero, agregue el repositorio Certbot Ubuntu:

    1. sudo add-apt-repository ppa:certbot/certbot

    Necesitarás presionar ENTERpara aceptar.

    A continuación, instale el paquete Nginx de Certbot con apt:

    1. sudo apt install python-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, ejecute 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 desea 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 2022-01-24. 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 uWSGI 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 extremadamente flexible diseñado para brindar funcionalidad a sus aplicaciones sin ser demasiado restrictivo en cuanto a estructura y diseño. Puede utilizar la pila general descrita en esta guía para brindar servicio a las aplicaciones Flask que desee diseñar.

    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