【问题标题】:mod_wsgi does not find environment variable in virtualenvmod_wsgi 在 vi​​rtualenv 中找不到环境变量
【发布时间】:2013-07-18 19:37:32
【问题描述】:

我在 ec2 实例的环境变量中设置了一些用户名、密码和其他配置。我已经创建了一个 virtualenv 设置并在我运行 django 服务器的地方处于活动状态。在该 django 服务器的设置文件中,我以 os.environ['variable'] 的形式访问环境变量。

在 virtualenv 之外,站点可以正常访问这些变量。当我运行 printenv 时,我看到了所有的变量和值。

但是,当我在它们上调用 os.environ 时,服务器找不到它们并因此引发关键错误。

setup = ec2 实例 - mod_wsgi - nginx - apache

更新 这通过以下列方式设置 django.wsgi 中的变量开始工作。

os.environ['SQL_PASSWORD'] = 'password'

升级到新的 ec2 硬件后,仅此一项就停止工作了。我不确定这有什么关系。

现在,最终起作用的是在 apache 配置文件中使用 SetEnv 单独设置变量。仍然不是最佳选择,因为我必须在生产机器上检查配置文件,但它解除了我的阻止。

SetEnv SQL_PASSWORD password

【问题讨论】:

  • 运行 printenv 时是否激活了 virtualenv?
  • 是的,据我所知它是活跃的。
  • shell 提示符是这样说的。
  • 你能得到任何环境变量吗?请显示触发问题的最小提取(至少显示您的导入和给出错误的行)。另外,我假设您正在运行 django,且 virtualenv 处于活动状态。
  • 可能想看看:print os.environ

标签: python django virtualenv


【解决方案1】:

我在 Ec2 上使用 nginx 和 uwsgi,并且有一个厨师食谱来构建我的服务器。为了解决这个问题,在厨师中,我的角色包含未存储在应用程序存储库中的凭据。

厨师根据角色创建的/home/user/web/site/environment 文件。

MYSQL_DATABASE=databasename
MYSQL_USER=databaseuser
MYSQL_PASSWORD=databasepassword
MYSQL_HOST=databaseip
MYSQL_PORT=3306

REDIS_HOST=redishost
REDIS_PASSWORD=redispassword
REDIS_PORT=6379
REDIS_DB=0

MEDIA_ROOT=/home/user/web/site/media
STATIC_ROOT=/home/user/web/site/static

在我的生产/暂存/等设置文件的开头,我有以下块来读取环境文件

import os, re

try:
    dirname = os.path.dirname(os.path.abspath(__file__))
    # my environment file is always in the same place relative to my project's settings file
    env_path = os.path.normpath(os.path.join(dirname, '..', '..', '..', '..', 'environment'))
    with open(env_path) as f:
        content = f.read()

        for line in content.splitlines():
            m1 = re.match(r'\A([A-Za-z_0-9]+)=(.*)\Z', line)
            if m1:
                key, val = m1.group(1), m1.group(2)
                m2 = re.match(r"\A'(.*)'\Z", val)
                if m2:
                    val = m2.group(1)
                m3 = re.match(r'\A"(.*)"\Z', val)
                if m3:
                    val = re.sub(r'\\(.)', r'\1', m3.group(1))
                os.environ.setdefault(key, val)
except IOError:
    pass

瞧,设置在单独管理的存储库(厨师)中进行源代码控制并加载到应用程序中。这可能不是最好的方式,但它是相当安全的 b/c 如何锁定厨师存储库和目标服务器的权限并且易于部署。

【讨论】:

  • 似乎可行,但应该有更好的方法来做到这一点。当我使用 python 检查它们时,我在环境中设置了所有密码。为什么 mod_wsgi 不加载那些?
  • 他们在哪个用户的环境中?你的 ssh 用户,还是你的 apache 用户? Apache 作为 apache 运行(可能?我是 uwsgi 人)
  • 哪个用户的 .bash_profile? apache 我相信它以自己的名为 apache 的用户身份运行。如果您在 ssh 用户的 .bash_profile 中设置它,那么它不会被加载到您的应用程序的环境中。 stackoverflow.com/questions/2509334/…
  • 是同一个用户。也许我需要这样做:httpd.apache.org/docs/2.2/mod/mod_env.html#passenv。但是,我不确定应该在哪个文件中传递环境变量: PassEnv MY_VAR
  • 这听起来很有希望。当它进入 apache 的本质时,我无能为力 - 这不是我经常遇到的事情。
猜你喜欢
  • 2017-03-26
  • 2016-04-03
  • 1970-01-01
  • 2021-02-21
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 2018-12-27
  • 2016-07-11
相关资源
最近更新 更多