Перейти к содержимому

10. Переменные окружения

Переменные окружения — основной способ передачи конфигурации в контейнеры Docker. Они обеспечивают гибкость, позволяя использовать один образ в разных средах (dev, staging, prod) без пересборки.

Инструкция 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 — только во время сборки образа
ARG VERSION=latest
ARG BUILD_DATE
FROM node:20-alpine
# Передать ARG в ENV для использования в контейнере
ARG VERSION
ENV APP_VERSION=${VERSION}
# Передача при сборке
# docker build --build-arg VERSION=1.2.3 .

Разница:

  • ARG — доступен только во время docker build, не сохраняется в образе
  • 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/mydb
docker run -e DATABASE_URL myapp # значение берётся с хоста
Окно терминала
# .env файл в директории проекта
NODE_ENV=development
DATABASE_URL=postgresql://postgres:password@localhost/mydb
REDIS_URL=redis://localhost:6379
JWT_SECRET=dev_secret_change_in_prod
API_PORT=3000
docker-compose.yml
services:
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 # базовые значения, в git
.env.local # локальные переопределения, в .gitignore
.env.development # для разработки
.env.production # для продакшена (без секретов!)
.env.test # для тестов
# docker compose с конкретным .env
docker compose --env-file .env.production up

❌ Никогда не делайте:

# Секреты в Dockerfile попадают в образ!
ENV DATABASE_PASSWORD=mysecret123
ENV API_KEY=sk-prod-abc123

✅ Правильный подход:

Окно терминала
# 1. Передавать секреты через --env или Docker Secrets
docker run -e DATABASE_PASSWORD=$DB_PASS myapp
# 2. Использовать Docker Secrets в Swarm
docker secret create db_password ./db_password.txt
docker service create --secret db_password myapp
# 3. Использовать HashiCorp Vault или cloud secrets managers
# 4. Никогда не коммитить .env с секретами в git
.gitignore
.env
.env.local
.env.*.local