Django — Настройки: конфиденциальные настройки и различные среды (dev, prod, промежуточные). Каков рекомендуемый способ сделать это

#django #django-settings

#django #django-настройки

Вопрос:

Я использую django версии 2.1.7:

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

 Approches used in the general are:
1) setting environmental variables
2) multiple settings
3) load configuration variables from a file like using django-environ etc
  

Approach 1: Я не буду использовать, потому что я не хочу использовать переменные среды для хранения переменных.

Approach 3: использует стороннюю библиотеку, и иногда они могут больше не поддерживаться. Но если есть какой-либо стандартный способ сделать это, я в порядке.

Approach 2: Здесь я не уверен, как хранить конфиденциальные данные отдельно.

Итак, может кто-нибудь подсказать мне в этом отношении.

Ответ №1:

Я использую комбинацию всех:

  • При запуске gunicorn как службы в systemd вы можете установить переменные среды, используя файл conf в вашем каталоге .service.d:
     [Service]
    Environment="DJANGO_SETTINGS_MODULE=myapp.settings.production"
    Environment="DATABASE_NAME=MYDB"
    Environment="DATABASE_USER=MYUSER"
    Environment="DATABASE_PASSWORD=MYPASSWORD" 
    ...
      
  • Этот файл извлекается из S3 (где он зашифрован) при запуске экземпляра. У меня есть скрипт запуска с использованием aws-cli, который делает это.
  • Чтобы иметь возможность запускать команды управления, например, для переноса вашей базы данных в рабочую среду, вам также нужны эти переменные, поэтому, если переменные среды не установлены, я извлекаю их непосредственно из этого файла. Итак, в моих настройках у меня есть что-то вроде этого:

     def get_env_variable(var_name):
        try:
            return os.environ[var_name]
        except KeyError:
            env = fetch_env_from_gunicorn()
            return env[var_name]
    
    def fetch_env_from_gunicorn():
        gunicorn_conf_directory = '/etc/systemd/system/gunicorn.service.d'
        gunicorn_env_filepath = '%s/gunicorn.conf' % (gunicorn_conf_directory,)
        if not os.path.isfile(gunicorn_env_filepath):
            raise ImproperlyConfigured('No environment settings found in gunicorn configuration')
    
        key_value_reg_ex = re.compile(r'^Environments*=s*"(. ?)s*=s*(. ?)"$')
        environment_vars = {}
        with open(gunicorn_env_filepath) as f:
            for line in f:
                match = key_value_reg_ex.search(line)
                if match:
                    environment_vars[match.group(1)] = match.group(2)
        return environment_vars
    
    ...
    
    DATABASES = {
        ...
        'PASSWORD': get_env_variable('DATABASE_PASSWORD'),
        ...}
      

    Обратите внимание, что все команды управления, которые я запускаю в своих размещенных экземплярах, мне нужно явно передавать --settings=myapp.settings.production , чтобы он знал, какой файл настроек использовать.

  • Разные настройки для разных типов сред. Это потому, что такие вещи, как DEBUG но также настройки почты, настройки аутентификации и т.д. … Слишком разные в разных средах, чтобы использовать один файл настроек. У меня есть default.py настройки в каталоге настроек со всеми общими настройками, а затем производство. например, py начинается с from .default import * и просто переопределяет то, что ему нужно переопределить, как DEBUG = False и другое DATABASES (для использования вышеупомянутого механизма), LOGGING и т.д…

При этом возникают следующие риски для безопасности:

  • Любой, у кого есть доступ по ssh и разрешения для каталога systemd, может прочитать секреты. Убедитесь, что у вас есть ваши экземпляры в VPN и ограничьте доступ ssh, например, к определенным IP-адресам. Также я разрешаю ssh только с ssh-ключами, а не с именем пользователя / паролем, поэтому нет риска кражи паролей.
  • Любой, у кого есть ssh-доступ к каталогу приложений django, может запустить оболочку и from django.conf import settings затем прочитать settings . То же, что и выше, в любом случае должно быть ограничено.
  • Любой, у кого есть доступ к вашему хранилищу (например, S3), может прочитать файл. Опять же, это можно легко ограничить.