Ответ
В работе с Docker мне часто нужно узнать, на какой хост-порт проброшен порт контейнера, для настройки балансировщиков или проверки связности. Использую несколько методов.
1. Команда docker port (самый прямой способ):
docker port <container_name_or_id> <container_port>
# Пример:
docker port my-nginx-container 80
# Вывод: 0.0.0.0:8080
Эта команда показывает маппинг только для явно опубликованных портов (флаг -p).
2. docker inspect с Go-шаблоном (для скриптов):
Когда нужно программно получить порт в скрипте сборки или мониторинга:
# Получить хост-порт для контейнерного порта 80/tcp
docker inspect --format='{{(index (index .NetworkSettings.Ports "80/tcp") 0).HostPort}}' my-container
# Более надежный вариант, который обрабатывает случаи, когда порт не опубликован:
HOST_PORT=$(docker inspect my-container --format='{{range $p, $conf := .NetworkSettings.Ports}}{{(index $conf 0).HostPort}}{{end}}')
if [ -n "$HOST_PORT" ]; then
echo "Port is mapped to: $HOST_PORT"
fi
3. Просмотр через docker ps:
Часто бывает достаточно посмотреть колонку PORTS:
docker ps --format "table {{.Names}}t{{.Ports}}" --filter "name=my-container"
Практический контекст:
В CI/CD пайплайне, после развертывания контейнера, я могу использовать docker port для динамического определения порта и запуска интеграционных тестов:
APP_PORT=$(docker port my-app 8080 | cut -d: -f2)
curl -f http://localhost:$APP_PORT/health
Важно: Для контейнеров в Docker Swarm или Kubernetes используются другие методы (сервисы, Ingress, kubectl get svc).
Ответ 18+ 🔞
А, ну это классика, блядь! Каждый раз, когда контейнер запускаешь, начинается: «А на какой порт, сука, он там приземлился?» Особенно весело, когда этих контейнеров, как собак нерезаных, и каждый тянет своё. Ёпта, сейчас расскажу, как не сойти с ума.
1. docker port — твой прямолинейный друг, но с приколами.
Вот ты запустил контейнер, а он молчит, как партизан. Хочешь узнать, куда стучаться? Команда — раз, и готово.
docker port <container_name_or_id> <container_port>
# Пример:
docker port my-nginx-container 80
# Вывод: 0.0.0.0:8080
Но тут, чувак, подвох! Эта команда показывает только то, что ты сам явно наружу высунул через этот самый -p. Если порт не публиковал — нихуя не увидишь, тишина. Так что имей в виду.
2. docker inspect с шаблонами — для тех, кто любит поковыряться в кишках.
Это уже для серьёзных пацанов, которые в скриптах всё автоматизируют. Выглядит, конечно, как заклинание древнее, но работает на ура.
# Выцепить хост-порт для 80/tcp
docker inspect --format='{{(index (index .NetworkSettings.Ports "80/tcp") 0).HostPort}}' my-container
# А вот вариант понадёжнее, на случай, если порт вдруг не опубликован. Чтобы скрипт не накрылся медным тазом.
HOST_PORT=$(docker inspect my-container --format='{{range $p, $conf := .NetworkSettings.Ports}}{{(index $conf 0).HostPort}}{{end}}')
if [ -n "$HOST_PORT" ]; then
echo "Port is mapped to: $HOST_PORT"
fi
Сам от себя охуевал, когда первый раз этот формат писал, но, блядь, привыкаешь. Главное — скопипастить правильно, а то будет тебе хиросима.
3. Старый добрый docker ps — быстрый взгляд.
Иногда не хочется заморачиваться, просто глянуть, что там творится. Колонка PORTS всё покажет.
docker ps --format "table {{.Names}}t{{.Ports}}" --filter "name=my-container"
Удобно, быстро, но деталей маловато. Зато сразу видно всю картину, если контейнеров несколько.
А вот где это реально в жизни пригождается, так это в CI/CD.
Представь: контейнер взлетел, а тестам надо на него наброситься. Порт-то динамический может быть! Вот и крутишь, как мартышлюшка, чтобы вытащить его и подсунуть в curl.
APP_PORT=$(docker port my-app 8080 | cut -d: -f2)
curl -f http://localhost:$APP_PORT/health
Работает — красота. Не работает — ну, блядь, идём искать, где накосячили.
И главное, запомни раз и навсегда: вся эта магия только для обычного Docker. Если у тебя там Swarm или, упаси боже, Kubernetes — это совсем другой цирк. Там свои команды, свои service и ingress. Так что не пытайся docker port на кластере применить — будет тебе волнение ебать, а толку ноль.