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

Не удается запустить Gunicorn через Supervisor после перезагрузки сервера

У меня есть приложение Django djngxgun, которое использует Nginx и Gunicorn. Я только что установил Supervisor, чтобы использовать его для управления своими процессами Gunicorn. Проблема в том, что Supervisor не запускает Gunicorn после перезагрузки сервера. Когда я запускаю Gunicorn через Supervisor («sudo supervisorctl start djngxgun»), я вижу следующую ошибку, повторяющуюся в моем файле Gunicorn error.log:

2014-02-28 15:36:47 [4753] [INFO] Starting gunicorn 18.0
Traceback (most recent call last):
  File "/home/djngxgun/venv/djngxgun/bin/gunicorn", line 9, in <module>
    load_entry_point('gunicorn==18.0', 'console_scripts', 'gunicorn')()
  File "/home/djngxgun/venv/djngxgun/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 71, in run
    WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
  File "/home/djngxgun/venv/djngxgun/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 143, in run
    Arbiter(self).run()
  File "/home/djngxgun/venv/djngxgun/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 172, in run
    self.start()
  File "/home/djngxgun/venv/djngxgun/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 124, in start
    self.pidfile.create(self.pid)
  File "/home/djngxgun/venv/djngxgun/local/lib/python2.7/site-packages/gunicorn/pidfile.py", line 38, in create
    fd, fname = tempfile.mkstemp(dir=fdir)
  File "/usr/lib/python2.7/tempfile.py", line 300, in mkstemp
    return _mkstemp_inner(dir, prefix, suffix, flags)
  File "/usr/lib/python2.7/tempfile.py", line 235, in _mkstemp_inner
    fd = _os.open(file, flags, 0600)
OSError: [Errno 13] Permission denied: '/var/run/tmpcda84p'

Похоже, проблема в том, что учетной записи djngxgun необходимо создать временный файл в / var / run, но разрешения этого каталога мешают этому:

drwxr-xr-x 14 root root 640 Feb 28 15:36 /run

Если я вручную изменяю / запускаю (/ var / run - это символическая ссылка на / run), так что владельцем группы является «adm», и он доступен для записи в группу, а djngxgun добавляется в группу adm, как это,

drwxrwxr-x 14 root adm 640 Feb 28 15:36 /run

... Я могу без проблем запустить Gunicorn через Supervisor. Однако, если я перезагружаю свой сервер, права собственности и разрешения группы возвращаются к исходным настройкам, что приводит к повторному возникновению ошибки. Как и следовало ожидать, если я просто запустил сценарий запуска вручную («sudo / www / djngxgun / bin / start-gunicorn &»), Gunicorn запустится без проблем.

Я неправильно настраиваю Gunicorn и / или Supervisor? Я не понимаю, как мне обойтись без необходимости писать в / var / run, если я использую Supervisor, но я не могу, если он принадлежит root. Я не думаю, что хочу запускать свое приложение через пользователя root. Я не видел никаких настроек Gunicorn или Supervisor, которые могли бы решить эту проблему. Есть другой способ сделать это?

Спасибо.

Это мой сценарий запуска Gunicorn:

#!/bin/bash
NAME=djngxgun
DJANGODIR=/www/djngxgun
USER=$NAME
GROUP=$NAME
NUM_WORKERS=3
DJANGO_SETTINGS_MODULE=conf.prod
DJANGO_WSGI_MODULE=conf.wsgi

WORKON_HOME=/home/${USER}/venv
source `which virtualenvwrapper.sh`
workon $NAME
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH

echo "Starting $NAME as `whoami`"
exec gunicorn $DJANGO_WSGI_MODULE:application \
  --name $NAME \
  --workers $NUM_WORKERS \
  --user=$USER \
  --group=$GROUP \
  --bind=127.0.0.1:8000 \
  --pid /var/run/gunicorn.pid \
  --access-logfile /var/log/gunicorn/access.log \
  --error-logfile /var/log/gunicorn/error.log \
  --log-level=debug

Это мой файл конфигурации супервизора "/etc/supervisor/conf.d/djngxgun.conf"

[program:djngxgun]
command = /www/djngxgun/bin/start-gunicorn
user=djngxgun
stdout_logfile = /var/log/gunicorn/supervisor.log
redirect_stderr = true

Вы не должны запускать свой сервер Gunicorn как root, просто подумайте, если кто-то обнаружит эксплойт в вашем коде, может что-нибудь сделать с сервером.

Поместите pid-файл в / tmp или / var / tmp и запустите как непривилегированный пользователь.

Я понял. Решение состоит в том, чтобы установить «user = root» в файле конфигурации Supervisor проекта. В документация говорит: «Если supervisord запускается от имени пользователя root, эта учетная запись пользователя UNIX будет использоваться в качестве учетной записи, которая запускает программу». Таким образом, такой способ настройки пользователя эквивалентен запуску скрипта вручную с помощью «sudo».