# Управление переменными окружения --- ## Принцип Все настройки, которые меняются между окружениями (local, staging, production) — в переменных окружения. Никаких hardcoded значений в коде. --- ## Формат: .env ```bash # === Core === PROJECT_NAME=MyProject PROJECT_VERSION=1.0.0 PROJECT_ENV=local # === Server === SERVER_HOST=0.0.0.0 SERVER_PORT=8020 # === Database === DATABASE_URL=sqlite+aiosqlite:///./app.db # DATABASE_URL=postgresql+asyncpg://user:pass@localhost/dbname # === JWT === JWT_SECRET_KEY=your-secret-key-here JWT_ALGORITHM=HS256 # === Logging === LOG_LEVEL=INFO ``` --- ## Валидация при старте ```python from pydantic_settings import BaseSettings class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", extra="ignore") project_name: str = "MyProject" database_url: str = "sqlite+aiosqlite:///./app.db" jwt_secret_key: str = "" @property def is_sqlite(self) -> bool: return "sqlite" in self.database_url def validate_for_production(self) -> None: """Проверить что критические переменные установлены.""" if self.project_env == "production": assert self.jwt_secret_key, "JWT_SECRET_KEY not set" assert "postgresql" in self.database_url, "Use PostgreSQL in production" ``` --- ## Синхронизация .env.example `.env.example` должен быть в репозитории и обновляться при каждом добавлении переменной. Правила: - Все переменные с комментариями - Чувствительные значения пустые (пароли, ключи) - Секции разделены комментариями (`# === Database ===`) - Примеры значений в комментариях --- ## Secrets management | Окружение | Где хранить секреты | |-----------|-------------------| | Local | `.env` (в .gitignore) | | Staging | GitHub Secrets / 1Password | | Production | GitHub Secrets / Vault | --- ## [ASK] - Какой метод управления секретами? (рекомендация: .env + GitHub Secrets) - Нужен ли Vault? (нет, < 10 разработчиков) - Как часто менять JWT_SECRET_KEY? (при утечке или раз в год)