【问题标题】:Can't access Environment Variables Remote Server Django无法访问环境变量远程服务器 Django
【发布时间】:2015-11-16 11:12:30
【问题描述】:

在我的远程服务器上,运行 Ubuntu 14.04,服务器配置:Django、Nginx 和 Gunicorn,我无法访问环境变量,尽管设置在正确的用户下并且服务器已重新启动。

在我的本地机器上,我设置了环境变量,django 可以在启动期间访问并且运行良好。在远程服务器上,虽然环境变量已经就位,django还是报keyerror。

# from two scoops

import os
from django.core.exceptions import ImproperlyConfigured

def get_env_variable(var_name):
    """Get the environment variable or return exception"""
    try:
        return os.environ[var_name]
    except KeyError:
        error_msg = "Set the {} environment variable".format(var_name)
        raise ImproperlyConfigured(error_msg)

在服务器上,运行 django 实例的用户与设置环境变量的用户相同。

一切都在本地 PC 上运行。在远程机器上,它没有。我已经重新启动了服务器,仍然。

当我在远程服务器的终端中运行export 时,我会得到环境变量列表,包括我自定义设置的内容。

为了确认,我进入python验证。

import os
os.environ['THE_CUSTOM_KEY']
>> returns the Key

如果 Django Python,那么我错过了哪一步,因为 python 看到了环境变量?

编辑:我在用户帐户的~/.profile 文件中设置变量。

我的 ~/.profile 和变量

# top part cut for brevity
export LOG_ECG_DB="name"
export LOG_ECG_EMAIL="email@gmail.com"
export LOG_ECG_EMAIL_PW="password"
export LOG_ECG_PW="password"
export LOG_ECG_SECRET="secret_key"

【问题讨论】:

  • Django 不是 Python,它是用 Python 编写的 Web Framework(请记住这个面试问题):)
  • 你是如何设置这些变量的?在哪里?
  • 我的 is 表达式意味着,Django 是用 Python 编写的。 @AamirAdnan因此如果python看到它,为什么python上的框架没有看到它?
  • @DanielRoseman 将变量添加到用户的~/.profile 文件中。更新了问题以包含该内容。
  • 好吧,那个配置文件是否设置了环境变量?如果不是 - 再次 - .profile 无关紧要。这仅与您 ssh 进入系统有关。 init.d 脚本由 root 启动,然后只更改用户。没有登录,没有 bash,没有配置文件或 bashrc 或其他任何东西。

标签: python django


【解决方案1】:

最终,以下是我解决问题的方法。可能会帮助某人。灵感来自两个独家新闻中的示例

简要步骤:

  • 在 ~/.env 中创建了一个 json 文件
  • 让 settings.py 在加载时读取 json 文件
  • 文件中的密钥用于填写敏感部分

创建 json 文件

我将文件放在本地和远程机器的 ~/.env 中,其中包含内容

{
"SECRET_KEY": "my_secret_key",
"DB": "db_name",
"USER": "db_user",
"USER_PW": "db_user_password",

"EMAIL": "email@email.com",
"EMAIL_PW": "password"
}

如果您的应用没有发送任何电子邮件,您可能不需要上面 sn-p 中的最后两行

读取json

在我的 settings.py(或者你可以放入一个 utils.py 文件中),我有这个 sn-p:

import json
from os.path import expanduser
from django.core.exceptions import ImproperlyConfigured

# with this, no need to hardcode
# home directory
home_directory = expanduser("~")

with open(home_directory + "/.env") as f:
    secrets = json.loads(f.read())


def get_secret(setting, secrets=secrets):
    """Get the secret variable or return explicit exception."""
    try:
        return secrets[setting]
    except KeyError:
        error_msg = "Set the {0} environment variable".format(setting)
        raise ImproperlyConfigured(error_msg)

填写作品

像这样SECRET_KEY = get_secret('SECRET_KEY')

等等..

【讨论】:

    【解决方案2】:

    这是一个 NGINX“问题”。当 NGINX 启动时,它会擦除​​除时区之外的所有环境变量。您可以使用 NGINX 配置文件手动设置环境变量。但当然,数据将在该配置文件中以明文形式存在。

    http://nginx.org/en/docs/ngx_core_module.html#env

    【讨论】:

    • 我没有看到这有帮助,因为在我的本地 PC 上,我不使用 nginx 为开发服务器提供服务,另外,使用生产设置切换到 DEBUG=False,服务器运行没有任何错误(除了未加载静态数据)。因此,我认为这与 NGINX 并不相近。我的问题是 Nginx 在请求链中扮演的角色。该问题目前正在发生 nginx 将传入请求发送到 django 进行处理。让 Nginx 将环境变量传递给 django?我怀疑我想这样做。
    • 在您的本地机器上,您是通过 NGINX 还是通过 django 的开发服务器提供服务?
    • 有机会在这里回答我的问题吗?您是否在本地通过 NGINX 提供服务?我问是因为当您通过开发服务器(典型的,用于本地测试)提供服务时,为当前用户设置的环境变量可供 Python/Django 使用。然而,当事情通过 NGNIX 服务器(它本身由 root 用户运行)运行时,NGINX 显式剥离了相关 python 进程的所有环境变量。 IE。它会解释你遇到的问题......
    • 抱歉我的回复晚了。我使用的是本地 Django 开发服务器。
    • 好的。我不确定您是否在这里对我投了反对票,但就其价值而言,我相信我实际上为您指明了正确的方向。在您的远程(生产/NGINX)配置中,NGINX 进程正在剥离您的环境变量。在您的本地(开发/开发服务器)配置中,没有发生这种剥离。因此,所有本地环境变量都“有效”,但所有远程环境变量都“不可用”。因此,相同的代码远程抛出错误(缺少键)但在本地正常工作。您的解决方法当然是有效的。但我相信我的诊断是准确的。
    猜你喜欢
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2014-05-06
    • 2022-01-12
    • 2020-03-06
    • 2013-03-17
    • 2022-06-27
    相关资源
    最近更新 更多