ports публикует порт контейнера на хостовую машину и делает сервис доступным извне. expose указывает внутренние порты контейнера для связи внутри Docker-сети, но не публикует их на хост.
ports публикует порт контейнера на хостовую машину и делает сервис доступным извне. expose указывает внутренние порты контейнера для связи внутри Docker-сети, но не публикует их на хост.
Что делает ports
Поле ports задаёт проброс порта между хостом и контейнером. Формат HOST_PORT:CONTAINER_PORT означает, что запрос на порт хоста будет передан на порт приложения внутри контейнера.
services:
web:
image: nginx:alpine
ports:
- "8080:80"В этом примере Nginx слушает порт 80 внутри контейнера и становится доступен с хоста по адресу http://localhost:8080.
Что делает expose
Поле expose указывает порт, который предназначен для внутренних соединений между контейнерами. Оно не публикует этот порт на хостовую машину.
services:
db:
image: postgres:16
expose:
- "5432"Связь сервисов внутри сети
Контейнеры в одной Docker-сети обычно могут подключаться друг к другу по имени сервиса и внутреннему порту. Например, backend может обращаться к PostgreSQL по адресу db:5432, даже если порт базы не опубликован через ports.
Когда что использовать
ports — когда сервис должен быть доступен с хоста, из браузера или извне Docker-сети;
expose — чтобы обозначить внутренний порт сервиса без публикации на хост;
для базы данных в production часто не используют ports, если к ней не должен подключаться внешний клиент.
Безопасность
Не стоит публиковать на хост порты PostgreSQL, Redis, внутренних admin-сервисов и message brokers без необходимости. Чем меньше сервисов доступно извне, тем меньше поверхность атаки.
Как ответить на собеседовании
ports публикует порт контейнера на хост, например 8080:80. expose не открывает порт наружу, а указывает его для внутреннего взаимодействия сервисов. В Compose контейнеры обычно обращаются друг к другу по имени сервиса, например db:5432.
Оцени свой прогресс