Python Django call_command права доступа gunicorn + nginx - PullRequest
0 голосов
/ 13 марта 2019

Задача

Получите 502 неверных шлюза, когда я попытаюсь выполнить команду управления django через gunicorn

Логическая линия

Я думаю, что проблема связана с разрешениями, что-то вроде gunicorn не может вызвать команду. Я говорю это, потому что я могу запустить его на месте, где я не использую Gunicorn.

Я могу запустить его двумя способами:

  • python manage.py runserver и после этого стреляйте из Почтальона, и это нормально.

  • Второй звонит через терминал python manage.py command_name, и это тоже нормально.

  • На производстве я также могу работать с python manage.py command_name. Но не почтальоном, потому что возвращают 502 (основная проблема)

PS. Если я удаляю call_command, он возвращает 200 нормально, так что, похоже, основная проблема заключается в выполнении этой команды.

код

class TestCommandView(views.APIView):
    def post(self, request):
        id = request.data['id']

        try:
            call_command('command_name', target_id=id)
            return Response({"status": "success"})
        except Exception as error:
            return Response({"status": "error: " + str(error) })

Возвратный образец

<html>
    <head>
        <title>502 Bad Gateway</title>
    </head>
    <body bgcolor="white">
        <center>
            <h1>502 Bad Gateway</h1>
        </center>
        <hr>
        <center>nginx/1.14.0 (Ubuntu)</center>
    </body>
</html>

Gunicorn Conf

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
RuntimeDirectory=gunicorn
WorkingDirectory=/var/www/project
ExecStart=/var/www/project/venv/bin/ddtrace-run /var/www/project/venv/bin/guni$
Environment="DJANGO_SETTINGS_MODULE=project.settings.prod"

[Install]
WantedBy=multi-user.target

Ошибка журнала Nginx

2019/03/13 13:43:38 [error] 27552#27552: *3128 upstream prematurely closed connection while reading response header from upstream, client: IP, server: api.project.com, request: "POST /api/project/endpoint/ HTTP/1.1", upstream: "http://unix:/tmp/project.sock:/api/project/endpoint/", host: "api.project.com"

Что я пробовал

  • sudo chown -R www-data:www-data /var/www/project
  • sudo chown -R ubuntu:ubuntu /var/www/project
  • Измените значение моей среды на gunicorn config, основываясь на решении этого вопроса: Django call_command permissions nginx + gunicorn + supervisord . Добавление PYTHONPATH , но этот парень использует его в supervisor config, этот проект не использует supervisor , поэтому я попытался поставить его на gunicorn файл, это была просто попытка.

1 Ответ

0 голосов
/ 14 марта 2019

Я понял, что это была проблема тайм-аута

Тайм-аут по умолчанию gunicorn составляет 30 секунд, основываясь на его документации.

Док. Рабочие, которые молчат дольше, чем это количество секунд, погибают и перезапускаются.

Мой запрос получает более 30 секунд, поэтому gunicorn убил процесс и nginx вернул 502.

Решение

  • Изменение Gunicorn Время ожидания по умолчанию
  • Изменить время ожидания nginx

Gunicorn

Я добавил опцию времени ожидания для gunicorn ExecStart линия

- время ожидания 300

    ExecStart=/var/www/project/venv/bin/ddtrace-run /var/www/project/venv/bin/gunicorn --bind unix:/tmp/project.sock project.wsgi:application --access-logfile /home/ubuntu/gunicorn.log --error-logfile /home/ubuntu/gunicorn.error.log --timeout 720 --workers 3

Nginx

Добавлена ​​эта опция в HTTP-часть nginx conf

proxy_read_timeout 300s;

Перезапущено nginx и gunicorn и это работает как шарм

...