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

Gunicorn не создает сокет на nginx

Я пытаюсь настроить Django, Gunicorn и nginx.

Я настроил Gunicorn для запуска, но мне кажется, что у меня проблема с конфигурацией nginx для использования Gunicorn.

Вот моя конфигурация:

/etc/systemd/system/gunicorn.service

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

[Service]
PIDFile=/run/gunicorn/pid
User=root
Group=root
RuntimeDirectory=gunicorn
WorkingDirectory=/srv/myproject/current
ExecStart=/srv/venvs/myenv/bin/gunicorn --pid /run/gunicorn/pid   \
          --bind unix:/run/gunicorn/socket myapp.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Статус Gunicorn выглядит так

sudo systemctl статус gunicorn

gunicorn.service - gunicorn daemon
   Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2018-01-18 23:32:11 UTC; 3min 23s ago
  Process: 6347 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
 Main PID: 6355 (gunicorn)
    Tasks: 2
   Memory: 195.7M
      CPU: 1.426s
   CGroup: /system.slice/gunicorn.service
           ├─6355 /srv/venvs/myenv/bin/python3.6 /srv/venvs/myenv/bin/gunicorn --pid /run/gunicorn/pid --bind unix:/run/gunicorn/socket myapp.wsgi:application
           └─6360 /srv/venvs/myenv/bin/python3.6 /srv/venvs/myenv/bin/gunicorn --pid /run/gunicorn/pid --bind unix:/run/gunicorn/socket myapp.wsgi:application

Jan 18 23:32:11 python-server systemd[1]: Stopped gunicorn daemon.
Jan 18 23:32:11 python-server systemd[1]: Started gunicorn daemon.
Jan 18 23:32:11 python-server gunicorn[6355]: [2018-01-18 23:32:11 +0000] [6355] [INFO] Starting gunicorn 19.7.1
Jan 18 23:32:11 python-server gunicorn[6355]: [2018-01-18 23:32:11 +0000] [6355] [INFO] Listening at: unix:/run/gunicorn/socket (6355)
Jan 18 23:32:11 python-server gunicorn[6355]: [2018-01-18 23:32:11 +0000] [6355] [INFO] Using worker: sync
Jan 18 23:32:11 python-server gunicorn[6355]: [2018-01-18 23:32:11 +0000] [6360] [INFO] Booting worker with pid: 6360

Моя конфигурация nginx

/ и т. д. / nginx / сайты с включенным / myserver-python

server {
    server_tokens off;
    listen      443 ssl;
    server_name         myserver.com;
    keepalive_timeout   70;

    ssl_certificate     /etc/ssl/certs/myserver.com.merged.crt;
    ssl_certificate_key /etc/ssl/private/myserver.com.key;

    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    #access_log      /var/log/nginx/access.myserver.log;
    access_log      /var/log/nginx/access.myserver.log;
    #error_log       /var/log/nginx/error.myserver.log;
    error_log       /var/log/nginx/error.myserver.log;

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn/socket;
    }
}

На пути /run/gunicorn Я могу видеть только pid файл. файл socket никогда не создавал.

Так выглядит журнал ошибок

/var/log/nginx/error.myserver.log

2018/01/18 23:09:00 [crit] 5764#5764: *1 connect() to unix:/run/gunicorn/socket failed (2: No such file or directory) while connecting to upstream, client: 212.251.167.250, server: my-server.com, request: "GET / HTTP/1.1", upstream: "http://unix:/run/gunicorn/socket:/",, host: "myserver.com"

Кто-нибудь может увидеть, что здесь не так? Зачем socket файл не сделан и pid файл сделан?

Розетка, которая стреляет фактически open, как показано в записях журнала, отличается от сокета, настроенного в вашем модуле systemd.

В журнале показано, что на самом деле сделал Gunicorn:

Jan 18 23:08:49 python-server gunicorn[5858]: [2018-01-18 23:08:49 +0000] [5858] [INFO] Listening at: unix:/run/gunicorn/socket (5858)

Обратите внимание, что он действительно открылся /run/gunicorn/socket. Но ваша конфигурация nginx и модуль systemd указывают на открытие /run/gunicorn/gunicorn.socket, а это другой путь.

Моя первая мысль, что вы, вероятно, изменили путь в модуле systemd, но не запустили systemctl daemon-reload. Любые изменения в модулях systemd не вступят в силу, пока вы не запустите это (или не перезагрузитесь).

Поэтому я бы перезагрузил systemd, а затем попробовал перезапустить gunicorn.

systemctl daemon-reload
systemctl restart gunicorn.service

Конфигурация была правильной, но проблема заключалась в том, что служба Gunicorn не была перезапущена должным образом.

Поскольку gunicorn был установлен как systemd, его следует перезапустить с помощью systemctl restart gunicorn.

После этого все заработало.

Другая причина, по которой файл сокета Gunicorn не будет создан или разрешить доступ для чтения / записи, связана с блокировкой доступа SELinux. SELinux наиболее распространен в разновидностях Linux RedHat / Fedora / CentOS.

Например, если у вас запущен SELinux и демон создает файл сокета вне / run, / var / run или подкаталог ниже любого из них, то при перезапуске демона файл сокета будет иметь неправильный контекст файла. Это будет отображаться в журнале SELinux (/var/log/audit/audit.log) как ошибка, например:

type=AVC msg=audit(1569976379.346:40651): avc:  denied  { connectto } for  pid=25861 comm="httpd" path="/home/username/gunicorn.sock" 
scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=unix_stream_socket permissive=0

У вас также может возникнуть проблема с подключением веб-сервера к сокету, если разрешения «пользователя» или «группы», используемые процессом веб-сервера, не имеют доступа для чтения / записи в файл сокета. Это может означать изменение User = root или Group = root (показано в OP) в файле "Unit" демона systemd.

systemctl edit --full gunicorn.service

а затем перезагрузите файл юнита и пулемет

sudo systemctl daemon-reload
sudo systemctl restart gunicorn && systemctl status gunicorn