Nowadays making a proxy from an nginx to a gunicorn socket running on supervisor or systemd makes things so easier that most of us even forgot how deployment was before. Recently I was asked to deploy a flask application on already working Apache2 instance. In this blog post I will describe steps and problems using mod_wsgi on Apache.
First of all, install python, pip and mod_wsgi:
apt install python3-dev python3-pip libapache2-mod-wsgi
apache2 service and verify that wsgi module is loaded:
sudo apache2ctl -M|grep -i wsgi
projectname.wsgi file in your project:
from app import app as application
application.root_path = '/path/to/project'
The first thing will add your python files to the python path, that is needed to find the app.py file (where your flask app is located). The second part will tell the application where the root is, it is required for loading templates.
Create a configuration file (
projectname.conf - .conf extension is required for the new version of Apache) for your project under
WSGIDaemonProcess <projectname> user=<user> group=www-data threads=2
WSGIScriptAlias / /path/to/project/projectname.wsgi
Allow from all
Alias "/static/" "/path/to/project/static/"
Allow from all
CustomLog /path/to/logs/access.log combined
Link the configuration file to the enabled folder:
cd ../sites-enabled &
ln -s ../sites-available/projectname.conf projectname.conf.
Reload apache2 service and check if the website is online.
Most notable difference between gunicorn is that you will not be able to open files from the relative path. You can use
current_app.root_path to access path and it is true for all plugins too (in my case, one of the plugins was storing a session file in the project root). Also defining
PROJECT_ROOT can be helpful:
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))