Как разместить несколько фляжных приложений в одном домене, размещенном на nginx?

То, что я пытаюсь достичь:

У меня есть веб-сервер nginx, на котором размещается mydomain.com. Когда кто-то вводит мой домен.com в свой клиент, я хотел бы, чтобы мой сервер обслуживал index.html из /var/www/mydomain/ Когда они набирают mydomain.com/flaskapp1, они должны видеть flaskapp1. Когда они набирают mydomain.com/flaskapp2, они должны видеть flaskapp2.

Мне удалось получить одно или другое приложение для флэков, которое использовалось в этом учебнике здесь: http://www.markjberger.com/flask-with-virtualenv-uwsgi-nginx/, но при попытке реализовать два отдельных приложения для флэков я столкнулся с трудностями, Вместо того, чтобы видеть приложение с флягой, я получаю сообщение 404, когда пытаюсь получить доступ к любому из флеш-приложений с помощью mydomain.co.uk/flaskapp или mydomain.co.uk/flaskapp2 в браузере.

Это то, что у меня есть до сих пор:

cat/etc/nginx/sites-available/mydomain.co.uk

server {
       listen 80;

        server_name www.mydomain.co.uk mydomain.co.uk;

        location / {
               root /var/www/html/;
               index index.html index.htm;
        }

        location /flaskapp {
                include uwsgi_params;
                uwsgi_pass unix:/tmp/flaskapp.sock;
        }

         location /flaskapp2 {
              include uwsgi_params;
              uwsgi_pass unix:/tmp/flaskapp2.sock;
         }
 }

Вышеупомянутый файл conf был связан с SIM-картой в /etc/nginx/sites-enabled.

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

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

Оба файла.ini были связаны символами в /etc/uwsgi/apps-enabled. UWSGI перезагружается без каких-либо проблем и работает. И flaskapp.sock, и flaskapp2.sock принадлежат www-data

cat/var/www/flaskapp/flaskapp.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World from flaskapp1!'

if __name__ == '__main__':
    app.run(host='0.0.0.0')

cat/var/www/flaskapp2/flaskapp2.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World from flaskapp2!'

if __name__ == '__main__':
    app.run(host='0.0.0.0')

cat/var/www/mydomain.co.uk/index.html

<!DOCTYPE html>
<html>
<body>

<h1>mydomain.co.uk</h1>

<p>This is the index page of my domain.co.uk</p>

</body>
</html>

В обеих виртуальных средах установлена фляга, и они будут запускать приложения для флэков с использованием сервера разработки.

Надеюсь, это что-то простое, что я пропустил.

Ответы

Ответ 1

Смотрите здесь документацию uwsgi для NGINX.

В частности:

К сожалению, nginx не может переписать PATH_INFO соответственно SCRIPT_NAME. По этой причине вам необходимо указать uWSGI для сопоставления определенных приложений в так называемой "точке монтирования" и автоматически переписать SCRIPT_NAME и PATH_INFO:

Сработало изменение файлов flaskapp.ini и flaskapp2.ini, содержащих точки монтирования для приложений и включение переменной имени сценария управления.

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

И теперь оба флеш-приложения запускаются через uwsgi через nginx по мере необходимости.

Ответ 2

Проблема здесь: оба флеш-приложения не знают, что их подавали из подкаталога в вашем домене. Nginx передает полный URL-адрес им, а не URL-адрес относительно этого каталога, поэтому каждый URL-адрес отправляется относительно root. Посмотрим, что в примере:

Предположим, что у вас есть 3 вида в вашем flaskapp, которые подаются на URL-адресах /one/, /two/ и /three/. Поэтому, когда вы пытаетесь получить доступ к представлению по URL /one/, вы вводите адрес: http://yourdomain.com/flaskapp/one/. Flask будет получать от nginx URL /flaskapp/one/ но в этом приложении нет такого представления, поэтому он отправит 404 в ответ.

Что вы можете сделать, так это сообщить каждому фласкапу, что они не подаются в корне домена, а в конкретном подкаталоге. Вы можете добиться этого, отправив SCRIPT_NAME uwsgi_param с местоположением подкаталога в значение, поэтому ваша конфигурация nginx будет иметь:

    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;
    }