Python Django中的私有设置和部署

Python Django中的私有设置和部署,python,django,security,deployment,fabric,Python,Django,Security,Deployment,Fabric,我正在使用Django并使用Ansible部署我的堆栈。最后,我使用Fabric部署我的Django项目,从GitHub中提取代码 我的问题:处理Django的settings.py文件中的私有设置(如电子邮件或S3的密码)的最佳实践是什么?目前,在重新启动应用程序服务器之前,我会在部署脚本结束时将settings_production.py文件从我的计算机传输到生产计算机。此文件包含的设置不是作为repo的一部分放入settings.py的设置 在我的settings.py的末尾,我添加了如下

我正在使用Django并使用Ansible部署我的堆栈。最后,我使用Fabric部署我的Django项目,从GitHub中提取代码

我的问题:处理Django的settings.py文件中的私有设置(如电子邮件或S3的密码)的最佳实践是什么?目前,在重新启动应用程序服务器之前,我会在部署脚本结束时将settings_production.py文件从我的计算机传输到生产计算机。此文件包含的设置不是作为repo的一部分放入settings.py的设置

在我的settings.py的末尾,我添加了如下内容

try:
    from settings_production import *
except ImportError:
    pass

有更好的方法吗?

我认为您可以创建一个
settings.py
,然后在其中执行以下操作:

try:
    from local_settings import *
except ImportError:
    pass
您必须将其放在
settings.py
的末尾。对于您的开发环境,您可以创建
local\u settings.py
,在那里您可以将所有生产配置覆盖到本地内容。通过这种方式,您可以跟踪生产设置的更改,同时尽可能保持本地设置的灵活性

不过,唯一的问题是,如果您不小心忘记覆盖
本地设置.py
中的
设置.py
,您可能最终会使用生产设置,这可能是有害的

对我来说,我只是在我的本地
~/.bashrc
中添加这个,以确保django始终使用
local\u settings.py

export DJANGO_SETTINGS_MODULE=app.settings.local_settings
编辑:

如果您不想通过repo来跟踪更改,也不想接触生产服务器,我认为没有更好的方法来复制设置文件。毕竟,您的更改必须以某种方式从计算机转移到生产中!也许你可以
rsync
这个文件,但它并不比fabric
put
好,对吧?

答案是:

您应该通过不同的设置模块管理环境之间与代码相关的差异。例如,将
debug\u工具栏
添加到本地安装的
应用程序
,同时在生产中删除它。要处理这方面的问题,与其使用旧的
try:import except importorror:…
习惯用法并在本地计算机上保留版本控制
local\u settings.py
,不如将所有设置模块保留在版本控制中,包括本地设置。然后,在
wsgi.py
manage.py
中,使用
os.environ.setdefault('DJANGO\u SETTINGS\u MODULE','myproject.conf.local')
将项目默认为使用本地设置。在dev/production中,添加一个环境变量以使用相应的设置模块(例如,
DJANGO\u settings\u module=myproject.conf.dev

当您使用12因素时,不再需要将某些设置模块置于版本控制之外,因为使用12因素时,您不会将任何密码或敏感设置直接放入设置模块。而是将它们保留在环境中,并按如下方式访问它们:

# Inside of a settings module
FOO_PASSWORD = os.environ['FOO_PASSWORD']
在这样的环境中,此设置很简单,因为您可以通过web界面输入应用程序

我推荐几乎所有的原则,特别是像,和

合理牺牲 如果您想在版本控制之外维护一个额外的设置模块,以避免在本地开发过程中使用环境变量(我不怪您),您仍然可以遵循上述原则,并在版本控制中的本地设置模块的底部添加,
尝试:从一些其他本地导入*除了:pass
。这将允许您仅在本地设置必要的覆盖设置,同时在版本控制中保留其余的本地设置(例如,本地数据库、相对静态/媒体文件路径、已安装的应用程序等),这将为您提供最好的两个方面

额外资源

我认为一个很好的例子是,除了代码外,还包括一些链接,特别是关于的链接。

所有配置都应该使用环境变量完成,因为:

  • 他们是语言不可知论者
  • 它们通常不太可能被意外地检查到源代码控制中
  • 在某些部署环境中,这是唯一可用的配置形式
  • 因此,我们的想法是使用env-var标志使您的部署完全可配置

    在开发环境中,按目录设置环境变量是一种简单的方法

    此外,您还可以使用一种机制,允许开发人员在其开发环境中使用忽略的python文件覆盖设置:

    # the manage.py file
    import os
    
    if __name__ == '__main__':
        if os.path.isfile('local_overrides.py'):
            os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'local_overrides')
        else:
            os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
        execute_from_command_line(sys.argv)
    
    和本地_覆盖文件:

    # the local_overrides.py file
    import os
    
    os.environ["DB_NAME"] = "abc"
    from settings import *
    INSTALLED_APPS.append('xyz')
    
    请注意,这与建议在末尾添加try/import的其他答案不同。在这里,本地_覆盖文件具有完全控制权,此设置有三个优点:

  • 使用
    os.environ
  • 因为它位于python文件中,所以会触发热重新加载,而其他环境变量操作工具则需要重新启动开发服务器
  • 您可以从任意数量的设置模块导入,这使得实验更加容易
  • 这符合建议,但增加了开发人员的便利性

    请注意,12factor针对每个环境推荐设置模块。我想说的是,环境和“运行模式”之间有区别,它们基本上有三种:在服务器上、在开发模式下或作为单元测试


    因此,避免将“生产”设置作为python模块,而将“服务器”作为服务于所有服务器环境的python模块,因为它们具有相似性,但是使用粒度环境变量来区分它们。

    这就是我正在做的。生产设置的setings\u local.py设置了我不想提交给git repo的值。对不起,不准确。这对我很有效。除非:如果我