Я пытаюсь запустить приложение Flask на Gunicorn через сервер Nginx. Я бы хотел, чтобы приложение запускалось в подкаталоге, а не через другой порт, если это возможно, но все, что я получаю, это ошибки 404. Вот мой файл conf, включенный в папку conf.d:
server {
listen 80;
server_name 127.0.0.1;
location / {
root /var/www/html;
}
location /chess/ {
proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
proxy_set_header Host $http_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-Proto $scheme;
}
}
Может кто-нибудь, пожалуйста, скажите мне, как это сделать? Я все перерыл и перепробовал много разных вещей, но безрезультатно. Он отлично работает на другом порту, но это не то, что мне нужно. Субдомен также является подходящим вариантом, но по какой-то причине я могу заставить его работать только в производстве, а не в разработке. Кто-то задал вопрос здесь, но ссылка, которую они дали на решение, мертва.
когда вы получаете 404? когда вы заходите в /chess/? пожалуйста, приложите код фляжного приложения.
так или иначе, следующее, безусловно, работает, я проверял это.
следовал этому руководству
myproject.py
:
from flask import Flask
app = Flask(__name__)
@app.route("/chess/",defaults = {'name': None})
@app.route("/chess/<name>")
def hello(name):
if name is None:
name = "!"
else:
name = ", " + name
# PLEASE don't use the following line of code in a real app, it creates a self-xss vulnerability. ALWAYS sanitize user input.
return f"<h1 style='color:blue'>Hello There{name}</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
nginx - /etc/nginx/sites-enabled/myproject (symlink)
server {
listen 8080;
server_name your_domain www.your_domain;
location / {
root /home/username/myproject/static/;
}
location /chess/ {
include proxy_params;
proxy_pass http://unix:/home/username/myproject/myproject.sock;
}
}
<host>:8080/chess/stackoverflow
:
<host>:8080/a.html
: (на самом деле подается из /home/myproject/static
)
в общем и для дальнейшего использования - попробуйте посмотреть журналы nginx (/var/log/nginx
) или сервисные журналы (journalctl -u myproject
или systemctl status myproject
)
Понял. Спасибо! рад слышать, что это сработало. просто для записи порт 80 сработал бы так же хорошо. «лучшая практика» не имеет особого смысла, поскольку пушка (в вашем случае) вообще не «прослушивает» какой-либо сетевой порт, вы общаетесь с ним через unix-сокет. все, что делает добавленный прокси-проход, — это перемещает его из nginx в себя (с порта 80 на 8080) (а затем перенаправляет его с порта 8080 на пушку через unix-сокет)
Я еще немного поиграл и обнаружил, что вы абсолютно правы, поэтому я изменил свой ответ, чтобы включить ваш. Однако двойной метод proxy_pass имеет преимущество в таких ситуациях, как использование поддомена, поэтому я оставил его.
Доступны два метода. Первый метод включает в себя добавление подпути как к конфигурации NGINX, так и к приложению Flask, как это предлагается в ответе Yarin_007. Настройте NGINX следующим образом:
server {
listen localhost:80;
location / {
root /var/www/html;
}
location /chess/ {
proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
proxy_set_header Host $http_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-Proto $scheme;
}
}
И измените приложение Flask, чтобы включить вложенный путь:
from flask import Flask, request
...
@app.route("/chess/", methods=["GET", "POST"])
...
Альтернативой, , как предлагается в этом ответе , является запуск службы Gunicorn на непривилегированном порту (или, возможно, поддомене) и использование двух директив proxy_pass
для прямого перехода из подпути порта 80 следующим образом:
server {
listen localhost:80;
location / {
root /var/www/html;
}
location /chess/ {
proxy_pass http://localhost:8080/;
}
}
server {
listen localhost:8080;
location / {
proxy_pass http://unix:/usr/share/nginx/sockets/chess.sock;
proxy_set_header Host $http_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-Proto $scheme;
}
}
Приложение Flask может остаться таким, каким оно было изначально:
from flask import Flask, request
...
@app.route("/", methods=["GET", "POST"])
...
Я голосую и присуждаю награду за ваш ответ, потому что он вывел меня на правильный путь, но я не могу отметить его как правильный, потому что смысл вопроса заключался в том, чтобы оставаться на порту 80. Я нашел свое решение в другом месте . Смотрите мой ответ.