当部署到Elastic Beanstalk时,Django没有看到环境变量

时间:2016-11-23 16:43:38

标签: python django amazon-web-services django-rest-framework elastic-beanstalk

我试图在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可以看到环境变量?

3 个答案:

答案 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"