Передача переменных при запуске:
Самый частый способ, флаг -e у docker run. Официальный образ postgres без пароля вообще не стартует, так что пример живой:
Код: Выделить всё
docker run -d --name db \
-e POSTGRES_PASSWORD=secret123 \
-e POSTGRES_DB=shop \
postgres:16Проверить, что контейнер реально получил, можно командой docker exec db env, она печатает всё окружение главного процесса. А docker inspect db покажет тот же список в блоке Config.Env. Отсюда важный вывод: любой, у кого есть доступ к Docker на этой машине, видит ваши переменные через inspect. Для обычной конфигурации это нормально, а для серьёзных секретов в продакшене используют другие механизмы, вернёмся к этому в главе 11.
Файл с переменными:
Когда переменных больше трёх, флаги превращаются в кашу. Сложите их в файл и подключите через --env-file:
Код: Выделить всё
# app.env
DATABASE_URL=postgres://app:secret123@db:5432/shop
REDIS_HOST=cache
APP_DEBUG=false
# запуск:
# docker run -d --env-file app.env myapp:1.2ENV и ARG в Dockerfile:
В Dockerfile из главы 4 вы уже встречали инструкцию ENV. Она задаёт значение по умолчанию, которое попадает в каждый контейнер из этого образа:
Код: Выделить всё
FROM node:20-alpine
ARG BUILD_VERSION=dev
ENV NODE_ENV=production \
APP_PORT=3000
LABEL version=$BUILD_VERSION
WORKDIR /app
COPY . .
CMD ["node", "server.js"]И ARG, и ENV остаются видимыми в docker history и docker inspect образа. Передавать через них токены и пароли на этапе сборки нельзя, они останутся в слоях навсегда.
Конфиги целиком:
Не всё сводится к переменным. Если приложению нужен полноценный конфиг-файл, например nginx.conf, проще смонтировать его с хоста, как в главе 5:
Код: Выделить всё
docker run -d -p 8080:80 \
-v "$(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro" \
nginx:1.27Типичные грабли:
Переменные нельзя поменять у работающего контейнера. docker exec -e подсунет значение только в ту команду, которую вы выполняете, сам контейнер не изменится. Нужно новое окружение, пересоздавайте контейнер. Это нормально, контейнеры одноразовые.
Вторая ловушка, кавычки и пробелы в env-file, о ней выше. Третья, опечатка в имени переменной: Docker имена не валидирует, контейнер молча стартует без нужного значения, а приложение падает с невнятной ошибкой где-то глубоко. Привычка прогонять docker exec ... env после первого запуска экономит часы.
Четвёртая: ENV с паролем, добавленный в Dockerfile "временно, для теста", имеет свойство уезжать в реестр вместе с образом. Проверяйте docker history перед push.
Что в итоге: переменные окружения передаются через -e, --env-file и ENV, приоритет у того, что задано при запуске. Секреты в образ не зашиваются, объёмные конфиги монтируются томами. В следующей главе соберём всё наработанное в docker-compose.yml, и там переменные заиграют по-новому: Compose умеет подставлять их прямо в свою конфигурацию из файла .env.