Пошук уроків, статей та іншого контенту
Зберігайте значення конфігурації у файлі .env та підставляйте їх під час запуску контейнерів.
.envКонфігурація застосунку часто відрізняється залежно від середовища:
у розробці використовується один порт;
у тестовому середовищі — інший;
ім’я образу або режим журналювання можуть змінюватися;
секрети не повинні бути записані безпосередньо в Dockerfile чи compose.yaml.
Файл .env дає змогу зберігати такі значення окремо від команд запуску та підставляти їх під час створення контейнера.
Приклад .env:
APP_NAME=orders-api
APP_PORT=8080
LOG_LEVEL=infoЗмінні мають формат ІМʼЯ=значення. Порожні рядки можна використовувати для розділення груп налаштувань, а коментарі починаються символом #.
docker runПараметр --env-file передає змінні з файлу в середовище контейнера:
docker run --rm \
--env-file .env \
alpine:3.20 \
sh -c 'echo "Назва: $APP_NAME"; echo "Порт: $APP_PORT"; echo "Рівень логування: $LOG_LEVEL"'Після запуску контейнер виведе:
Назва: orders-api
Порт: 8080
Рівень логування: infoУ цьому прикладі:
--env-file .env читає значення з файлу;
alpine:3.20 запускається як тимчасовий контейнер;
sh -c виконує команду всередині контейнера;
$APP_NAME, $APP_PORT і $LOG_LEVEL — змінні середовища контейнера.
Сам файл .env не копіюється в контейнер. Docker читає його на хості та передає значення як змінні середовища.
Для однієї або кількох змінних можна використати --env або скорочений варіант -e:
docker run --rm \
--env APP_NAME=orders-api \
--env LOG_LEVEL=debug \
alpine:3.20 \
sh -c 'echo "$APP_NAME: $LOG_LEVEL"'Значення, передане через --env, може замінити значення з файлу, якщо для тієї самої змінної використано обидва способи:
docker run --rm \
--env-file .env \
--env LOG_LEVEL=debug \
alpine:3.20 \
sh -c 'echo "$LOG_LEVEL"'Результат:
debug.env у Docker ComposeDocker Compose використовує .env для підстановки значень у файл compose.yaml.
Створімо файл .env:
APP_NAME=orders-api
APP_PORT=8080
LOG_LEVEL=infoФайл compose.yaml:
services:
app:
image: alpine:3.20
environment:
APP_NAME: ${APP_NAME}
LOG_LEVEL: ${LOG_LEVEL}
PORT: ${APP_PORT}
command:
- sh
- -c
- |
echo "Застосунок: $APP_NAME"
echo "Порт: $PORT"
echo "Логування: $LOG_LEVEL"
sleep 3600Запустіть сервіс:
docker compose upCompose знайде .env у поточному каталозі та замінить вирази:
${APP_NAME}
${LOG_LEVEL}
${APP_PORT}відповідними значеннями.
У результаті контейнер отримає приблизно таку конфігурацію:
environment:
APP_NAME: orders-api
LOG_LEVEL: info
PORT: 8080Зупинити та видалити контейнер можна командою:
docker compose downДля змінної можна вказати значення, яке використовуватиметься, якщо змінна не задана:
services:
app:
image: alpine:3.20
environment:
APP_NAME: ${APP_NAME:-orders-api}
LOG_LEVEL: ${LOG_LEVEL:-info}Синтаксис:
${VARIABLE:-default}Якщо VARIABLE має значення, буде використано його. Якщо змінну не задано або вона порожня, використовується default.
Наприклад, у такій конфігурації:
APP_NAME=вираз:
APP_NAME: ${APP_NAME:-orders-api}дасть значення orders-api.
Під час підстановки в compose.yaml Compose може використовувати:
змінні середовища оболонки;
змінні з .env;
змінні з файлу, явно переданого через --env-file.
Наприклад:
APP_PORT=9000 docker compose upЯкщо в .env записано:
APP_PORT=8080то для цього запуску значення з оболонки 9000 має пріоритет над значенням із .env.
Це дає змогу тимчасово змінити конфігурацію без редагування файлу:
LOG_LEVEL=debug docker compose upДля різних середовищ можна створити кілька файлів:
.env
.env.test
.env.productionПотрібний файл можна передати через --env-file:
docker compose --env-file .env.test upАбо:
docker compose --env-file .env.production up -dФайл compose.yaml при цьому залишається однаковим, а значення конфігурації змінюються залежно від середовища.
Приклад .env.test:
APP_NAME=orders-api-test
APP_PORT=8081
LOG_LEVEL=debugПриклад .env.production:
APP_NAME=orders-api
APP_PORT=8080
LOG_LEVEL=warn.env і env_file — різні механізмиУ Docker Compose є два схожі за назвою поняття.
.envФайл .env використовується Compose для підстановки значень у compose.yaml:
services:
app:
image: ${APP_IMAGE}За замовчуванням Compose шукає .env у робочому каталозі проєкту.
env_fileВластивість env_file передає змінні безпосередньо в середовище контейнера:
services:
app:
image: alpine:3.20
env_file:
- app.env
command:
- sh
- -c
- 'echo "$APP_NAME $LOG_LEVEL"; sleep 3600'Файл app.env:
APP_NAME=orders-api
LOG_LEVEL=infoУ цьому випадку змінні з app.env будуть доступні всередині контейнера.
env_file не потрібно плутати з автоматичною підстановкою в самому compose.yaml. Якщо значення потрібно використати для побудови конфігурації Compose, застосовуйте ${VARIABLE} і файл .env або --env-file.
Можна поєднувати обидва механізми:
services:
app:
image: ${APP_IMAGE:-alpine:3.20}
env_file:
- app.envТут:
${APP_IMAGE:-alpine:3.20} налаштовує образ під час обробки Compose-файлу;
env_file передає змінні з app.env у контейнер.
Приклад структури:
project/
├── .env
├── .gitignore
├── compose.yaml
└── app.env.env:
APP_IMAGE=alpine:3.20
APP_PORT=8080app.env:
APP_NAME=orders-api
LOG_LEVEL=infocompose.yaml:
services:
app:
image: ${APP_IMAGE}
environment:
PORT: ${APP_PORT}
env_file:
- app.env
command:
- sh
- -c
- |
echo "Застосунок: $APP_NAME"
echo "Порт: $PORT"
echo "Рівень логування: $LOG_LEVEL"
sleep 3600Запуск:
docker compose upУ цьому прикладі:
APP_IMAGE береться з .env і використовується для вибору образу;
APP_PORT береться з .env і явно передається контейнеру;
APP_NAME і LOG_LEVEL беруться з app.env та доступні всередині контейнера.
.env у GitФайли з локальною конфігурацією часто містять паролі, токени або адреси внутрішніх сервісів. Їх не слід додавати до репозиторію.
Додайте .env до .gitignore:
.env
.env.*
!.env.exampleФайл .env.example може містити лише назви змінних і безпечні приклади:
APP_NAME=orders-api
APP_PORT=8080
LOG_LEVEL=info
DATABASE_URL=postgres://user:password@db:5432/ordersРеальні значення розробник створює локально у власному .env.
Файл .env не є механізмом шифрування. Якщо секрет потрапив у контейнер через змінну середовища, він може бути доступний процесам або інструментам, які мають доступ до конфігурації контейнера. Тому не варто використовувати .env як захищене сховище секретів у production.
Перед запуском сервісів корисно перевірити підсумкову конфігурацію Compose:
docker compose configКоманда покаже конфігурацію після підстановки змінних. Це допомагає виявити:
змінну, яку не було задано;
неправильне ім’я змінної;
неочікуване значення порту;
помилку у форматі YAML.
Щоб перевірити значення змінних, які Compose використовує для підстановки, можна виконати:
docker compose config --environment.env автоматично потрапить у контейнерНаявність .env у каталозі не означає, що всі його змінні будуть доступні всередині контейнера.
Щоб передати змінну контейнеру, використовуйте environment:
services:
app:
environment:
APP_NAME: ${APP_NAME}або env_file:
services:
app:
env_file:
- app.envІмена мають збігатися:
APP_PORT=8080environment:
PORT: ${APP_PORT}Якщо написати ${PORT} замість ${APP_PORT}, Compose не використає значення APP_PORT.
=Пишіть:
APP_PORT=8080а не:
APP_PORT = 8080Пробіли можуть стати частиною імені або значення залежно від способу читання файлу та призвести до неочікуваної конфігурації.
Не додавайте справжні паролі й токени до .env, який комітується в Git. Використовуйте .gitignore та окрему локальну конфігурацію.
Якщо значення містить пробіли або спеціальні символи, перевірте, як конкретний інструмент обробляє лапки. Після зміни .env запускайте:
docker compose configТак можна побачити фактичний результат підстановки.
.env зберігає значення конфігурації окремо від Docker-команд.
docker run --env-file .env передає змінні в контейнер.
Docker Compose використовує ${VARIABLE} для підстановки значень у compose.yaml.
env_file передає змінні безпосередньо в середовище контейнера.
Значення можна тимчасово замінити через змінні оболонки або інший файл із --env-file.
.env не є захищеним сховищем секретів і зазвичай не повинен потрапляти до Git.
Команда docker compose config допомагає перевірити результат підстановки до запуску контейнерів.