10. Переменные окружения
Переменные окружения — основной способ передачи конфигурации в контейнеры Docker. Они обеспечивают гибкость, позволяя использовать один образ в разных средах (dev, staging, prod) без пересборки.
ENV в Dockerfile
Заголовок раздела «ENV в Dockerfile»Инструкция ENV устанавливает переменные на этапе сборки и сохраняет их в образе:
FROM node:20-alpine
# Одна переменнаяENV NODE_ENV=production
# Несколько переменныхENV PORT=3000 \ HOST=0.0.0.0 \ LOG_LEVEL=info
# Использование в инструкцияхRUN echo "Building for $NODE_ENV"
CMD ["node", "server.js"]# В контейнере: process.env.NODE_ENV === "production"ARG vs ENV
Заголовок раздела «ARG vs ENV»# ARG — только во время сборки образаARG VERSION=latestARG BUILD_DATE
FROM node:20-alpine
# Передать ARG в ENV для использования в контейнереARG VERSIONENV APP_VERSION=${VERSION}
# Передача при сборке# docker build --build-arg VERSION=1.2.3 .Разница:
- ARG — доступен только во время
docker build, не сохраняется в образе - ENV — доступен во время сборки и в работающем контейнере, сохраняется в образе
Флаг —env при запуске
Заголовок раздела «Флаг —env при запуске»# Передать одну переменнуюdocker run -e NODE_ENV=production myapp
# Передать несколько переменныхdocker run \ -e NODE_ENV=production \ -e DATABASE_URL=postgresql://localhost/mydb \ -e SECRET_KEY=mysecret \ myapp
# Взять значение из окружения хостаexport DATABASE_URL=postgresql://prod-server/mydbdocker run -e DATABASE_URL myapp # значение берётся с хостаФайл .env с Docker Compose
Заголовок раздела «Файл .env с Docker Compose»# .env файл в директории проектаNODE_ENV=developmentDATABASE_URL=postgresql://postgres:password@localhost/mydbREDIS_URL=redis://localhost:6379JWT_SECRET=dev_secret_change_in_prodAPI_PORT=3000services: api: image: myapi env_file: - .env # загружает .env файл - .env.local # переопределения (git-игнорируется) environment: - NODE_ENV=${NODE_ENV:-development} # с дефолтным значением - CUSTOM_VAR=hardcoded # жёстко заданная
postgres: image: postgres:15 environment: POSTGRES_DB: ${POSTGRES_DB:-mydb} POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Database password required} # :? — ошибка если не заданоНесколько .env файлов
Заголовок раздела «Несколько .env файлов»# Иерархия .env файлов для разных сред:
.env # базовые значения, в git.env.local # локальные переопределения, в .gitignore.env.development # для разработки.env.production # для продакшена (без секретов!).env.test # для тестов
# docker compose с конкретным .envdocker compose --env-file .env.production upЛучшие практики безопасности
Заголовок раздела «Лучшие практики безопасности»❌ Никогда не делайте:
# Секреты в Dockerfile попадают в образ!ENV DATABASE_PASSWORD=mysecret123ENV API_KEY=sk-prod-abc123✅ Правильный подход:
# 1. Передавать секреты через --env или Docker Secretsdocker run -e DATABASE_PASSWORD=$DB_PASS myapp
# 2. Использовать Docker Secrets в Swarmdocker secret create db_password ./db_password.txtdocker service create --secret db_password myapp
# 3. Использовать HashiCorp Vault или cloud secrets managers# 4. Никогда не коммитить .env с секретами в git.env.env.local.env.*.local