Зачем выносить параметры подключения к базе данных в переменные окружения?
Что проверяют
Знаете ли вы принцип «конфигурация отдельно от кода» и понимаете ли его пределы. Следом обычно уточняют, как вы работаете с настройками локально, в Docker и в проде, и достаточно ли переменных окружения для хранения паролей.
Как отвечать
Три причины, по порядку важности:
- секреты не попадают в репозиторий: пароль в коде рано или поздно окажется в git, а история помнит его и после удаления из файла. Если так случилось, секрет считается скомпрометированным и его меняют;
- один артефакт на все среды: тот же образ идёт на dev, stage и прод, отличаются только значения переменных. Так принцип сформулирован в Twelve-Factor App;
- смена без пересборки: ротация пароля или переезд базы делается правкой окружения и перезапуском.
В Python читайте через os.environ["DATABASE_URL"], а не os.getenv(): без переменной приложение упадёт на старте с KeyError, а не через час с непонятной ошибкой подключения. Удобнее собрать настройки в класс на pydantic-settings: BaseSettings прочитает переменные, приведёт типы и провалидирует. Локально подойдёт .env через python-dotenv, сам файл в .gitignore, а в репозитории лежит .env.example с пустыми значениями. В Django часто берут django-environ с одной переменной DATABASE_URL.
Покажите, что знаете ограничения. Переменные окружения видны в /proc/<pid>/environ и в docker inspect, наследуются дочерними процессами и легко попадают в логи. Для чувствительных систем секреты берут из хранилища вроде HashiCorp Vault или облачного менеджера секретов либо монтируют файлом, как умеют Docker и Kubernetes.
Где спотыкаются
Коммитят .env «временно» или оставляют в коде значение по умолчанию с боевым паролем: os.getenv("DB_PASSWORD", "prod123").
Считают переменные окружения шифрованием. Это лишь способ не хранить секрет в коде, от человека с доступом к серверу он не защищает.
Печатают объект настроек целиком при старте для отладки. В pydantic для паролей есть тип SecretStr, который не показывает значение в repr и логах.