Назад | Перейти на главную страницу

Проксирование приложения Flask с помощью Gunicorn и nginx

У меня есть приложение Flask, которое в настоящее время обслуживается на машине (назовите его first_vm), используя следующую команду в supervisord:

gunicorn run:app -b 0.0.0.0:8002 -k socketio.sgunicorn.GeventSocketIOWorker --workers 1

Это приложение также имеет обратный прокси локально в порту 80 по nginx, так что http://first_vm/ будет обслуживать приложение, как ожидалось.

Что я хотел бы сделать, так это отменить прокси-сервер приложения на другом сервере (скажем, second_vm), такое что http://second_vm/my_app обслуживает приложение, нажав gunicorn на first_vm:8002.

Это конфигурация nginx, которую я сейчас использую second_vm:

location /my_app {
    proxy_pass http://first_vm:8002/;

    proxy_set_header   Host $host;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Host $server_name;
}

Эта конфигурация отлично работает, поскольку она обслуживает мое приложение на http://second_vm/my_app, но статические файлы (например, JS / CSS) не обслуживаются должным образом, потому что браузер пытается получить их из http://second_vm/ вместо того http://second_vm/my_app.

Например, Chrome скажет мне, что это Failed to load resource: the server responded with a status 404 в следующем сценарии:

http://second_vm/blueprint/static/css/bootstrap.min.css   <-- what Chrome fails to fetch
http://second_vm/my_app/blueprint/static/css/bootstrap.min.css   <-- what it should fetch

Может ли кто-нибудь помочь мне сделать эту работу?

После многих испытаний и невзгод я обнаружил сообщение в блоге, которое решило эту проблему и для меня. http://albertoconnor.ca/blog/2011/Sep/15/hosting-django-under-different-locations В нем упоминается Django, но в остальном это то же программное обеспечение (а именно, gunicorn и nginx), и исправление такое же, как и основная причина.

Редактировать:

По сути, в приложении flask отсутствует заголовок SCRIPT_NAME, который сообщает ему, где находится приложение, поэтому добавление proxy_set_header SCRIPT_NAME /my_app; - это первый запуск, но затем вам нужно также исправить перенаправление, так как есть некоторые исправления URL-адресов под капотом, поэтому proxy_redirect http://first_vm:8002/my_app http://$host/my_app; должен помешать ему делать такие вещи, как возврат относительных адресов между first_vm и second_vm.