Элегантно обрабатывать специфичные для сайта настройки / настройки в svn / hg / git / etc? - PullRequest
24 голосов
/ 10 сентября 2009

Я искал лучший способ справиться с настройками сайта (в данном случае это файл django settings.py).

Структура и поля settings.py довольно непротиворечивы, но значения различаются в зависимости от среды разработчика, среды интеграции, контроля качества, тестирования и производства.

Какой элегантный способ контроля источника настроек при одновременном разрешении изменений между различными блоками?

Я также обеспокоен наличием конфиденциальных данных (например, паролей базы данных) в системе контроля версий, но я хочу автоматического развертывания.

Примеры того, что мы использовали:

  • settings.py устанавливает общие значения, затем загружает вторичный файл настроек на основе имени хоста или имени пользователя.

  • вставка значений в файл settings.py с помощью сценария развертывания. Но это просто переносит проблему на управление сценариями развертывания вместо сценария settings.py.

У кого-нибудь есть особенно элегантный подход?

Ответы [ 4 ]

18 голосов
/ 10 сентября 2009

Создайте основной файл settings.py, который должен включать это:

# Pull in hostname-based changes.
import socket
HOSTNAME = socket.gethostname().lower().split('.')[0].replace('-','')

try:
    exec "from myproject.settings.host_%s import *" % HOSTNAME
except ImportError:
    pass

# Pull in the local changes.
try:
    from myproject.settings.local import *
except ImportError:
    pass

Теперь вы создаете новый файл настроек для каждого нужного вам имени хоста. Но они действительно маленькие. Каждый файл вашего производственного сервера содержит:

from myproject.settings.production import *

и ваши промежуточные серверы имеют:

from myproject.settings.staging import *

Теперь вы можете создать файл production.py с производственными переопределениями для настроек, staging.py и так далее. Вы можете создавать новые файлы для каждой роли, которую играет сервер.

Наконец, вы можете создать файл local.py на любом компьютере (включая компьютеры разработчиков) с локальными переопределениями и пометить этот файл как игнорируемый системой контроля версий, чтобы изменения не регистрировались.

Мы использовали эту структуру годами, она работает очень хорошо.

4 голосов
/ 11 сентября 2009

+ 1 для ответа Неда, но хочу упомянуть небольшое изменение.

Я вижу настройки Django как попадающие в 2 области: проект и экземпляр.

Настройки проекта являются общими для всех экземпляров (dev, тестирования, производства, нескольких сайтов в производстве), а настройки экземпляров являются локальными только для этого конкретного экземпляра сервера.

Настройки проекта - это такие вещи, как INSTALLED_APPS (хотя локальные настройки могут также включать это для добавления таких вещей, как панель отладки django для разработчиков), MIDDLEWARE_CLASSES и TEMPLATE_LOADERS. Настройки экземпляра - это настройки базы данных, MEDIA_URL и т. Д.

Настройки проекта входят в settings.py, а настройки экземпляра - в local_settings.py, который импортируется в settings.py. local_settings.py указан в .gitignore, а настройки проекта хранятся в git.

Я попробовал несколько других вариантов этого, но закончил здесь, потому что это намного проще.

Единственный раз, когда мне не нравится эта настройка, это для нескольких сайтов (использующих структуру сайтов Django), которые в конечном итоге распространяются на такие вещи, как sitename_settings.py, который импортирует sitename_local_settings.py и т. Д.

Наконец, я сохраняю local_settings_template.py в git, чтобы использовать его в качестве отправной точки для новых экземпляров и для разработчиков, чтобы отслеживать изменения, которые им могут понадобиться в их собственных локальных настройках.

3 голосов
/ 10 марта 2013

Позволяет разделить эти две различные проблемы: 1) управление настройками сайта и 2) управление секретами.

1) Настройки для конкретного сайта

Версия всего (кроме секретов), даже настроек, специфичных для разработчика.

С Django и многими другими программами файл конфигурации представляет собой фрагмент исполняемого кода, который позволяет легко загружать общие параметры конфигурации и переопределять все, что необходимо переопределить. Таким образом, вы можете остаться DRY .

