Как настроить несколько Django Apps с помощью Supervisor (включая Gunicorn и Nginx)? bind() to [::]:8090 failed (98: Address already in use)
Я уже развернул приложение Django/Wagtail, используя Supervisor, Gunicorn и Nginx (на Debian Buster), поэтому я могу добраться до него с помощью http://xx.xxx.xxx.xxx:8090.
/etc/nginx/sites-available/cms
server {
server_name xx.xxx.xxx.xxx;
listen 8090;
listen [::]:8090 ipv6only=on;
error_log /home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/var/log/gunicorn-error.log;
access_log /home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/var/log/gunicorn-access.log;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/www.mysite.com/www/my-site/cms/admin_panel;
}
location /media/ {
root /home/www.mysite.com/www/my-site/cms/admin_panel;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/run/gunicorn.sock;
}
}
/etc/supervisor/conf.d/guni-mysite-admin.conf
[program:guni-mysite-admin]
command=/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/bin/gunicorn admin_panel.wsgi:application --config /home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/etc/gunicorn/conf.py
user=www.mysite.com
autostart=true
autorestart=true
/etc/supervisor/conf.d/nginx-mysite-admin.conf
[program:nginx-mysite-admin]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stderr_logfile=/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/var/log/nginx-error.log
stdout_logfile=/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/var/log/nginx-access.log
stderr_logfile_maxbytes=2MB
stdout_logfile_maxbytes=2MB
/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/etc/gunicorn/conf.py
workers = 3
keepalive = 5
user = 'www.mysite.com'
proc_name = 'admin_panel'
loglevel = 'error'
errorlog = '/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/var/log/gunicorn-error.log'
accesslog = '/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/var/log/gunicorn-access.log'
bind = 'unix:/home/www.mysite.com/.local/share/virtualenvs/cms-WqsZ9qOt/run/gunicorn.sock'
raw_env = ['DJANGO_SETTINGS_MODULE=admin_panel.settings.production']
pythonpath = '/home/www.mysite.com/www/mysite/cms/admin_panel'
Теперь я добавил еще 2 приложения Django Apps тем же способом. К сожалению, Supervisor не может их запустить. Иногда запускается 1 из 3, но большую часть времени ни одно из них не работает. В случае работы создается 3 процесса (не знаю, так ли это должно быть).
$ sudo lsof -i:8090
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 3631 root 16u IPv4 961301189 0t0 TCP *:8090 (LISTEN)
nginx 3631 root 17u IPv6 961301190 0t0 TCP *:8090 (LISTEN)
nginx 3632 www-data 16u IPv4 961301189 0t0 TCP *:8090 (LISTEN)
nginx 3632 www-data 17u IPv6 961301190 0t0 TCP *:8090 (LISTEN)
nginx 3633 www-data 16u IPv4 961301189 0t0 TCP *:8090 (LISTEN)
nginx 3633 www-data 17u IPv6 961301190 0t0 TCP *:8090 (LISTEN)
Журнал ошибок Nginx выдает 98: Address already in use, даже на порту 81 (взял его как порт по умолчанию, потому что Apache использует 80), который не используется. Apache не должен быть проблемой, потому что это не работает, даже когда Apache выключен.
/var/log/nginx/error.log
...
2021/08/06 12:41:54 [emerg] 24927#24927: bind() to [::]:4020 failed (98: Address already in use)
2021/08/06 12:41:54 [emerg] 24927#24927: bind() to [::]:8090 failed (98: Address already in use)
2021/08/06 12:41:54 [emerg] 24927#24927: bind() to [::]:81 failed (98: Address already in use)
2021/08/06 12:41:54 [emerg] 24927#24927: bind() to [::]:8070 failed (98: Address already in use)
2021/08/06 12:41:54 [emerg] 24927#24927: bind() to [::]:8080 failed (98: Address already in use)
2021/08/06 12:41:54 [emerg] 24927#24927: bind() to [::]:4030 failed (98: Address already in use)
2021/08/06 12:41:54 [emerg] 24928#24928: still could not bind()
...
Решение
С помощью следующей настройки я успешно запускаю двух клиентов, три API, Wordpress и Php Analytics Site без конфликтов: Например, один из API имеет Apache2 HTTP Server в качестве прокси (прослушивающий порт 80), который перенаправляется на Nginx (не контролируемый Supervisor, что на самом деле является решением!) Gunicorn контролируется Supervisor. Поэтому я просто перестал использовать Supervisor для процессов Nginx. Это может работать без использования ipv6only, но я хочу использовать его для лучшего контроля над привязкой IP. Так что меня это устраивает.