HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Любое простое приложение взаимодействует с внешним миром: использует базу данных, обращается к внешним сервисам, например, платежным, отправляет письма и получает список друзей. Для большинства этих операций необходимы специальные параметры: ключи, пароли, адреса серверов и порты. Они называются конфигурацией приложения.</p>
1 <p>Любое простое приложение взаимодействует с внешним миром: использует базу данных, обращается к внешним сервисам, например, платежным, отправляет письма и получает список друзей. Для большинства этих операций необходимы специальные параметры: ключи, пароли, адреса серверов и порты. Они называются конфигурацией приложения.</p>
2 <p>В этом уроке разберем, где хранить конфигурацию.</p>
2 <p>В этом уроке разберем, где хранить конфигурацию.</p>
3 <h2>Приложение двенадцати факторов</h2>
3 <h2>Приложение двенадцати факторов</h2>
4 <p>Самый простой и неправильный выбор - хранить конфигурацию прямо в приложении. У такого подхода две проблемы:</p>
4 <p>Самый простой и неправильный выбор - хранить конфигурацию прямо в приложении. У такого подхода две проблемы:</p>
5 <ul><li>Часть этих данных секретная. Хранить их в репозитории нельзя из-за возможных проблем с безопасностью. Любой, у кого есть доступ к репозиторию, сможет получить доступ. Есть вариант с шифрованием, но он выходит за рамки обсуждаемой темы. Для интересующихся рекомендуем изучить<a>Ansible Vault</a></li>
5 <ul><li>Часть этих данных секретная. Хранить их в репозитории нельзя из-за возможных проблем с безопасностью. Любой, у кого есть доступ к репозиторию, сможет получить доступ. Есть вариант с шифрованием, но он выходит за рамки обсуждаемой темы. Для интересующихся рекомендуем изучить<a>Ansible Vault</a></li>
6 <li>При изменении этих параметров придется заново выкладывать сайт. По сути, ничего не изменилось: нет новых фич, нет исправления старых багов. Просто изменилась конфигурация</li>
6 <li>При изменении этих параметров придется заново выкладывать сайт. По сути, ничего не изменилось: нет новых фич, нет исправления старых багов. Просто изменилась конфигурация</li>
7 </ul><p>В 2011 году разработчики компании<a>Heroku</a>выложили в интернете сайт, который называется<a>12factors</a>. Он описывает методологию для создания веб-приложений. Она уменьшает затраты на установку и настройку приложения, повышает переносимость между средами исполнения, позволяет масштабироваться без существенных изменений в инструментах, архитектуре и практике разработки. С тех пор эта методология фактически стала стандартом в индустрии.</p>
7 </ul><p>В 2011 году разработчики компании<a>Heroku</a>выложили в интернете сайт, который называется<a>12factors</a>. Он описывает методологию для создания веб-приложений. Она уменьшает затраты на установку и настройку приложения, повышает переносимость между средами исполнения, позволяет масштабироваться без существенных изменений в инструментах, архитектуре и практике разработки. С тех пор эта методология фактически стала стандартом в индустрии.</p>
8 <p>Рекомендуем полностью изучить этот документ. Сейчас же нас интересует один его аспект - конфигурация. Двенадцать факторов требуют строгого разделения конфигурации и кода. Конфигурация может меняться между развертываниями: локальное окружение разработчика, продакшен, среда для тестирования. Код не меняется.</p>
8 <p>Рекомендуем полностью изучить этот документ. Сейчас же нас интересует один его аспект - конфигурация. Двенадцать факторов требуют строгого разделения конфигурации и кода. Конфигурация может меняться между развертываниями: локальное окружение разработчика, продакшен, среда для тестирования. Код не меняется.</p>
9 <p>Конфигурация должна передаваться в приложение снаружи. Единственный универсальный способ сделать это - использовать переменные окружения.</p>
9 <p>Конфигурация должна передаваться в приложение снаружи. Единственный универсальный способ сделать это - использовать переменные окружения.</p>
10 <h2>Переменные окружения</h2>
10 <h2>Переменные окружения</h2>
11 <p>У Django большое количество настроек для разных подсистем, которые задаются через файл<em>settings.py</em>. Например, так можно запустить фреймворк в режиме отладки:</p>
11 <p>У Django большое количество настроек для разных подсистем, которые задаются через файл<em>settings.py</em>. Например, так можно запустить фреймворк в режиме отладки:</p>
12 <p>Таких переменных довольно много. Например, они отвечают за настройку кеширования или за отправку почты. Все они указываются в файле<em>settings.py</em>.</p>
12 <p>Таких переменных довольно много. Например, они отвечают за настройку кеширования или за отправку почты. Все они указываются в файле<em>settings.py</em>.</p>
13 <p>Некоторые такие настройки конфиденциальны и должны храниться отдельно от основного кода проекта. Для этих целей используются переменные окружения:</p>
13 <p>Некоторые такие настройки конфиденциальны и должны храниться отдельно от основного кода проекта. Для этих целей используются переменные окружения:</p>
14 <p>У данного способа есть несколько недостатков:</p>
14 <p>У данного способа есть несколько недостатков:</p>
15 <ul><li>Переменные загружаются только из окружения</li>
15 <ul><li>Переменные загружаются только из окружения</li>
16 <li>Необходимо обрабатывать исключения KeyError</li>
16 <li>Необходимо обрабатывать исключения KeyError</li>
17 <li>Необходимо конвертировать типы вручную</li>
17 <li>Необходимо конвертировать типы вручную</li>
18 </ul><p>Для простоты конфигурации Django есть сторонняя библиотека<a>python-dotenv</a>. Она позволяет загружать переменные не только из окружения, но и из специального файла<em>.env</em>, который находится в корне проекта. Этот файл не хранится в репозитории. Он специфичен для окружения, в котором идет запуск. Вот его пример:</p>
18 </ul><p>Для простоты конфигурации Django есть сторонняя библиотека<a>python-dotenv</a>. Она позволяет загружать переменные не только из окружения, но и из специального файла<em>.env</em>, который находится в корне проекта. Этот файл не хранится в репозитории. Он специфичен для окружения, в котором идет запуск. Вот его пример:</p>
19 <p>Это обычный текстовый файл, в каждой строке которого находится имя переменной и ее значение.<em>python-dotenv</em>автоматически подгружает его, и затем эти переменные используются в коде, если это необходимо.</p>
19 <p>Это обычный текстовый файл, в каждой строке которого находится имя переменной и ее значение.<em>python-dotenv</em>автоматически подгружает его, и затем эти переменные используются в коде, если это необходимо.</p>
20 <p>Чтобы подключить<em>python-dotenv</em>, необходимо в файле<em>settings.py</em>произвести следующие настройки:</p>
20 <p>Чтобы подключить<em>python-dotenv</em>, необходимо в файле<em>settings.py</em>произвести следующие настройки:</p>
21 <p>Теперь можно использовать переменные окружения, которые описаны в файле<em>.env</em>:</p>
21 <p>Теперь можно использовать переменные окружения, которые описаны в файле<em>.env</em>:</p>
22 <p>Для конфигурации продакшен-окружения одной библиотекой не обойтись. Здесь нужно применять либо системы управления конфигурацией, такие как<a>Ansible</a>, либо использовать системы оркестрации, например,<a>Kubernetes</a>, либо системы, подобные<a>Vault</a>.</p>
22 <p>Для конфигурации продакшен-окружения одной библиотекой не обойтись. Здесь нужно применять либо системы управления конфигурацией, такие как<a>Ansible</a>, либо использовать системы оркестрации, например,<a>Kubernetes</a>, либо системы, подобные<a>Vault</a>.</p>
23 <h2>База данных</h2>
23 <h2>База данных</h2>
24 <p>По умолчанию Djano создает локальную SQLite базу, но в продакшен среде зачастую требуется другая база с отдельным сервером. Чтобы поменять базу, достаточно указать параметры подключения в переменной DATABASES файла<em>settings.py</em>.</p>
24 <p>По умолчанию Djano создает локальную SQLite базу, но в продакшен среде зачастую требуется другая база с отдельным сервером. Чтобы поменять базу, достаточно указать параметры подключения в переменной DATABASES файла<em>settings.py</em>.</p>
25 <p>В зависимости от среды (разработка или продакшен) нам может понадобиться и разная база. Локальная для тестирования в разработке и уже полноценная для задеплоенного приложения. В дополнение, указывать все параметры подключения в коде нельзя - это небезопасно, и потому они также передаются через переменную окружения. Для решения этих задач есть сторонняя библиотека<a>dj-database-url</a>:</p>
25 <p>В зависимости от среды (разработка или продакшен) нам может понадобиться и разная база. Локальная для тестирования в разработке и уже полноценная для задеплоенного приложения. В дополнение, указывать все параметры подключения в коде нельзя - это небезопасно, и потому они также передаются через переменную окружения. Для решения этих задач есть сторонняя библиотека<a>dj-database-url</a>:</p>
26 <p>В примере выше, по умолчанию используется локальная SQLite база. При этом, если будет указана база по ссылке DATABASE_URL, то использоваться будет она. Так мы можем разделять среду разработки и деплоя.</p>
26 <p>В примере выше, по умолчанию используется локальная SQLite база. При этом, если будет указана база по ссылке DATABASE_URL, то использоваться будет она. Так мы можем разделять среду разработки и деплоя.</p>
27 <p>Ссылку на базу, как и все конфиденциальные переменные мы также храним в .env.</p>
27 <p>Ссылку на базу, как и все конфиденциальные переменные мы также храним в .env.</p>