Django 如何将shell环境变量传递给Supervisor程序?

Django 如何将shell环境变量传递给Supervisor程序?,django,ansible,environment-variables,supervisord,secret-key,Django,Ansible,Environment Variables,Supervisord,Secret Key,我有一个在Gunicorn上运行的Django应用程序,由Ansible管理的SupervisorD管理 我希望Django从环境中读取Django_SECRET_KEY变量,因为我不想将我的密钥存储在配置文件或VCS中。为此,我从我的设置.py中的环境中读取密钥: SECRET\u KEY=os.environ['DJANGO\u SECRET\u KEY'] 看着它说: 注意子流程将继承用于启动“supervisord”的shell的环境变量,此处覆盖的除外。请参阅子流程环境 这是我的su

我有一个在Gunicorn上运行的Django应用程序,由Ansible管理的SupervisorD管理

我希望Django从环境中读取
Django_SECRET_KEY
变量,因为我不想将我的密钥存储在配置文件或VCS中。为此,我从我的
设置.py中的环境中读取密钥:

SECRET\u KEY=os.environ['DJANGO\u SECRET\u KEY']
看着它说:

注意子流程将继承用于启动“supervisord”的shell的环境变量,此处覆盖的除外。请参阅子流程环境

这是我的
supervisor.conf

[程序:gunicorn]
command=/…/.virtualenvs/homepage/bin/gunicorn homepage.wsgi-w 1--绑定本地主机:8001--pid/tmp/gunicorn.pid
目录=/…/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\u SECRET\u KEY=XXX监管者重新启动gunicorn
gunicorn:错误(未运行)
gunicorn:错误(生成错误)
查看主管错误日志:

文件“/…/http/homepage/homepage/settings.py”,第21行,在
SECRET\u KEY=os.environ['DJANGO\u SECRET\u KEY']
文件“/…/.virtualenvs/homepage/lib/python2.7/UserDict.py”,第40行,在__
升起钥匙错误(钥匙)
KeyError:“DJANGO\u密钥”
[2017-08-27 08:22:09+0000][19353][INFO]工人退出(pid:19353)
[2017-08-27 08:22:09+0000][19349][INFO]关闭:主机
[2017-08-27 08:22:09+0000][19349][INFO]原因:工作进程无法启动。
我还尝试重新启动supervisor服务,但出现了相同的错误:

$DJANGO\u SECRET\u KEY=XXX系统控制重启管理器
...
退出信息:gunicorn(退出状态3;不期望)

我的问题是如何让主管将环境变量“传递”到其子进程?

创建类似的可执行文件,并尝试手动启动它。 i、 e在下面创建文件并复制脚本
/home/user/start\u 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
可能有用的参考资料,

    • 好的,我自己想出来的。原来ansible有一个叫做Vault的功能,它正是用于加密密钥这类工作的

      现在,我将保险库密钥添加到ansible的主机变量中,请参见: 和

      我在ansible playbook中添加了一项任务,将密钥文件从ansible vault复制到服务器:

      让Django从那个文件里读到了秘密:

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

      如果有人有更简单/更好的解决方案,请发布,我会接受它作为答案。

      这完全是错误的。Supervisor不在您的用户ID下运行。您应该在Supervisor配置中设置变量,而不是相反。@DanielRoseman我的Supervisor配置在VCS中,因此,我无法将我的密钥放入其中。读取
      DJANGO\u secret\u key
      Environment变量与supervisor conf无关。不确定如何操作,但可以使用
      os.environ.get('DJANGO\u secret\u key')
      在DJANGO设置文件中赋值。您也可以使用类似于
      django-environ
      的包来实现此目的。@demonno我已经在django的
      settings.py
      中有了
      os.environ.get('django\u SECRET\u KEY')
      。问题是当Gunicorn进程从Supervisor.Hmm开始时,没有设置此变量,那么如何管理
      start\u django.sh
      ?我无法将其置于版本控制中,因为它包含密钥。我可以很容易地将我的密钥放入
      settings.py
      supervisor.conf
      ,但问题是这些文件也在版本控制下。我认为可以在建议的bash脚本中添加一行,从外部文件导出env变量(不受版本控制跟踪)。但我个人更喜欢使用
      django environ
      ,它可以配置为从
      .env
      文件中读取所有变量。
      with open(os.path.join(BASE_DIR, 'deploy', 'django_secret_key.txt')) as secret_key_file:
          SECRET_KEY = secret_key_file.read().strip()