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
Restart apache2
service and verify that wsgi module is loaded: sudo apache2ctl -M|grep -i wsgi
Create a projectname.wsgi
file in your project:
import sys
sys.path.insert(0, '/path/to/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 /etc/apache2/sites-available
:
<VirtualHost *:<PORT>>
ServerName <DOMAIN.NAME>
WSGIDaemonProcess <projectname> user=<user> group=www-data threads=2
WSGIScriptAlias / /path/to/project/projectname.wsgi
<Directory /path/to/project>
WSGIProcessGroup <projectname>
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
Alias "/static/" "/path/to/project/static/"
<Directory /path/to/project/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog /path/to/logs/error.log
CustomLog /path/to/logs/access.log combined
</VirtualHost>
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__))
Comments
There are currently no comments
New Comment