обслуживание приложения flask с использованием gunicorn + nginx, показывающее 404 [ec2]

Я пытаюсь обслуживать простой API, следуя этому руководство по digitalocean.

Для тестирования я ранее обслуживал API через gunicorn, выполняя

$ gunicorn --bind 0.0.0.0:5000 trumporate.wsgi:app

И скручивание конечной точки API работает внутри коробки ec2.

$ curl -X GET http://0.0.0.0:5000/api/v1/trump/rant/
{
  "foo": "bar"
}

Теперь я переключил этот процесс gunicorn на запуск при запуске, создав службу systemd

# /etc/systemd/system/trumporate.service

[Unit]
Description=Gunicorn instance for trumporate
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/var/opt/trumporate
ExecStart=/usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunicorn-error.log trumporate.wsgi:app

[Install]
WantedBy=multi-user.target

Я создал файлы

  • /var/log/trumporate/gunicorn-error.log
  • /var/log/trumporate/gunicorn-access.log

и изменил владельца и группу на ubuntu

После включения сервиса и перезагрузки проверил статус

$ sudo systemctl status trumporate.service
● trumporate.service - Gunicorn instance for trumporate
   Loaded: loaded (/etc/systemd/system/trumporate.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2017-05-03 06:30:26 UTC; 1h 2min ago
 Main PID: 1122 (gunicorn)
    Tasks: 4
   Memory: 92.2M
      CPU: 1.390s
   CGroup: /system.slice/trumporate.service
           ├─1122 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic
           ├─1264 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic
           ├─1266 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic
           └─1267 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic

May 03 06:30:26 ip-172-31-25-173 systemd[1]: Started Gunicorn instance for trumporate.

Следуя руководству по DO, я попытался настроить nginx для проксирования входящих запросов через порт 80.

$ cat /etc/nginx/sites-available/trumporate
server {
    listen 80;
    server_name private_ip_address;

    location / {
        include proxy_params;
        proxy_pass http://unix:/var/opt/trumporate/trumporate.sock;
    }
}

А потом сделал

$ ln -s /etc/nginx/sites-available/trumporate /etc/nginx/sites-enabled

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Теперь, если я попытаюсь выполнить GET запрос к конечной точке API из-за пределов поля ec2

$ curl -X GET http://public_ip/api/v1/trump/rant
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.0 (Ubuntu)</center>
</body>
</html>

Тот же случай, когда я пытаюсь сделать это и из контейнера ec2.

$ curl -X GET http://localhost:80/api/v1/trump/rant/
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.10.0 (Ubuntu)</center>
</body>
</html>

файлы журнала

# /var/log/nginx/access.log
dev_box_ip - - [03/May/2017:05:50:45 +0000] "GET /api/v1/trump/rant/ HTTP/1.1" 404 580 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"
127.0.0.1 - - [03/May/2017:06:13:26 +0000] "GET /api/v1/trump/rant/ HTTP/1.1" 404 178 "-" "curl/7.47.0"
dev_box_ip - - [03/May/2017:07:42:42 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36"

/var/log/nginx$ cat error.log
/var/log/nginx$

/var/log/trumporate$ cat gunicorn-access.log
/var/log/trumporate$

$ cat gunicorn-error.log
[2017-05-03 06:28:41 +0000] [1884] [INFO] Starting gunicorn 19.7.1
[2017-05-03 06:28:41 +0000] [1884] [INFO] Listening at: unix:trumporate.sock (1884)
[2017-05-03 06:28:41 +0000] [1884] [INFO] Using worker: sync
[2017-05-03 06:28:41 +0000] [1889] [INFO] Booting worker with pid: 1889
[2017-05-03 06:28:41 +0000] [1890] [INFO] Booting worker with pid: 1890
[2017-05-03 06:28:41 +0000] [1891] [INFO] Booting worker with pid: 1891
[2017-05-03 06:29:48 +0000] [1884] [INFO] Handling signal: term
[2017-05-03 06:29:48 +0000] [1889] [INFO] Worker exiting (pid: 1889)
[2017-05-03 06:29:48 +0000] [1890] [INFO] Worker exiting (pid: 1890)
[2017-05-03 06:29:48 +0000] [1891] [INFO] Worker exiting (pid: 1891)
[2017-05-03 06:29:49 +0000] [1884] [INFO] Shutting down: Master
[2017-05-03 06:30:27 +0000] [1122] [INFO] Starting gunicorn 19.7.1
[2017-05-03 06:30:27 +0000] [1122] [INFO] Listening at: unix:trumporate.sock (1122)
[2017-05-03 06:30:27 +0000] [1122] [INFO] Using worker: sync
[2017-05-03 06:30:27 +0000] [1264] [INFO] Booting worker with pid: 1264
[2017-05-03 06:30:27 +0000] [1266] [INFO] Booting worker with pid: 1266
[2017-05-03 06:30:28 +0000] [1267] [INFO] Booting worker with pid: 1267
/var/log/trumporate$

ИЗМЕНИТЬ

Соответствующая часть фляжного приложения

@app.route('/api/v1/trump/rant/')
def return_rant():
    foo = # logic
    return jsonify(rant=foo)

person Tasdik Rahman    schedule 03.05.2017    source источник


Ответы (1)


Вы сделали nginx -s reload && systemctl restart nginx?

Еще одна вещь, которую вы можете попробовать, - это сделать привязки к http-порту вместо сокета:

--bind 127.0.0.1:6767 #in systemd config

и измените конфигурацию nginx следующим образом:

location / {
    include proxy_params;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:6767;
}

Также, почему у вас есть private_ip в конфигурации nginx?

server_name private_ip_address;

Измените это на

server_name "_";
# OR
server_name PUBLIC_IP;

и удалите все конфиги по умолчанию из /etc/nginx/site-enabled


1) использование server_name private_ip_address ;?

Nginx использует server_name для сверки с заголовком хоста входящего запроса, и это не частный адрес. (Обычно вы получаете доступ, используя либо доменное имя, либо общедоступный адрес в строке URL)

2) Я удалил каталог /etc/nginx/site-enabled/default, чтобы все заработало.

Если ваше имя_сервера указано неправильно, nginx обрабатывает запрос, используя файл по умолчанию или блок сервера, содержащий default_server. Поэтому я попросил вас удалить этот файл на случай, если возникнут проблемы с именем вашего сервера ^_^

Кроме того, какая разница в производительности API, если я привяжу его к порту, а не к файлу сокета, как это предлагается в сообщении в блоге?

Как правило, это преждевременная оптимизация, любая разница, которую вы получите, будет находиться в пределах погрешности по сравнению с узкими местами, вызванными flask/python и особенно подключениями к базе данных. Хотя, пожалуйста, отнеситесь к этому с недоверием, поскольку у меня нет надежного источника, чтобы процитировать это.

person oxalorg    schedule 03.05.2017
comment
привязка к конкретному порту отработана. Не уверен, почему привязка к сокету не работала в этом конкретном случае. Несколько быстрых вопросов, которые вы можете добавить к своему ответу: 1) использование server_name private_ip_address;? 2) Я удалил /etc/nginx/site-enabled/default каталог, чтобы все заработало. Ваши комментарии? - person Tasdik Rahman; 03.05.2017
comment
Кроме того, какая разница в производительности API, если я привяжу его к порту, а не к файлу сокета, как это предлагается в сообщении в блоге? - person Tasdik Rahman; 03.05.2017