我试图在Elastic Beanstalk上设置Django / DRF应用程序,无论出于何种原因,Django都无法看到所需的环境变量。当我登录时,通过使用
,我可以很好地看到它们$ eb ssh
$ cat /opt/python/current/env
我也可以看到它们,除了涉及RDS的相对敏感的,只需使用$eb printenv
。
所有这些似乎都已设置并正常运行。但是,Django喜欢在启动时立即读取环境,而环境变量似乎还没有设置好。我在[{1}}中简单地插入print(os.environ)
进行了实验,当我这样做时,我发现了一大堆我不需要的环境变量(即settings.py
),而不是我自己设定的那些,如'SUPERVISOR_GROUP_NAME': 'httpd'
。
我已经更改了代码,以便在加载设置时报告缺少特定的环境变量,并且从最近的运行中,它生成了这个:
DJ_SECRET_KEY
同样,这些变量在设置中设置,并显示EB给我的任何其他报告工具。他们只是没有及时设置Django在启动和读取[Wed Nov 23 15:56:38.164153 2016] [:error] [pid 15708] DJ_SECRET_KEY not in environment; falling back to hardcoded value.
[Wed Nov 23 15:56:38.189717 2016] [:error] [pid 15708] RDS_DB_NAME not in environment; falling back to sqlite
[Wed Nov 23 15:56:38.189751 2016] [:error] [pid 15708] AWS_STORAGE_BUCKET_NAME not in environment; falling back to local static storage.
时读取它们。
This看起来非常接近这个问题,但它并不完全相同:我知道在ssh进入eb实例时如何查看/加载环境变量到shell中;当我需要它们用于实际项目时,它们才会显示出来。
This几乎就是我所拥有的问题,但接受正确的答案对我来说毫无意义,并且最高投票的答案并不适用;那些文件已经在git中了。
我应该如何配置以便Django可以看到环境变量?
答案 0 :(得分:3)
鉴于EB将所有这些环境变量作为bash脚本存储在规范位置,我最终只是让bash执行脚本,并从解析后的结果中更新环境。
我与/*
* Look the appearance up without checking first if it exists because
* almost every TextView has one and it greatly simplifies the logic
* to be able to parse the appearance first and then let specific tags
* for this View override it.
*/
TypedArray a = theme.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes);
TypedArray appearance = null;
int ap = a.getResourceId(
com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
a.recycle();
if (ap != -1) {
appearance = theme.obtainStyledAttributes(
ap, com.android.internal.R.styleable.TextAppearance);
}
if (appearance != null) {
int n = appearance.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = appearance.getIndex(i);
switch (attr) {
case com.android.internal.R.styleable.TextAppearance_textColorHighlight:
textColorHighlight = appearance.getColor(attr, textColorHighlight);
break;
case com.android.internal.R.styleable.TextAppearance_textColor:
textColor = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textColorHint:
textColorHint = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textColorLink:
textColorLink = appearance.getColorStateList(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textSize:
textSize = appearance.getDimensionPixelSize(attr, textSize);
break;
case com.android.internal.R.styleable.TextAppearance_typeface:
typefaceIndex = appearance.getInt(attr, -1);
break;
case com.android.internal.R.styleable.TextAppearance_fontFamily:
fontFamily = appearance.getString(attr);
break;
case com.android.internal.R.styleable.TextAppearance_textStyle:
styleIndex = appearance.getInt(attr, -1);
break;
case com.android.internal.R.styleable.TextAppearance_textAllCaps:
allCaps = appearance.getBoolean(attr, false);
break;
case com.android.internal.R.styleable.TextAppearance_shadowColor:
shadowcolor = appearance.getInt(attr, 0);
break;
case com.android.internal.R.styleable.TextAppearance_shadowDx:
dx = appearance.getFloat(attr, 0);
break;
case com.android.internal.R.styleable.TextAppearance_shadowDy:
dy = appearance.getFloat(attr, 0);
break;
case com.android.internal.R.styleable.TextAppearance_shadowRadius:
r = appearance.getFloat(attr, 0);
break;
case com.android.internal.R.styleable.TextAppearance_elegantTextHeight:
elegant = appearance.getBoolean(attr, false);
break;
case com.android.internal.R.styleable.TextAppearance_letterSpacing:
letterSpacing = appearance.getFloat(attr, 0);
break;
case com.android.internal.R.styleable.TextAppearance_fontFeatureSettings:
fontFeatureSettings = appearance.getString(attr);
break;
}
}
appearance.recycle();
}
并行创建了文件get_eb_env.py
。其主要内容:
settings.py
然后,我只是导入并致电import os
import subprocess
ENV_PATH = '/opt/python/current/env'
def patch_environment(path=ENV_PATH):
"Patch the current environment, os.environ, with the contents of the specified environment file."
# mostly pulled from a very useful snippet: http://stackoverflow.com/a/3505826/504550
command = ['bash', '-c', 'source {path} && env'.format(path=path)]
proc = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)
proc_stdout, _ = proc.communicate(timeout=5)
# proc_stdout is just a big string, not a file-like object
# we can't iterate directly over its lines.
for line in proc_stdout.splitlines():
(key, _, value) = line.partition("=")
os.environ[key] = value
的{{1}}附近的patch_environment()
。
答案 1 :(得分:1)
我解决了修改密钥的问题&#34; DJANGO_AWS_SECRET_ACCESS_KEY&#34;因为DJANGO生成带引号(`)的键并将其解释为命令。
答案 2 :(得分:0)
这不完全是你所要求的,但我希望无论如何这都能解决你的问题。
我在设置中使用了很多环境变量。我认为Elastic Beanstalk在运行容器命令之前将所有内容设置为一次,并且变量不可用,这就是为什么您的日志记录显示为空。但那时你真的需要变量吗?
您无法在local_settings.py中放置所需的任何本地开发设置,并使其不受版本控制。
我们这样使用它们。
if 'DB_HOST' in os.environ:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'ebdb',
'USER': 'ebroot',
'PASSWORD': 'ebpassword',
'HOST': os.environ['DB_HOST'],
'PORT': '3306',
}
}
try:
from local_settings import *
except ImportError:
pass
运行container_commands时它们也可用:
container_commands:
01_do_something:
command: "do_something_script_{$PARAM1}.sh"