Django、Gunicorn、nginxをセットアップしようとしています。
実行するためにGunicornを設定しましたが、Gunicornを使用するためのnginx設定で問題が発生しているようです。
これが私の設定です:
[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.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構成
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
は作成されていません。
これは、エラーログがどのように見えるかです。
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
ファイルが作成されるのはなぜですか?
ジャーナルエントリに示されているように、gunicorn 実際にが開いているソケットは、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ソケットファイルが作成されない、または読み取り/書き込みアクセスを許可しないもう1つの理由は、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
また、Webサーバープロセスで使用される「ユーザー」または「グループ」のアクセス許可にソケットファイルへの読み取り/書き込みのアクセス権がない場合、ソケットと通信するWebサーバーに問題がある可能性があります。これは、systemdデーモンの「Unit」ファイル内のUser = rootまたはGroup = root(OPに表示)を変更することを意味する場合があります。
systemctl edit --full gunicorn.service
ユニットファイルとgunicornをリロードします
Sudo systemctl daemon-reload
Sudo systemctl restart gunicorn && systemctl status gunicorn