Desplegar o integrar Flask con Apache en Linux
Bueno, ya hemos entrenado bastante con Python y su framework Flask, de manera que es hora de desplegar nuestros proyectos con Apache2. Ya no más con el servidor propio de Flask. Por eso vamos a ver cómo integrar Flask con Apache web server en Linux.
Recordemos que así como Apache recurre al interprete PHP para transformar el código PHP en una vista HTML, así también en Flask tenemos un interprete o un gateway para que Apache pueda devolver al cliente una vista HTML, desde un desarrollo en python. Para Apache, este componente mediador se llama wsgi (Web Server Gateway Interface).
Instalación de Apache y el módulo wsgi
Instalamos a Apache server y el módulo WSGI para que acepte la vinculación con Flask:
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi-py3
Habilitamos a wsgi:
sudo a2enmod wsgi
Creamos el archivo de configuración de nuestro virtual host en Apache, para el funcionamiento de nuestro proyecto:
cd /etc/apache2
sudo touch site-available/flask.conf
Este será su contenido:
<VirtualHost *:80>
ServerAdmin tu@correo.com.co
ServerName 192.168.0.30
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIScriptAlias / /var/www/flask/mi_flask.wsgi
<Directory /var/www/flask/>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
Luego deshabilitamos el virtual host predeterminado de Apache2 y habilitamos el que acabamos de crear:
sudo a2dissite 000-default.conf &&
sudo a2ensite flask.conf
Creamos los directorios flask/MiFlask como subdirectorios de /var/www:
sudo mkdir /var/www/flask/MiFlask
Creamos el archivo mi_flask.py en el directorio /var/www/flask/MiFlask/:
sudo touch /var/www/flask/MiFlask/mi_flask.py
Este es su contenido:
from flask import Flask
app = Flask("__name__")
@app.route("/")
def principal():
return "Hola desde Flask!"
if __name__ == '__main__':
app.run()
Ahora creamos el archivo mi_flask.wsgi en el directorio /var/www/flask
sudo touch /var/www/flask/mi_flask.wsgi
Este es su contenido:
import sys
sys.path.insert(0, '/var/www/flask/MiFlask/')
from mi_flask import app as application
Perfecto, ahora solo nos queda reiniciar el servicio de Apache, y abrir nuestra dirección IP con nuestro navegador favorito:

