Python

伺服器重啟後無法通過 Supervisor 啟動 Gunicorn

  • March 24, 2014

我有一個使用 Nginx 和 Gunicorn 的 Django 應用程序“djngxgun”。我剛剛安裝了 Supervisor,以便我可以使用它來管理我的 Gunicorn 程序。問題是在我重新啟動伺服器後,Supervisor 沒有啟動 Gunicorn。當我通過 Supervisor(“sudo supervisorctl start djngxgun”)啟動 Gunicorn 時,我看到 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

如果我手動更改 /run(/var/run 是 /run 的符號連結),使其組所有者是“adm”並且它是組可寫的,並且 djngxgun 像這樣添加到 adm 組中,

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

…我可以毫無問題地通過主管啟動 Gunicorn。但是,如果我重新啟動伺服器,組所有權和權限將恢復為原始設置,這會導致錯誤再次發生。如您所料,如果我只是手動執行啟動腳本(“sudo /www/djngxgun/bin/start-gunicorn &”),Gunicorn 將毫無問題地啟動。

我是否錯誤地配置了 Gunicorn 和/或 Supervisor?如果我使用Supervisor,我不知道如何繞過需要寫入/var/run,但如果它由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

我想到了。解決辦法是在項目的Supervisor配置文件中設置“user = root”。文件說:“如果 supervisord 以 root 身份執行,則此 UNIX 使用者帳戶將用作執行程序的帳戶。” 因此,以這種方式設置使用者相當於我使用“sudo”手動執行腳本。

你不應該以 root 身份執行你的 gunicorn 伺服器,只要想想如果有人在你的程式碼中發現了一個漏洞可以對伺服器做任何事情。

將 pidfile 放入 /tmp 或 /var/tmp 並以非特權使用者身份執行。

引用自:https://serverfault.com/questions/579112