# settings_prod.py
from settings_base import *
... # override whatever needs to be overridden for production environment

Так что теперь у вас есть settings_base.py, settings_prod.py, settings_dev.py, settings_developper_john.py и т. Д. Как вы скажете Django, какой из них использовать?

Развертывание соответствующего файла настроек на сервере, я считаю, является задачей сценария развертывания. Сценарий развертывания будет знать, что вы развертываете на хосте prod17, который является рабочим сервером, поэтому он на лету сгенерирует файл settings.py, который будет выглядеть следующим образом:

# settings.py (generated by deployment script)
from settings_prod import *

Другое решение состоит в том, чтобы иметь эту логику в общем settings.py: она могла бы прочитать переменную среды или получить имя хоста (или применить любую другую логику) и загрузить соответствующий модуль настроек:

# settings.py
import os
if os.environ["MY_APP_ENV"] == "prod":
    from settings_prod import *
elif ...

Мое любимое решение для настроек Django - , описанное здесь .

Для любого другого программного обеспечения, которое не является настолько гибким в своем конфигурационном файле, возможно, лучше всего, чтобы сценарий развертывания генерировал файл конфигурации, возможно, с использованием шаблонов (инструменты, такие как Chef или Puppet, делают это легко). Это позволяет вам оставаться СУХИМЫМИ: например, если для программного обеспечения требуется плоский файл config.ini, то сценарий развертывания может прочитать файл common.ini и production.ini, смешать их соответствующим образом и создать config.ini, готовый к быть развернутым к производству.

Управление секретами

Прежде всего, не храните свои пароли в системе контроля версий. : -)

Одним из решений для управления секретами является передача сценариями сценария развертывания. Например, Боб отвечает за развертывание веб-приложений, он знает пароль к базе данных, поэтому, когда он запускает сценарий развертывания, ему предлагается ввести пароль базы данных, и сценарий передает его на сервер. Или сценарий развертывания просто читает пароль в файле на компьютере Боба и передает его. Это, наверное, самое распространенное решение. Это нормально в большинстве случаев.

              secrets
deployer ================> server

Если вам нужно автоматизировать создание виртуальных машин и вы не хотите, чтобы автоматизированный установщик знал какой-либо секрет, вы можете включить эти секреты в образ виртуальной машины. Конечно, кто-то должен сначала включить секреты в образ виртуальной машины.

                  VM image including secrets
human deployer -------------------------------+
                                              |
                                              |
                    image_name                v
automated deployer ==============> Cloud Service ========> VM including secrets

Проблема этого решения заключается в том, что вам необходимо генерировать новый образ виртуальной машины каждый раз, когда происходят какие-либо секретные изменения. Если вы хотите избежать этого, то вам может потребоваться «секретный сервер»: сервер, управляющий секретами каждого другого сервера. Тогда единственный секрет, который вам нужно включить в образ виртуальной машины, - это секрет начальной загрузки, необходимый для подключения к «секретному серверу».

step 1:

               VM image including bootstrap secret
human deployer -----------------------------------+
                                                  |
                                                  |
                    image_name                    v
automated deployer ==================> Cloud Service ========> VM including secrets


step 2:

    bootstrap secret
   ==================>
VM                     Secret Server
   <==================
         secrets

Например, секретный сервер может быть сервером Chef, секреты могут храниться в зашифрованных пакетах данных, а секретный ключ начальной загрузки будет ключом для расшифровки этих пакетов.

0 голосов
/ 11 сентября 2009

Чтобы справиться с этим, нужно иметь базовый файл settings.py, а затем файл настроек для каждой среды (например, dev_settings.py, live_settings.py)

Вверху каждого конкретного файла среды

from settings import *

Затем я могу просто переопределить любые настройки, которые мне нужно изменить, в зависимости от конкретной среды

Чтобы гарантировать, что каждая среда использует правильные настройки, я просто изменяю переменную среды DJANGO_SETTINGS_MODULE. Как вы это сделаете, зависит от того, как вы развертываете django (mod_wsgi, mod_python и т. Д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...