How to host multiple flask apps under a single domain hosted on nginx?
Looking at the uwsgi documentation for NGINX here.
Specifically:
Unfortunately nginx is not able to rewrite PATH_INFO accordingly to SCRIPT_NAME. For such reason you need to instruct uWSGI to map specific apps in the so called “mountpoint” and rewrite SCRIPT_NAME and PATH_INFO automatically:
Changing my flaskapp.ini
and flaskapp2.ini
files to contain the mount points for the apps and turning on the manage-script-name variable has worked.
cat /etc/uwsgi/apps-available/flaskapp.ini
[uwsgi]
vhost = true
socket = /tmp/flaskapp.sock
venv = /var/www/flaskapp/venv
chdir = /var/www/flaskapp
module = flaskapp
callable = app
mount = /flaskapp=flaskapp.py
manage-script-name = true
cat /etc/uwsgi/apps-available/flaskapp2.ini
[uwsgi]
vhost = true
socket = /tmp/flaskapp2.sock
venv = /var/www/flaskapp2/venv
chdir = /var/www/flaskapp2
module = flaskapp2
callable = app
mount = /flaskapp2=flaskapp2.py
manage-script-name = true
And now both flask apps are running via uwsgi through nginx as required.
Adding the mounting point worked for me.
/etc/uwsgi/apps-available/flaskapp.ini
callable = app
mount = /flaskapp=/var/www/flaskapp
/etc/uwsgi/apps-available/flaskapp2.ini
callable = app
mount = /flaskapp2=/var/www/flaskapp2
Source https://neginfinity.bitbucket.io/2017/09/hosting-multiple-flask-applications-in-nginx.html
The problem is here: both flask apps have no idea that they were served from subdirectory in your domain. Nginx is passing full URL to them, not URL relative to that directory, so every URL is dispatched relative to root. Let's see that in example:
Assume that you have 3 views in your flaskapp, served on urls /one/
, /two/
and /three/
. So when you're trying to access view on URL /one/
, you are typing address: http://yourdomain.com/flaskapp/one/
. Flask will receive from nginx URL /flaskapp/one/
but there is no such view in that app, so it will send 404 in response.
What you can do is inform each flaskapp that they aren't served on domain root, but on particular subdirectory. You can achieve this by sending SCRIPT_NAME
uwsgi_param
with subdirectory location in value, so your nginx config will have:
location /flaskapp {
include uwsgi_params;
uwsgi_pass unix:/tmp/flaskapp.sock;
uwsgi_param SCRIPT_NAME /flaskapp;
}
location /flaskapp2 {
include uwsgi_params;
uwsgi_pass unix:/tmp/flaskapp2.sock;
uwsgi_param SCRIPT_NAME /flaskapp2;
}