Пошук уроків, статей та іншого контенту
Налаштуєте доступ до контейнерів, передавання конфігурації та збереження даних за допомогою томів.
Контейнер ізольований від хост-системи. Щоб взаємодіяти з ним, зазвичай потрібно налаштувати:
порти — щоб отримати доступ до мережевого сервісу контейнера;
змінні середовища — щоб передати конфігурацію під час запуску;
томи — щоб зберігати дані незалежно від життєвого циклу контейнера.
Ці параметри задають під час виконання команди docker run.
Контейнер може запускати вебсервер або інший мережевий сервіс. Проте порт контейнера не стає автоматично доступним на хості.
Параметр -p публікує порт:
-p порт_хоста:порт_контейнераНаприклад:
docker run --rm --name lesson-web -p 8080:80 nginx:alpineЦя команда:
запускає контейнер nginx:alpine;
передає порт 8080 хоста на порт 80 контейнера;
називає контейнер lesson-web;
автоматично видаляє контейнер після його зупинки завдяки --rm.
Після запуску відкрийте в браузері:
http://localhost:8080Або перевірте доступність командою:
curl http://localhost:8080Зупинити контейнер можна в іншому терміналі:
docker stop lesson-webЗа замовчуванням Docker публікує порт на всіх мережевих інтерфейсах хоста. Для доступу лише з цього комп’ютера вкажіть адресу 127.0.0.1:
docker run --rm --name lesson-web -p 127.0.0.1:8080:80 nginx:alpineТепер сервіс буде доступний через localhost:8080, але не буде відкритий для інших пристроїв у мережі.
Порт після двокрапки — це порт усередині контейнера:
-p 8080:808080 — порт на хості;
80 — порт у контейнері.
Їх можна змінювати незалежно:
docker run --rm --name lesson-web -p 9000:80 nginx:alpineУ цьому випадку вебсервер усе ще слухає порт 80 усередині контейнера, але на хості він доступний через порт 9000.
Публікація порту не запускає мережевий сервіс. Усередині контейнера вже має працювати програма, яка слухає відповідний порт.
Змінна середовища — це пара «назва — значення», доступна процесам усередині контейнера.
Передати змінну можна параметром -e:
docker run --rm \
-e APP_NAME=lesson \
-e APP_MODE=development \
alpine:3.20 \
sh -c 'echo "Назва: $APP_NAME"; echo "Режим: $APP_MODE"'Результат буде приблизно таким:
Назва: lesson
Режим: developmentУсередині контейнера змінні доступні так само, як і в звичайному процесі Linux:
echo "$APP_NAME"Змінна може вже існувати на хості:
export APP_MODE=production
docker run --rm -e APP_MODE alpine:3.20 sh -c 'echo "$APP_MODE"'Якщо після -e вказати лише назву змінної, Docker візьме її значення з поточного середовища оболонки.
Інший варіант — явно передати значення:
docker run --rm -e APP_MODE="$APP_MODE" alpine:3.20 sh -c 'echo "$APP_MODE"'Якщо змінних багато, їх можна зберігати у файлі .env:
APP_NAME=lesson
APP_MODE=developmentПередайте цей файл за допомогою параметра --env-file:
docker run --rm \
--env-file .env \
alpine:3.20 \
sh -c 'echo "Назва: $APP_NAME"; echo "Режим: $APP_MODE"'Файл .env зручно використовувати для локальної конфігурації. Не додавайте до системи контролю версій файли, що містять паролі, токени або інші секрети.
Створіть контейнер, який працює у фоні:
docker run -d \
--name lesson-env \
-e APP_MODE=development \
alpine:3.20 \
sh -c 'while true; do sleep 60; done'Переглянути змінні контейнера можна так:
docker exec lesson-env envПісля перевірки видаліть контейнер:
docker rm -f lesson-envДані всередині контейнера належать його файловій системі. Якщо контейнер видалити, ці дані зазвичай будуть втрачені.
Том Docker зберігає дані окремо від контейнера. Тому том можна підключити до нового контейнера після видалення попереднього.
Створіть том:
docker volume create lesson-dataПідключіть його до каталогу /data всередині контейнера:
docker run --rm \
--name lesson-writer \
-v lesson-data:/data \
alpine:3.20 \
sh -c 'echo "Дані збережено у томі" > /data/message.txt'Формат параметра:
-v ім_я_тому:шлях_у_контейнеріПеревірте, що файл зберігся, запустивши інший контейнер із тим самим томом:
docker run --rm \
-v lesson-data:/data \
alpine:3.20 \
cat /data/message.txtНавіть though перший контейнер був автоматично видалений через --rm, файл залишився в томі.
Видалити том можна окремо:
docker volume rm lesson-dataDocker не видаляє іменований том автоматично разом із контейнером.
Замість іменованого тому можна підключити конкретний каталог із хоста:
mkdir -p ./site
echo "Вміст із хоста" > ./site/index.html
docker run --rm \
-p 8080:80 \
-v "$PWD/site:/usr/share/nginx/html:ro" \
nginx:alpineТут:
./site — каталог на хості;
/usr/share/nginx/html — каталог усередині контейнера, який використовує Nginx;
:ro — режим лише для читання з боку контейнера.
Відкрийте http://localhost:8080. Nginx покаже файл index.html із каталогу ./site.
Зміни у файлах хоста будуть доступні контейнеру одразу, тому bind mount часто використовують під час локальної розробки.
Використовуйте іменований том, коли:
дані має зберігати Docker;
важливо пережити видалення контейнера;
не потрібно вручну працювати з файлами в конкретному каталозі хоста.
Використовуйте bind mount, коли:
потрібно підключити конкретні файли або каталог проєкту;
зміни на хості мають одразу з’являтися в контейнері;
ви розробляєте застосунок локально.
Для іменованих томів також існує більш описовий синтаксис --mount:
docker run --rm \
--mount type=volume,source=lesson-data,target=/data \
alpine:3.20 \
sh -c 'echo "Новий запис" > /data/another.txt'Наступний приклад одночасно використовує порт, змінні середовища та том:
# Створюємо іменований том для даних
docker volume create lesson-data
# Запускаємо контейнер у фоновому режимі
docker run -d \
--name lesson-demo \
-p 8080:80 \
-e APP_MODE=development \
-e APP_MESSAGE="Вітаємо в Docker" \
-v lesson-data:/data \
nginx:alpine
# Перевіряємо опублікований порт
curl http://localhost:8080
# Перевіряємо конфігурацію контейнера
docker inspect lesson-demo
# Зупиняємо та видаляємо контейнер
docker rm -f lesson-demo
# Видаляємо том, коли дані більше не потрібні
docker volume rm lesson-dataУ цьому прикладі:
-p 8080:80 робить Nginx доступним через порт 8080 хоста;
-e передає конфігурацію контейнеру;
-v lesson-data:/data підключає іменований том;
docker rm -f видаляє контейнер, але не видаляє том.
Неправильно:
docker run --rm -p 80:8080 nginx:alpineЯкщо Nginx слухає порт 80 у контейнері, правильний запис:
docker run --rm -p 8080:80 nginx:alpineСпочатку вказують порт хоста, потім порт контейнера.
Якщо порт 8080 уже використовує інша програма або контейнер, Docker не зможе запустити новий контейнер із цим портом.
Використайте інший порт:
docker run --rm -p 8081:80 nginx:alpineКонтейнер працює, доки працює його основний процес. Якщо команда завершується, контейнер також зупиняється.
Наприклад, цей контейнер завершиться одразу після виконання echo:
docker run --name short-task alpine:3.20 echo "Готово"Це нормальна поведінка для одноразової команди. Для сервісів потрібно запускати процес, який продовжує працювати у фоні.
Якщо том підключено до /data, файл /tmp/message.txt не буде збережено в цьому томі:
docker run --rm -v lesson-data:/data alpine:3.20 \
sh -c 'echo "Тимчасовий файл" > /tmp/message.txt'Для збереження записуйте дані саме в /data:
docker run --rm -v lesson-data:/data alpine:3.20 \
sh -c 'echo "Збережений файл" > /data/message.txt'Змінні середовища зручні для конфігурації, але їхні значення можуть бути видимими через інформацію про контейнер і процеси.
Не зберігайте паролі та токени у файлах, які додаються до репозиторію, або без потреби передаються через -e.
Команда нижче видаляє невикористані томи:
docker volume pruneВиконуйте її обережно: Docker видалить усі томи, які не підключені до контейнерів.
-p порт_хоста:порт_контейнера публікує порт контейнера на хості.
Порт хоста можна змінити, не змінюючи порт, на якому працює програма всередині контейнера.
-e NAME=value передає змінну середовища контейнеру.
--env-file завантажує кілька змінних із файлу.
Іменований том зберігає дані незалежно від контейнера.
Bind mount підключає конкретний каталог або файл із хоста.
Контейнер можна видалити, не втративши дані тому.
:ro монтує каталог у режимі лише для читання.