多站点django设置的重复设置

时间:2013-09-09 13:23:32

标签: python django heroku

我在heroku上的多个应用程序上使用相同的django代码库。我的设置是为每个单独的域使用git master分支和各个分支。然而,我正在努力寻找存储每个应用程序不同的设置变量的理想解决方案。

我正在沿着将它们存储在环境变量中的路线,为heroku上的每个应用程序分开。这将是理想的解决方案。但是,我目前只在我的应用程序中本地运行一个或两个管理功能,需要知道每个应用程序的设置。这意味着我必须在每个应用环境中存储每个应用的所有设置。例如:

而不是

site_email=blah@site.com

我最终会:

site1_email=blah@site1.com
site2_email=blah@site2.com

依旧......

我能做到这一点,但这对我来说似乎很混乱。还有其他选择吗?我可以删除有问题的功能并将它们构建到自己的应用程序中,但这似乎只是为了隐藏应用程序设置。

2 个答案:

答案 0 :(得分:3)

给出以下应用设置:

/Project/
    /app1/
    /app2/
    /project/ (the project app that gets auto created in Django 1.4+)
        /settings/
            __init__.py <- general site inspecific settings
            sitea.py <- site A's specific settings
            siteb.py <- site B's specific settings

sitea.py内放置了网站特定设置(您仍然可以使用os.environ.get()调用来使用heroku存储设置。)

# Default Django settings for project.
from project.settings import * 

DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)
MANAGERS = ADMINS
ALLOWED_HOSTS = []
MEDIA_ROOT = ''
STATIC_ROOT = ''

然后在你的heroku运行/启动脚本中做相当于(我假设你将使用gunicorn或其他一些生产django服务器)

python manage.py runserver --settings=project.settings.sitea

更新 - 示例Project/project/settings/production.py文件,注意:所有敏感信息都是从环境读取而不是从文件读取。

from project.settings import *

DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    ('Francis', 'francis@teamcolab.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': os.environ.get('MYSQL_DATABASE'),                      # Or path to database file if using sqlite3.
        # The following settings are not used with sqlite3:
        'USER': os.environ.get('MYSQL_USER'),
        'PASSWORD': os.environ.get('MYSQL_PASSWORD'),
        'HOST': os.environ.get('MYSQL_HOST'),                      # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP.
        'PORT': os.environ.get('MYSQL_PORT'),                      # Set to empty string for default.
    }
}

REDIS = {
    'HOST' : os.environ.get('REDIS_HOST'),
    'PASSWORD' : os.environ.get('REDIS_PASSWORD', None),
    'PORT' : int(os.environ.get('REDIS_PORT', 6379)),
    'DB' : int(os.environ.get('REDIS_DB', 0)),
}

WEBSOCKET_URL = os.environ.get('WEBSOCKET_URL')

# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ['XX.com','production.XX.com','www.XX.com',]

SESSION_COOKIE_DOMAIN = '.XX.com'

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = os.environ.get('MEDIA_ROOT')

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
STATIC_ROOT = os.environ.get('STATIC_ROOT')

答案 1 :(得分:0)

以下是我们在The Motley Fool上的表现。

我们有多个设置文件,每个环境一个。

我们有一个defaults.py设置文件,它是所有环境的“库存”。

我们为每个环境设置了文件:testing.pylive.py等。

这些包含默认的更改(或根据需要完全不同的设置)。

我们使用Fabric +内部部署程序将正确的设置文件部署到正确的环境中。

我们有一个像这样(简化)的fabfile:

@task @def test():
    """sets environment to test"""
    set_hosts(['testserver01.test.com', 'testserver02.test.com']) #servers to deploy to
    env.environment = 'testing'

我们有一个内部部署程序,用于编写环境的创建脚本:

def setup():
    from fabric.api import cd, env
    with cd(env.checkout):
        env.run('python create_manage_script.py %s' % env.environment)

因此,当我们部署时,会发生以下情况:

  • 用户运行fab {{environment}} deploy
  • 我们的部署人员查看设置目录,并查找与环境名称匹配的设置文件(testing / live / etc)
  • 部署者向Fabric发送适当的命令,
  • Fabric将代码部署到该服务器并将服务器指向正确的设置文件

重要的是要注意我们有三种不同的环境(开发,测试,实时),我们有三个不同的应用程序使用这三种不同的环境。