我有一个在Gunicorn上运行的Django应用程序,由SuperibleD管理,由Ansible管理。
我希望Django从环境中读取DJANGO_SECRET_KEY
变量,因为我不想将我的密钥存储在配置文件或VCS中。为此,我在settings.py
:
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
看Supervisor docs它说:
注意,子进程将继承用于启动“supervisord”的shell的环境变量,除了在此处重写的那些。请参阅子流程环境。
这是我的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
但是,当我在shell中设置变量并重新启动Supervisor服务时,我的应用程序无法启动,找不到有关找不到变量的错误:
$ DJANGO_SECRET_KEY=XXX supervisorctl restart gunicorn
gunicorn: ERROR (not running)
gunicorn: ERROR (spawn error)
查看Supervisor错误日志:
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)
我的问题是如何让Supervisor将环境变量“传递”给它的子进程?
答案 0 :(得分: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
答案 1 :(得分:0)
好吧我自己弄清楚了。原来ansible有一个名为Vault的功能,它正好用于这类工作 - 加密密钥。
现在我将已保存的密钥添加到ansible的host_vars中,请参阅: Vault: single encrypted variable和Inventory: Splitting out host and group specific data。
我在ansible playbook中添加了一个任务,将密钥文件从ansible vault复制到服务器:
<Style TargetType="ListViewItem">
<Setter Property="Foreground" Value ="HotPink"/>
</Style>
让Django从该文件中读取秘密:
@Retryable(
value = { Exception.class },
maxAttempts = 2,
backoff=@Backoff(delay = 2000))
@Async
@EventListener
如果有人有更简单/更好的解决方案,请发布,我会接受它作为答案。