伺服器重啟後無法通過 Supervisor 啟動 Gunicorn
我有一個使用 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 並以非特權使用者身份執行。