Переменные окружения — стандартный способ конфигурировать контейнеры. Они позволяют использовать один образ в разных средах (dev, staging, prod) без пересборки.
ENV в Dockerfile: дефолтные значения
ENV задаёт переменные, которые доступны как во время сборки, так и в рантайме контейнера. Это значения по умолчанию.
FROM python:3.12-slim
# Дефолтные значения
ENV APP_ENV=production
ENV PORT=8000
ENV LOG_LEVEL=info
ENV DEBUG=false
WORKDIR /app
COPY . .
CMD ["python", "main.py"]
В коде приложения:
import os
port = int(os.environ.get("PORT", 8000))
debug = os.environ.get("DEBUG", "false").lower() == "true"
log_level = os.environ.get("LOG_LEVEL", "info")
Значения из ENV в Dockerfile — дефолты. Их можно переопределить при запуске контейнера.
Флаг -e: переменные при запуске
# Одна переменная
docker run -e DEBUG=true my-app
# Несколько переменных
docker run \
-e DEBUG=true \
-e PORT=9000 \
-e DATABASE_URL=postgresql://localhost/mydb \
my-app
# Передать переменную из окружения хоста
export API_KEY=secret123
docker run -e API_KEY my-app # значение берётся с хоста
Переданные через -e переменные перекрывают ENV из Dockerfile.
Флаг –env-file: переменные из файла
При большом количестве переменных удобнее хранить их в файле:
# dev.env
DEBUG=true
PORT=8000
DATABASE_URL=postgresql://localhost/devdb
LOG_LEVEL=debug
REDIS_URL=redis://localhost:6379
docker run --env-file dev.env my-app
docker run --env-file prod.env my-app
Формат файла: одна переменная на строку, KEY=VALUE. Строки с # — комментарии.
environment: в docker-compose.yml
services:
web:
build: .
environment:
# Явные значения
DEBUG: "false"
PORT: "8000"
LOG_LEVEL: info
# Из окружения хоста (значение не указано)
SECRET_KEY:
API_KEY:
worker:
build: .
environment:
- QUEUE_NAME=tasks
- CONCURRENCY=4
Оба синтаксиса (key: value и - KEY=VALUE) равнозначны.
.env файл в Docker Compose
Docker Compose автоматически загружает .env из той же папки, что и docker-compose.yml. Значения из .env подставляются в docker-compose.yml через ${VAR}.
# .env
POSTGRES_PASSWORD=mysecretpass
POSTGRES_USER=myuser
IMAGE_TAG=1.2.3
APP_PORT=8000
services:
web:
image: my-app:${IMAGE_TAG}
ports:
- "${APP_PORT}:8000"
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/mydb
db:
image: postgres:15
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
# Проверить подстановку переменных
docker compose config
Можно задать дефолтное значение через ${VAR:-default}:
image: my-app:${IMAGE_TAG:-latest}
Никогда не коммить секреты в образ
Распространённая ошибка — зашить секрет прямо в Dockerfile:
# ПЛОХО: секрет попадёт в слой образа и в git
ENV API_KEY=super_secret_key_12345
RUN curl -H "Authorization: ${API_KEY}" https://api.example.com/setup
Даже если удалить переменную в следующем слое — она останется в истории образа и будет видна через docker history.
Правильный подход:
# ХОРОШО: секрет передаётся только при запуске
FROM python:3.12-slim
WORKDIR /app
COPY . .
CMD ["python", "main.py"]
# Никаких секретов в Dockerfile
# Секрет передаётся при запуске, не запекается в образ
docker run -e API_KEY=secret my-app
.gitignore и .dockerignore
# .gitignore — не коммитить в git
.env
.env.local
.env.production
*.env
# .dockerignore — не копировать в образ
.env
.env.*
Приоритет переменных (от высшего к низшему)
1. -e флаг / environment: в compose
2. --env-file / env_file: в compose
3. .env файл (только для Docker Compose)
4. ENV в Dockerfile
Пример: конфигурация для разных сред
# .env.dev
DATABASE_URL=postgresql://localhost/devdb
DEBUG=true
LOG_LEVEL=debug
# .env.prod
DATABASE_URL=postgresql://prod-server/mydb
DEBUG=false
LOG_LEVEL=warning
# Запуск в dev
docker compose --env-file .env.dev up
# Запуск в prod
docker compose --env-file .env.prod up
💬 Комментарии (0)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!