Пошук уроків, статей та іншого контенту
Розберіться з різницею між портами контейнера, хоста та правилами їхнього перенаправлення.
Порт — це числовий ідентифікатор, через який програма приймає мережеві з’єднання.
Наприклад, вебсервер усередині контейнера може слухати порт 80. Але сам контейнер працює в ізольованій мережі Docker, тому звернутися до цього порту безпосередньо з браузера на хості зазвичай не можна.
У контексті Docker важливо розрізняти:
порт контейнера — порт, на якому програма слухає всередині контейнера;
порт хоста — порт вашого комп’ютера, через який можна звернутися до контейнера;
перенаправлення портів — правило, яке з’єднує порт хоста з портом контейнера.
Уявімо, що контейнер запускає вебсервер:
контейнер
└── вебсервер слухає порт 80Порт 80 належить мережевому простору контейнера. Він не означає автоматичне відкриття порту 80 на вашому комп’ютері.
Інші контейнери в тій самій Docker-мережі можуть взаємодіяти з цим портом, але доступ із хоста потребує окремого правила перенаправлення.
Порт хоста належить операційній системі, у якій запущено Docker.
Наприклад, браузер може звертатися до:
localhost:8080Це означає:
localhost — поточний комп’ютер;
8080 — порт хоста.
Щоб запит потрапив до вебсервера в контейнері, Docker має перенаправити порт 8080 хоста на порт 80 контейнера.
Схема виглядає так:
localhost:8080
│
▼
порт 80 у контейнері
│
▼
вебсервер-pДля перенаправлення портів використовується параметр -p команди docker run:
-p ПОРТ_ХОСТА:ПОРТ_КОНТЕЙНЕРАЗапустімо контейнер з Nginx:
docker run --name web-server -d -p 8080:80 nginx:alpineУ цій команді:
--name web-server задає ім’я контейнера;
-d запускає контейнер у фоновому режимі;
-p 8080:80 перенаправляє порт 8080 хоста на порт 80 контейнера;
nginx:alpine — образ, з якого створюється контейнер.
Після запуску відкрийте в браузері:
http://localhost:8080Ви побачите стандартну сторінку Nginx.
Перевірити запущені контейнери можна командою:
docker psУ стовпці PORTS буде приблизно такий запис:
0.0.0.0:8080->80/tcpВін означає, що TCP-порт 8080 хоста перенаправляється на TCP-порт 80 контейнера.
Зупинити й видалити контейнер можна так:
docker stop web-server
docker rm web-serverПорт хоста та порт контейнера не зобов’язані збігатися.
Наприклад:
docker run --name web-server -d -p 3000:80 nginx:alpineТепер:
Nginx усе ще слухає порт 80 у контейнері;
на хості використовується порт 3000;
сторінка доступна за адресою http://localhost:3000.
Інші приклади:
-p 8080:80
-p 5000:80
-p 9000:80У всіх випадках програма в контейнері слухає порт 80, але користувач звертається до різних портів хоста.
За замовчуванням запис:
-p 8080:80зазвичай прив’язує порт до всіх мережевих інтерфейсів хоста. Це може зробити сервіс доступним не лише через localhost, а й з інших пристроїв у мережі.
Щоб дозволити доступ тільки з цього комп’ютера, явно вкажіть адресу 127.0.0.1:
docker run --name local-web -d -p 127.0.0.1:8080:80 nginx:alpineТепер сервіс доступний через:
http://localhost:8080але не має бути доступним через мережеву адресу комп’ютера з інших пристроїв.
Синтаксис у цьому випадку такий:
-p АДРЕСА_ХОСТА:ПОРТ_ХОСТА:ПОРТ_КОНТЕЙНЕРАEXPOSE не перенаправляє портУ Dockerfile можна побачити інструкцію:
EXPOSE 80Вона документує, що програма в контейнері очікує з’єднання на порту 80. Але EXPOSE сама по собі:
не відкриває порт на хості;
не створює перенаправлення;
не робить сервіс доступним у браузері.
Щоб опублікувати порт, під час запуску контейнера все одно потрібен параметр -p:
docker run --name web-server -d -p 8080:80 nginx:alpineУ готових образах, як-от Nginx, інформація про порт може бути вже зазначена в описі образу, але правило доступу з хоста все одно задається під час запуску контейнера.
На одному хості конкретний порт може бути зайнятий лише одним процесом або правилом перенаправлення.
Після запуску першого контейнера на порту 8080 така команда може завершитися помилкою:
docker run --name another-web -d -p 8080:80 nginx:alpineПричина — порт 8080 хоста вже використовується.
Для другого контейнера виберіть інший порт:
docker run --name another-web -d -p 8081:80 nginx:alpineТепер контейнери доступні за різними адресами:
http://localhost:8080
http://localhost:8081Обидва контейнери можуть використовувати порт 80 всередині себе, оскільки кожен контейнер має власний мережевий простір.
Можна запустити контейнер без -p:
docker run --name private-web -d nginx:alpineУ цьому випадку Nginx працює на порту 80 всередині контейнера, але порт хоста для нього не створюється.
Такий контейнер не буде доступним через http://localhost:80 лише тому, що Nginx слухає порт 80 у контейнері.
Перенаправлення потрібно вказати явно:
docker run --name public-web -d -p 8080:80 nginx:alpineЗа замовчуванням Docker використовує TCP:
docker run --name web-server -d -p 8080:80 nginx:alpineПротокол можна вказати явно:
-p 8080:80/tcpДля UDP використовується суфікс /udp:
-p 5353:5353/udpКонкретний протокол залежить від програми, яка працює в контейнері. Для звичайного HTTP зазвичай використовується TCP.
Неправильно:
docker run --name web-server -d -p 80:8080 nginx:alpineЦе означає: порт 80 хоста перенаправляється на порт 8080 контейнера. Але Nginx у цьому образі слухає порт 80, а не 8080.
Правильно:
docker run --name web-server -d -p 8080:80 nginx:alpineЗапам’ятайте порядок:
порт хоста : порт контейнера-pКоманда:
docker run --name web-server -d nginx:alpineне публікує порт на хості. Для доступу з браузера потрібен параметр -p.
Якщо порт хоста вже використовується, виберіть інший:
docker run --name web-server -d -p 8081:80 nginx:alpineЯкщо контейнер запущено так:
docker run --name web-server -d -p 8080:80 nginx:alpineпотрібно відкрити:
http://localhost:8080а не:
http://localhost:80У браузері використовується порт хоста — 8080.
Порт контейнера — це порт, на якому програма слухає всередині контейнера.
Порт хоста — це порт вашого комп’ютера, доступний для браузера або інших клієнтів.
Перенаправлення портів задається параметром -p.
Формат запису: -p ПОРТ_ХОСТА:ПОРТ_КОНТЕЙНЕРА.
Команда -p 8080:80 робить порт 80 контейнера доступним через порт 8080 хоста.
EXPOSE описує порт контейнера, але не публікує його на хості.
Один порт хоста не можна одночасно призначити кільком контейнерам.
Для доступу лише з локального комп’ютера можна використовувати 127.0.0.1.