0

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

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

代替

site_email=blah@site.com

我最终会得到:

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

等等...

我可以这样做,但对我来说似乎很乱。有没有其他选择?我可以删除有问题的功能并将它们构建到他们自己的应用程序中,但这似乎只是为了隐藏应用程序设置而需要做很多工作。

4

2 回答 2

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')
于 2013-09-09T14:07:46.007 回答
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 将代码部署到该服务器并将服务器指向正确的设置文件

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

于 2013-09-09T13:44:21.697 回答