2009-09-10 2 views
23

Я искал лучший способ справиться с настройками для сайта (в данном случае, файл django settings.py).Элегантно обрабатывать настройки/настройки сайта в svn/hg/git/etc?

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

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

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

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

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

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

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

+0

См. Также этот хороший ответ, в котором используются текущие учетные данные для входа в систему, чтобы различать конкретные параметры (но все еще есть все в управлении версиями): http://stackoverflow.com/questions/6009/how-do-you-deal- с-configuration-files-in-source-control/65226 # 65226 –

ответ

18

Создайте основной файл 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 файл на любом компьютере (в том числе машины разработчиков) с местными переопределениями и пометить этот файл игнорируются управлением версиями, так что изменения не провериться в.

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

+0

Спасибо Ned. Вы помещаете файлы настроек сайта в исходный элемент управления? Я беспокоюсь о наличии паролей в файлах настроек в исходном элементе управления. – Parand

+0

Мы помещаем все, кроме local.py, в исходное управление. У меня нет решения проблемы с паролем. –

+3

Это похоже на отличный подход, но я изо всех сил пытаюсь выяснить структуру вашего каталога. У вас есть файл settings.py, а также каталог/каталог настроек? Если да, то как избежать конфликтов имен? (Извините, если это действительно очевидно). – donturner

4

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

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

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

Настройки проекта такие, как 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, чтобы использовать в качестве отправной точки для новых экземпляров и для разработчиков отслеживать изменения, которые могут потребоваться для их собственных локальных настроек.

0

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

В верхней части каждой конкретной среды файла У меня есть

from settings import * 

затем я могу просто изменить все настройки нужно изменить на окружающую среду основе конкретного

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

3

Позволяет разделить эти две различные проблемы: 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 является described here.

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

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

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

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

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

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

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

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

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, секреты могут быть хранить в шифрованных пакетах данных, и бутстраповская секрет будет ключ для расшифровки этих пакетов.

Смежные вопросы