2017-08-27 148 views
0

我有一個運行在Gunicorn上的Django應用程序,由Ansible管理的SupervisorD管理。如何將shell環境變量傳遞給Supervisor程序?

我想讓Django從環境中讀取DJANGO_SECRET_KEY變量,因爲我不想將我的密鑰存儲在配置文件或VCS中。對於我讀的環境中我settings.py關鍵:

SECRET_KEY = os.environ['DJANGO_SECRET_KEY'] 

看着Supervisor docs它說:

注意子進程將繼承用於啓動「外殼的環境變量supervisord「除了這裏覆蓋的那些。請參閱子流程環境。

這裏是我的supervisor.conf

[program:gunicorn] 
command=/.../.virtualenvs/homepage/bin/gunicorn homepage.wsgi -w 1 --bind localhost:8001 --pid /tmp/gunicorn.pid 
directory=/.../http/homepage 

當我設置的變量,然後從shell中運行Gunicorn命令,它啓動就好了:

$ DJANGO_SECRET_KEY=XXX /.../.virtualenvs/homepage/bin/gunicorn homepage.wsgi -w 1 --bind localhost:8001 --pid /tmp/gunicorn.pid 

然而,當我設置的變量該外殼並重新啓動Supervisor服務我的應用程序無法啓動有關未找到變量的錯誤:

$ DJANGO_SECRET_KEY=XXX supervisorctl restart gunicorn 
gunicorn: ERROR (not running) 
gunicorn: ERROR (spawn error) 

看着監事錯誤日誌:

File "/.../http/homepage/homepage/settings.py", line 21, in <module> 
    SECRET_KEY = os.environ['DJANGO_SECRET_KEY'] 
    File "/.../.virtualenvs/homepage/lib/python2.7/UserDict.py", line 40, in __getitem__ 
    raise KeyError(key) 
KeyError: 'DJANGO_SECRET_KEY' 
[2017-08-27 08:22:09 +0000] [19353] [INFO] Worker exiting (pid: 19353) 
[2017-08-27 08:22:09 +0000] [19349] [INFO] Shutting down: Master 
[2017-08-27 08:22:09 +0000] [19349] [INFO] Reason: Worker failed to boot. 

我也曾嘗試重新啓動監督員服務,但同樣的錯誤出現:

$ DJANGO_SECRET_KEY=XXX systemctl restart supervisor 
... 
INFO exited: gunicorn (exit status 3; not expected) 

我的問題是如何讓我主管爲「通」環境變量是它的子進程?

+1

這完全是錯誤的方式。 Supervisor不在您的用戶標識下運行。您應該在supervisor配置中設置變量,而不是相反。 –

+0

@DanielRoseman我在VCS中有我的主管配置,所以我不能把我的密鑰放在裏面。 –

+1

閱讀'DJANGO_SECRET_KEY'環境變量與監督員conf無關。不知道你是如何做的,但你可以使用'os.environ.get('DJANGO_SECRET_KEY')'在我們的django設置文件中賦值。你也可以使用像'django-environ'這樣的軟件包。 – demonno

回答

0

創建類似於此的可執行文件並嘗試手動啓動它。 即創建下面的文件和複製腳本/home/user/start_django.sh

您需要填寫DJANGODIR並根據您的情況進行其他調整。另外,您可能需要相應地調整權限。

#!/bin/bash 

DJANGODIR=/.../.../.. 
ENVBIN=/.../.virtualenvs/homepage/bin/bin 

# Activate the virtual environment 
cd $DJANGODIR 
source $ENVBIN/activate 

DJANGO_SECRET_KEY=XXX 
#define other env variables if you need 

# Start your Django 
exec gunicorn homepage.wsgi -w 1 --bind localhost:8001 --pid /tmp/gunicorn.pid 

如果它手動啓動,那麼只需在你的conf中使用這個文件。

[program:django_project] 
command = /home/user/start_django.sh 
user = {your user} 
stdout_logfile = /var/log/django.log 
redirect_stderr = true 
# you can also try to define enviroment variables in this conf 
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8,DJANGO_SECRET_KEY=XXX 

引用可能會有所幫助,

+0

嗯,我如何管理'start_django.sh'?由於它包含密鑰,因此我無法將它放入版本控制中。我可以輕鬆地將我的密鑰放在'settings.py'或'supervisor.conf'中,但問題是這些文件也受版本控制。 –

+0

我認爲可以在建議的bash腳本中添加一行,它從外部文件中導出env變量(未受版本控制的跟蹤)。但我個人更喜歡使用'django-environ',它可以配置爲從'.env'文件讀取所有變量。 – demonno

0

確定了它自己。結果證明有一個稱爲Vault的功能,用於完成這類作業 - 加密密鑰。

現在我將拱形密鑰添加到ansible的host_vars中,請參閱: Vault: single encrypted variableInventory: Splitting out host and group specific data

我添加了一個任務,我ansible劇本從ansible庫密鑰文件複製到服務器:

- name: copy django secret key to server 
    copy: content="{{ django_secret_key }}" dest=/.../http/homepage/deploy/django_secret_key.txt mode=0600 

並取得Django的讀取該文件中的祕密:

with open(os.path.join(BASE_DIR, 'deploy', 'django_secret_key.txt')) as secret_key_file: 
    SECRET_KEY = secret_key_file.read().strip() 

如果有人有一個更簡單/更好的解決方案,請發佈它,我會接受它作爲答案。

相關問題