Cómo desplegar una aplicación Flask con uWSGI y Nginx en Ubuntu 20.04
Flask es un microframework web escrito en Python desarrollado por Armin Ronacher. Se llama microframework porque no requiere ninguna herramienta ni biblioteca. Flask es un módulo de Python y tiene un núcleo pequeño y fácil de extender que te ayuda a desarrollar aplicaciones web fácilmente.
En este tutorial, aprenderemos a desplegar una aplicación Flask con Uwsgi y Nginx en Ubuntu 20.04.
Requisitos previos
- Un servidor con Ubuntu 20.04.
- Un nombre de dominio válido apuntado con la IP de tu servidor.
- Una contraseña de root está configurado el servidor.
Cómo empezar
En primer lugar, se recomienda actualizar los paquetes de tu sistema con la última versión. Puedes actualizarlos ejecutando el siguiente comando:
apt-get update -y
Una vez actualizados todos los paquetes, puedes pasar al siguiente paso.
Instalar las dependencias necesarias
A continuación, tendrás que instalar algunas dependencias necesarias para desplegar la aplicación flask. Puedes instalarlas todas con el siguiente comando:
apt-get install nginx python3-pip python3-dev python3-venv build-essential libssl-dev libffi-dev python3-setuptools -y
Una vez instalados todos los paquetes, puedes proceder al siguiente paso.
Crear un entorno virtual
A continuación, tendrás que crear un entorno virtual para tu aplicación Flask. El entorno virtual es una herramienta muy útil para crear entornos Python aislados. Te ayuda a instalar una versión específica de Python para tu proyecto.
En primer lugar, crea un directorio para tu aplicación Flask con el siguiente comando:
mkdir /var/www/html/myapp
A continuación, cambia el directorio a myapp y crea un nuevo entorno virtual Python con el siguiente comando:
cd /var/www/html/myapp python3.8 -m venv myappenv
A continuación, activa el entorno virtual con el siguiente comando:
source myappenv/bin/activate
Configurar una aplicación Flask
En este punto, el entorno virtual Python está listo para desplegar la aplicación Flask. A continuación, tendrás que configurar una aplicación Flask dentro de tu entorno virtual.
En primer lugar, instala Flask y uWSGI con el siguiente comando:
pip install uwsgi flask
A continuación, crea una aplicación de ejemplo llamada myapp.py con el siguiente comando:
nano /var/www/html/myapp/myapp.py
Añade las siguientes líneas:
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "<h1 style='color:blue'>Hi This is My Flask Application</h1>" if __name__ == "__main__": app.run(host='0.0.0.0')
Guarda y cierra el archivo cuando hayas terminado. A continuación, ejecuta tu aplicación Flask con el siguiente comando:
python /var/www/html/myapp/myapp.py
Deberías ver la siguiente salida:
* Serving Flask app "myapp" (lazy loading) * Environment: production Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Ahora, abre tu navegador web y accede a tu aplicación Flask utilizando la URL http://your-server-ip:5000. Deberías ver la siguiente pantalla:
Ahora, pulsa CTRL + C en tu terminal para detener la aplicación Flask.
Configurar uWSGI
En primer lugar, crea un punto de entrada WSGI para indicar a tu servidor uWSGI cómo interactuar con él.
nano /var/www/html/myapp/wsgi.py
Añade las siguientes líneas para importar tu instancia Flask desde tu aplicación:
from myapp import app if __name__ == "__main__": app.run()
Guarda y cierra el archivo cuando hayas terminado y luego prueba si uWSGI puede servir la aplicación utilizando el siguiente comando:
uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
Ahora, accede de nuevo a tu aplicación utilizando la URL http://your-server-ip:5000. Deberías ver la siguiente pantalla:
Ahora, pulsa CTRL + C para detener la aplicación.
A continuación, ejecuta el siguiente comando para salir de tu entorno virtual:
deactivate
Configurar uWSGI
En este punto, uWSGI es capaz de servir a tu aplicación. Ahora, crea un archivo de configuración uWSGI con el siguiente comando:
nano /var/www/html/myapp/myapp.ini
Añade las siguientes líneas:
[uwsgi] module = wsgi:app master = true processes = 5 socket = myapp.sock chmod-socket = 660 vacuum = true die-on-term = true
Guarda y cierra el archivo cuando hayas terminado.
Crear un archivo de servicio Systemd
A continuación, tendrás que crear un archivo de servicio systemd para gestionar el servicio uWSGI. Puedes crearlo con el siguiente comando:
nano /etc/systemd/system/myapp.service
Añade las siguientes líneas:
[Unit] Description=uWSGI instance to serve myapp After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/html/myapp Environment="PATH=/var/www/html/myapp/myappenv/bin" ExecStart=/var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini [Install] WantedBy=multi-user.target
Guarda y cierra el archivo cuando hayas terminado y luego vuelve a cargar el demonio systemd con el siguiente comando:
systemctl daemon-reload
A continuación, cambia la propiedad de tu aplicación a www-data y establece el permiso adecuado con el siguiente comando:
chown -R www-data:www-data /var/www/html/myapp chmod -R 775 /var/www/html/myapp
A continuación, inicia tu aplicación y habilítala para que se inicie al reiniciar el sistema con el siguiente comando:
systemctl start myapp systemctl enable myapp
También puedes comprobar el estado de tu aplicación con el siguiente comando:
systemctl status myapp
Deberías obtener la siguiente salida:
? myapp.service - uWSGI instance to serve myapp Loaded: loaded (/etc/systemd/system/myapp.service; disabled; vendor preset: enabled) Active: active (running) since Sun 2020-09-13 08:38:08 UTC; 1min 53s ago Main PID: 662796 (uwsgi) Tasks: 6 (limit: 4691) Memory: 21.8M CGroup: /system.slice/myapp.service ??662796 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini ??662808 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini ??662809 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini ??662810 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini ??662811 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini ??662812 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x55e207e7a510 pid: 662796 (default app) Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: *** uWSGI is running in multiple interpreter mode *** Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI master process (pid: 662796) Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 1 (pid: 662808, cores: 1) Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 2 (pid: 662809, cores: 1) Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 3 (pid: 662810, cores: 1) Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 4 (pid: 662811, cores: 1) Sep 13 08:38:08 ubuntu2004 uwsgi[662796]: spawned uWSGI worker 5 (pid: 662812, cores: 1)
Configurar Nginx como Proxy Inverso
A continuación, tendrás que configurar Nginx como proxy inverso para servir la aplicación Flask. Puedes hacerlo con el siguiente comando
nano /etc/nginx/sites-available/flask.conf
Añade las siguientes líneas:
server { listen 80; server_name flask.example.com; location / { include uwsgi_params; uwsgi_pass unix:/var/www/html/myapp/myapp.sock; } }
Guarda y cierra el archivo cuando hayas terminado. A continuación, comprueba si Nginx tiene algún error de sintaxis con el siguiente comando:
nginx -t
Deberías ver la siguiente salida:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
A continuación, activa el host virtual Nginx con el siguiente comando:
ln -s /etc/nginx/sites-available/flask.conf /etc/nginx/sites-enabled/
Por último, reinicia el servicio Nginx para aplicar los cambios:
systemctl restart nginx
En este punto, Nginx está configurado para servir tu aplicación Flask.
Proteger la aplicación Flask con Let’s Encrypt SSL
A continuación, también se recomienda asegurar tu aplicación con el SSL gratuito Let’s Encrypt. En primer lugar, necesitarás instalar el cliente Certbot para instalar y gestionar el certificado SSL. Puedes instalarlo con el siguiente comando:
apt-get install python3-certbot-nginx -y
Una vez instalado, asegura tu sitio web con Let’s Encrypt SSL ejecutando el siguiente comando:
certbot --nginx -d flask.example.com
Se te pedirá que proporciones una dirección de correo electrónico válida y que aceptes las condiciones del servicio, como se muestra a continuación:
Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): [email protected] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel: A - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Y Obtaining a new certificate Performing the following challenges: http-01 challenge for flask.example.com Waiting for verification... Cleaning up challenges Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/flask.conf
A continuación, elige si deseas o no redirigir el tráfico HTTP a HTTPS, como se muestra a continuación:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Escribe 2 y pulsa Intro para finalizar la instalación. Deberías ver el siguiente resultado:
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/flask.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://flask.example.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=flask.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/flask.example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/flask.example.com/privkey.pem Your cert will expire on 2020-10-30. 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 - We were unable to subscribe you the EFF mailing list because your e-mail address appears to be invalid. You can try again later by visiting https://act.eff.org.
Ahora, tu sitio web Flask está protegido con Let’s Encrypt SSL. Puedes acceder a tu aplicación Flask utilizando la URL https://flask.example.com.
Conclusión
Enhorabuena! has desplegado con éxito la aplicación Flask con uWSGI y Nginx y la has asegurado con Let’s Encrypt SSL. Ahora puedes desarrollar y desplegar fácilmente tu aplicación Python con Flask. No dudes en preguntarme si tienes alguna duda.