Короткий ответ
Секреты в коде, закоммиченном в репозиторий, доступны всем, у кого есть доступ к истории Git, и их почти невозможно надёжно удалить задним числом; поэтому значения передают через переменные окружения или секрет-хранилища (Vault, AWS Secrets Manager), которые приложение читает в runtime.
Как это работает подробнее
переменные окружения задаются ОС/оркестратором и читаются процессом при старте через os.environ; секрет-хранилища дополнительно дают контроль доступа, аудит и ротацию без изменения кода.
Пример кода
example.py
import os
DATABASE_URL = os.environ["DATABASE_URL"]
DEBUG = os.environ.get("DEBUG", "false").lower() == "true"Что использовать на практике
- Рекомендация. в коде читают
os.environ["DATABASE_URL"], а в проде значение подставляет платформа деплоя; разные значения для dev/staging/production задаются конфигурацией окружения, а не условными блоками в коде.
Подводные камни
- Риск. хранить
.envс продовыми секретами в репозитории «для удобства»; хардкодить пароль в settings.py «временно»; логировать переменные окружения целиком при дебаге.