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

Nginx и Gunicorn 'err_conn_refused', но nginx не регистрирует ошибку

Я экспериментировал с Django Cookie Cutter для локальных проектов и хотел поместить его в свой DO Droplet в качестве полупроизводственной промежуточной среды.

Сервер настроен с обратным проксированием Nginx для различных проектов, некоторые обслуживаются с помощью Gunicorn, один - с голым Flask, а третий - с uWSGI. У каждого проекта свой virtualenv.

При развертывании проекта и его настройке у меня возникает следующая последовательность ошибок.

Конфигурация Nginx выглядит следующим образом (что отражает другие сайты в этой капле):

server {
        server_name test.myserver.com;

        access_log off;

        location /static/ {
            alias /var/www/myproject/static/;
        }

        location / {
                proxy_pass http://127.0.0.1:8085;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Real-IP $remote_addr;
                add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
        }
    }

В первом случае, после сброса nginx без настройки Gunicorn, это `` работает '' / делает то, что я ожидаю: выдает ошибку 502 Bad Gateway и примечание журналов nginx:

2016/02/25 11:27:25 [error] 21217#0: *275 connect() failed (111: Connection refused) while connecting to upstream, client: my.ip.address, server: test.myserver.com, request: "GET / HTTP/1.1", upstream:$

Итак, запускаем Gunicorn:

/var/www/test.myserver.com/env/bin/gunicorn -b 127.0.0.1:8085 myproject.wsgi:application &

(запускать из папки, в которой есть manage.py) - в браузере выдается 400 Bad Request; отмечает сервер Gunicorn (пока я вхожу по ssh и могу видеть):

[Django] ERROR: Invalid HTTP_HOST header: u'127.0.0.1:8085'.You may need to add u'127.0.0.1' to ALLOWED_HOSTS.

Имеет смысл: django-cookiecutter помещает большую часть конфиденциальной конфигурации в переменные среды. Мой файл .env (и я проверил, что он доступен в оболочке) выглядит так:

TERM=xterm-256color
SHELL=/bin/bash
SSH_CLIENT=my.ip.address 57044 22
OLDPWD=/var/www/myproject/env
SSH_TTY=/dev/pts/0
USER=root
VIRTUAL_ENV=/var/www/myproject/env
MAIL=/var/mail/root


PATH=/var/www/treatout/env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
        PWD=/var/www/treatout/env/bin
        LANG=en_US.UTF-8
        PS1=(env)${debian_chroot:+($debian_chroot)}\u@\h:\w\$ 
        SHLVL=1
        HOME=/root
        LOGNAME=root
        SSH_CONNECTION=82.23.204.106 57044 178.62.47.176 22
        _=/usr/bin/env

Если я экспортирую DJANGO_ALLOWED_HOSTS=127.0.0.1 (переменная env, которая сопоставляется с ALLOWED_HOSTS в настройках Django) или что-то еще (строка, а не строка, подстановочный знак, список), похоже, полностью нарушает что-то, и я получаю 'ERR_CONN_REF' ошибка в браузере, и URL-адрес браузера переключается с test.myserver.com на 127.0.0.1:8085 (так что, очевидно, он не подключается, я не запускаю сервер на моем локальном хосте на этом порту.)

В журнале Nginx ничего нет (я ожидал, что здесь будет ошибка восходящего потока), и Gunicorn никогда не видит запрос. Это не (как ни странно), похоже, не отображается в журнале доступа nginx.

Я также пробовал переименовать env.example, содержащий все мои переменные, в .env, но, похоже, это не имеет большого значения.

Я явно что-то упустил, но не знаю, что именно, и пытаюсь отладить; другие сайты работают нормально, и nginx в целом не пострадал. Пытаюсь unset DJANGO_ALLOWED_HOSTS удалил его из .env, но у меня все еще есть проблема после сброса nginx.

Изменить: я вернулся к последней «рабочей» конфигурации (т. Е. Выбросил 400 Bad Request и все, что записывается в журнал), только удалив и перестроив virtualenv; Я действительно не хочу делать это несколько раз, поскольку существует много зависимостей, и это занимает довольно много времени!

Второе редактирование: при проверке настроек среды с помощью джанго-окружающая среда похоже, что команда экспорта испортила формат:

env('DJANGO_ALLOWED_HOSTS')
'my.server.ip.address:127.0.0.1'

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

Ответ в этом конкретном случае связан с отсутствием соединения между файлом настроек production.py и настройками среды, когда вы не используете Heroku или Docker. (Взято из выпуска 490.)

Здесь у меня были двоякие проблемы: неправильный формат для разрешенных хостов, вызванный неправильным объединением строк, и необходимость поместить:

"В вашем файле настроек (например, common.py) читать можно так: env.read_env(ROOT_DIR('.env')) в зависимости от того, куда вы положили свою копию ".

Это немедленно сделало (ранее установленные) переменные среды доступными как для оболочки, так и для программы. Я не буду вдаваться в подробности о багах, которые возникли у меня в результате бесконечных ошибок, это отдельная история. :)

Отредактируйте через некоторое время: с этим была связана проблема - в файле конфигурации nginx для сайта (в sites-available) Пришлось добавить

proxy_set_header Host $http_host; чтобы убедиться, что было передано правильное имя хоста; это предотвращает перенаправление на localhost, которое происходит при определенных обстоятельствах.

Таким образом, теперь весь мой файл сайта:

server {
        server_name myservernamehere.com;

        access_log off;

        location /static/ {

            alias /var/www/mysitename/mysitename/mysitename/static/;
        }

        location / {
                proxy_pass http://127.0.0.1:8085;
                client_max_body_size 20M;
                proxy_set_header Host $http_host;
                proxy_set_header X-Forwarded-Host $server_name;
                proxy_set_header X-Real-IP $remote_addr;
                add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
        }
    }