Nel*_*luk 15 apache django ubuntu
我正在尝试将Django的密钥和DB传递给环境变量,正如广泛建议的那样,因此我可以在本地/生产服务器之间使用相同的代码库.
我遇到的问题是正确设置然后在运行Apache + mod_wsgi的生产服务器上读取环境变量.
我的用户配置文件中设置的Vars不可用,因为Apache不是以该用户身份运行的.虚拟主机文件中设置的SetEnv变量不可用,因为范围有所不同.
我读过一对夫妇1,2 SO答案,从而导致这个博客用的解决方案.
我无法弄清楚如何将解决方案应用于使用wsgi.py文件的当前版本的Django,如下所示:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
我如何将该博客解决方案应用于wsgi.py文件,或者是否有更好的地方存储Django可以获取的env-vars?
Abe*_*ler 22
如果其他人对格雷厄姆的回答感到沮丧,那么这个解决方案实际上适用于原始问题.我个人发现从Apache设置环境变量是非常有用和实用的,特别是因为我配置了自己的托管环境,可以做任何我想做的事情.
wsgi.py(在Django 1.5.4中测试)
from django.core.handlers.wsgi import WSGIHandler
class WSGIEnvironment(WSGIHandler):
    def __call__(self, environ, start_response):
        os.environ['SETTINGS_CONFIG'] = environ['SETTINGS_CONFIG']
        return super(WSGIEnvironment, self).__call__(environ, start_response)
application = WSGIEnvironment()
小记,你失去了面向未来的方法django.core.wsgi.get_wsgi_application,目前只返回WSGIHandler().如果该WSGIHandler.__call__方法已更新并且您也更新了Django,则可能必须WSGIEnvironment在参数更改时更新该类.我认为这是一个非常小的罚款,以支付方便.
Gra*_*ton 10
FWIW.依赖环境变量进行细粒度配置设置通常不是一个好主意.这是因为并非所有WSGI托管环境或商业PaaS产品都支持该概念.使用环境变量进行细粒度设置还可以有效地将您锁定到特定的PaaS产品中,您可以直接在代码中直接嵌入查找特定命名的环境变量,其中该环境变量的命名约定特定于该托管服务.因此,尽管某些服务推动了环境变量的使用,但要始终注意依赖于环境变量,因为它会降低WSGI应用程序的可移植性,并使部署机制之间的移动变得更加困难.
总而言之,您提到的博客文章通常不会有所帮助.这是因为它正在使用令人讨厌的技巧,即根据在Apache中使用SetEnv设置的每个请求WSGI环境设置在每个请求上设置进程环境变量.如果环境变量的值可能因URL上下文而异,则可能会在多线程配置中导致各种问题.对于Django的情况,它没有用,因为Django设置模块通常会在处理任何请求之前导入,这意味着环境变量在所需的时间不可用.
整个部署配置区域迫切需要一种更好的处理方式,但坦率地说,它主要是一个失败的原因,因为托管服务不会改变以适应更好的WSGI部署策略.他们已经完成了他们的工作,让他们的客户已经锁定他们已经完成的工作方式,并且即使存在更好的方法,也不会为自己创造工作并改变事物.
无论如何,"计算机科学中的所有问题都可以通过另一层次的间接解决".(http://en.wikipedia.org/wiki/Indirection)这就是你在这里可以做的.
没有应用程序查找环境变量.让它导入特定于部署的Python配置模块,其中包含使用API获取配置设置的方法.该配置模块将基于部署机制实现获取实际设置的不同方式.在某些情况下,它可以从环境变量中获取值.对于其他例如Apache/mod_wsgi,值可以在该配置模块中,或者从单独的配置文件中读取,该文件可以是ini,json或yaml格式.在提供API时,它还可以将配置设置的名称映射到不同PaaS产品使用的不同名称.
此配置模块不需要是应用程序代码的一部分,但可以手动放入目标系统上的"/ etc /"子目录中.然后,您需要设置Python模块搜索路径,以便您的应用程序可以看到它.作为更广泛的WSGI部署标准的一部分,整个系统可以做得相当优雅,但正如我所说,当现有的PaaS产品极不可能改变使用这样的标准时,很少有动力去创造这样的事情. .
这是一种替代解决方案,可以满足未来需求get_wsgi_application.它甚至允许您设置要在Django初始化中使用的环境变量.
# in wsgi.py
KEYS_TO_LOAD = [
    # A list of the keys you'd like to load from the WSGI environ
    # into os.environ
]
def loading_app(wsgi_environ, start_response):
    global real_app
    import os
    for key in KEYS_TO_LOAD:
        try:
            os.environ[key] = wsgi_environ[key]
        except KeyError:
            # The WSGI environment doesn't have the key
            pass
    from django.core.wsgi import get_wsgi_application
    real_app = get_wsgi_application()
    return real_app(wsgi_environ, start_response)
real_app = loading_app
application = lambda env, start: real_app(env, start)
我不是100%清楚如何mod_wsgi管理它的进程,但我认为它不会经常重新加载WSGI应用程序.如果是这样,初始化Django的性能损失只会在第一个请求中发生一次.
或者,如果在初始化Django之前不需要设置环境变量,则可以使用以下命令:
# in wsgi.py
KEYS_TO_LOAD = [
    # A list of the keys you'd like to load from the WSGI environ
    # into os.environ
]
from django.core.wsgi import get_wsgi_application
django_app = get_wsgi_application()
def loading_app(wsgi_environ, start_response):
    global real_app
    import os
    for key in KEYS_TO_LOAD:
        try:
            os.environ[key] = wsgi_environ[key]
        except KeyError:
            # The WSGI environment doesn't have the key
            pass
    real_app = django_app
    return real_app(wsgi_environ, start_response)
real_app = loading_app
application = lambda env, start: real_app(env, start)
| 归档时间: | 
 | 
| 查看次数: | 6269 次 | 
| 最近记录: |