EXPOSE и -p оба про порты, но работают по-разному. Один объявляет намерение, другой реально открывает доступ.EXPOSE это документация, не настройка
EXPOSE в Dockerfile говорит только одно: "контейнер слушает этот порт". Это подсказка для разработчика и для Docker, но не более. Трафик снаружи всё равно не пройдёт:FROM node:18
EXPOSE 3000
CMD ["node", "index.js"]
После
docker build и docker run без дополнительных флагов порт 3000 недоступен с хоста. EXPOSE ничего не открывает.PUBLISH это реальное пробрасывание порта
Флаг
-p при запуске контейнера связывает порт хоста с портом контейнера. Вот это уже работает:# хост:контейнер
docker run -p 8080:3000 myapp
Теперь запрос на
localhost:8080 попадает в контейнер на порт 3000. Без -p — не попадает, даже если EXPOSE 3000 прописан.Варианты использования
-p:# конкретный порт хоста
docker run -p 8080:3000 myapp
# случайный свободный порт хоста
docker run -p 3000 myapp
# только на localhost хоста, не наружу
docker run -p 127.0.0.1:8080:3000 myapp
# все порты из EXPOSE на случайные порты хоста
docker run -P myapp
Последний вариант с
-P это единственный случай, когда EXPOSE влияет на поведение. Docker смотрит, какие порты объявлены через EXPOSE, и пробрасывает их все на случайные порты хоста.В Docker Compose
Та же логика, другой синтаксис.
expose — только между контейнерами внутри сети. ports — наружу на хост:services:
app:
image: myapp
expose:
- "3000" # видно другим сервисам в сети, не хосту
ports:
- "8080:3000" # видно хосту
Важный момент: контейнеры в одной Compose-сети и так видят друг друга по всем портам без
expose и без ports. Директива expose в Compose нужна только для явной документации намерений.EXPOSE — документация для людей и инструментов. На реальный трафик не влияет. -p / ports — реальное пробрасывание, без него порт снаружи недоступен.📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека devops'a
#арсенал_инженера