Hola Mundo desde Flask
Y listo, ya tenemos la tarea lista de integrar Flask con Apache en Linux.
Hasta aquí ya tenemos nuestra app de Flask funcionando perfectamente con Apache web server. Sin embargo, si quieres optimizar a Apache para que trabaje con más de una app, entonces te recomiendo seguir leyendo.
Desplegar o Integrar Flask y Apache con múltiples apps
También podemos tener múltiples apps dentro de Flask y Apache. Si es nuestro caso, entonces solo debemos organizar el archivo de configuración del virtual host de Apache, de la siguiente manera:
<VirtualHost *:80>
ServerAdmin tu@correo.com.co
ServerName 192.168.0.30
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIScriptAlias /miflask /var/www/flask/MiFlask/wsgi/mi_flask.wsgi
<Directory /var/www/flask/MiFlask>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
WSGIScriptAlias /mi_nuevapp /var/www/flask/nuevapp/wsgi/nueva_app.wsgi
<Directory /var/www/flask/nuevapp>
Options FollowSymLinks
AllowOverride None
Require all granted
</directory>
</VirtualHost>
Como las rutas que apuntan a las apps han cambiado, entonces también debemos ajustar las rutas en los archivos wsgi:
El de mi_Flask.wsgi:
y el wsgi de la nueva app, nueva_app.wsgi:
El código de la nueva app de pruebas, flask2.py:
Y su funcionamiento en el navegador:
Ejecutar nuestras apps en modo Daemon
Puede que necesitemos ejecutar nuestras apps en entorno virtual, esto para solventar algún tipo de incompatibilidad de versiones entre librerías. Además, también necesitamos definir la cantidad de procesos hijos que WSGI gestionará para las apps. En ese caso, hemos de modificar el archivo de configuración del virtual host de Apache, así (se ha adicionado las líneas en rojo):
<VirtualHost *:80>
ServerAdmin tu@correo.com.co
ServerName 192.168.0.30
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIDaemonProcess myproc user=www-data group=www-data processes=2 threads=15 python-path=/var/www/flask/MiFlask:/var/www/flask/MiFask/lib/python3.8/site-packages/
WSGIProcessGroup myproc
WSGIScriptAlias /miflask /var/www/flask/MiFlask/wsgi/mi_flask.wsgi
<Directory /var/www/flask/MiFlask>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
WSGIScriptAlias /mi_nuevapp /var/www/flask/nuevapp/wsgi/nueva_app.wsgi
<Directory /var/www/flask/nuevapp>
Options FollowSymLinks
AllowOverride None
Require all granted
</directory>
</VirtualHost>
Entonces, por ahora renombramos el directorio MiFlask (por ejemplo a bkMiFlask), y ubicados en el directorio /var/www/flask/ creamos un ambiente virtual con el mismo nombre de nuestra app:
virtualenv MiFlask
Y trasladamos el contenido de ‘bkMiFlask’ al ambiente virtual (cp -r bkMiFlask/* MiFlask). Ahora debemos reiniciar el servicio de Apache
sudo service apache2 restart
Entramos al ambiente virtual de nuestra app y le instalamos las librerías de Flask, Pandas, PYMySQL (y las que necesites):
. MiFlask/bin/activate
pip3 install Flask
pip3 install pandas
Lo mismo hacemos para nuevapp.
Para salirnos del ambiente virtual:
deactivate
Nota: Si no nos aparece el comando virtualenv, debemos instalarlo así:
sudo apt install python3-virtualenv python3-venv
Puede suceder que cuando estamos creando un entorno virtual, el sistema te lo crea con la versión 2 de Python. Uno se da cuenta de eso porque el proceso muestra el mensaje “Running virtualenv with interpreter /usr/bin/python2”. Pero eso no es problema, podemos especificarle al sistema que cree nuestros entornos virtuales con Python 3, así:
- Ubica el binario de Python 3 con el comando ‘which python3‘ (en mi caso está en /usr/bin/python3).
- Luego, creamos el ambiente virtual con el siguiente comando:
sudo virtualenv -p /usr/bin/python3 mi_flask
¿Necesitas conectar tu app a una base de datos MySQL alojada en otra máquina?
En la configuración de MySQL del otro servidor, ubica el ‘bind-address‘ y cambiale el localhost por la IP de su tarjeta de red:
Luego creamos un usuario en la base de datos para que tenga permisos en esa IP, la 192.168.0.205. Yo creé mi usuario python y quedó así:
Apps de Flask en entornos virtuales diferentes
¿Quieres poner cada app en un entorno virtual separado? Ningún problema. Ajusta el virtual host de Apache, así:
<VirtualHost *:80>
ServerAdmin tu@correo.com.co
ServerName 192.168.0.30
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIDaemonProcess myproc user=www-data group=www-data processes=2 threads=15 python-path=/var/www/flask/MiFlask:/opt/entornos-virtuales/mi_flask/lib/python3.8/site-packages/
WSGIProcessGroup myproc
WSGIScriptAlias /miflask /var/www/flask/MiFlask/wsgi/mi_flask.wsgi
<Directory /var/www/flask/MiFlask>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
WSGIDaemonProcess myproc2 user=www-data group=www-data processes=2 threads=15 python-path=/var/www/flask/MiFlask:/opt/entornos-virtuales/mi_flask/lib/python3.8/site-packages/
WSGIProcessGroup myproc2
WSGIScriptAlias /mi_nuevapp /var/www/flask/nuevapp/wsgi/nueva_app.wsgi
<Directory /var/www/flask/nuevapp>
Options FollowSymLinks
AllowOverride None
Require all granted
</directory>
</VirtualHost>
Proseguimos creando el entorno virtual:
sudo virtualenv nuevaap
El detalle con este modelo de trabajo es que por cada cambio que realicemos en el código, debemos hacerle un reload al servidor Apache.
sudo service apache2 reload
Digamos que así está bien para tenerlo en un ambiente productivo (pues no vamos a estar haciendo cambios directamente en ambiente productivo), pero en un ambiente development resulta poco práctico. En ese caso te recomiendo trabajar el ambiente de desarrollo con el servidor web Gunicorn, que hace una recarga automática de la app con cada cambio de código:
TAmbién puedes ampliar más sobre instalar un servidor web apache
Solución al error ModuleNotFoundError: No module named ‘flask’
Si después de hacer todos los anteriores pasos no te carga la página, te aparece un error 500, y adicional a eso encuentras en el log de Apache un error que dice “[wsgi:error] … ModuleNotFoundError: No module named ‘flask’”, es porque puede que debamos instalar el módulo de Flask como root:
sudo pip install flask
Solución al error ModuleNotFoundError: No module named ‘markupsafe’
Este error me salió en un servidor con Ubuntu 18.04 cuando le estaba implementando Flask con Python 3. Bueno, la solución que me funcionó para superar este problema fue desinstalar Flask y volver a instalarlo, así:
sudo apt install python3-markupsafe
sudo apt install python3-flask
Recomendación: Mantener actualizadas las herramientas de instalación y configuración de repositorios Python, así:
pip3 install --upgrade setuptools
pip3 install --upgrade pip
Solución al error ‘jinja2.exceptions.TemplateNotFound:’
Este error comienza a salir cuando comenzamos a trabajar con templates y con Flask integrado con Apache (trabajándolo con otro web server tipo Gunicorn no aparece). Para solucionarlo, debemos instanciar el objeto Flask del siguiente modo:
app = Flask(__name__, template_folder='templates')
El __name__ sin comillas.
¿Podemos usar a Flask para sistemas de información grandes tipo ERP?
La respuesta es… sí, pero hay mejores soluciones para desarrollar ERPs, tales como DJango, u otro basados en PHP como CodeIgniter. Yo prefiero usar a Flask para pequeños problemas específicos, o para grandes problemas muy personalizados. Aunque existen buenos proyectos con Flask como backend, tal como Apache Superset.
Valora este artículo:
Tome su like
CREATE_APP
.
Comparte esto en









Pingback: 🥇 Exportar Datos de MySQL a Excel con Flask - Python
Pingback: 🥇 Optimizar o Acelerar a Apache Web Server en Linux
Pingback: 🥇 Crear Archivos PDF en Flask Python e Imprimirlo desde Linux
Pingback: 🥇 Aparece el error NumPy was imported from a Python en Python