Вот история.
У меня есть приложение (scala), которое работает в докере, определенном в docker-compose.yml
следующим образом:
app:
image: dmydlarz/foobar
ports:
- "9000:9000"
Когда он запускается с Docker, он прослушивает порты в соответствии с lsof -PiTCP -sTCP:LISTEN
как:
com.docke 631 darek 25u IPv4 0xd4ed8c6c9c16c231 0t0 TCP *:9000 (LISTEN)
com.docke 631 darek 26u IPv6 0xd4ed8c6c9c20bae9 0t0 TCP localhost:9000 (LISTEN)
Так что, как видите, он слушает как на Ip4, так и на Ip6.
Теперь, когда я запускаю свое приложение из командной строки / IntelliJ, оно успешно запускается и прослушивает порт 9000 (!) также.
Когда я перечисляю открытые порты, вот что у меня есть:
com.docke 631 darek 25u IPv4 0xd4ed8c6c9c16c231 0t0 TCP *:9000 (LISTEN)
com.docke 631 darek 26u IPv6 0xd4ed8c6c9c20bae9 0t0 TCP localhost:9000 (LISTEN)
java 53995 darek 249u IPv6 0xd4ed8c6c7ec3d8e9 0t0 TCP localhost:9000 (LISTEN)
3 процесса прослушивают порт 9000, 2 из них по одному протоколу Ip6.
При такой настройке приложение Docker всегда обслуживает запросы. Всегда означает для всех URL, которые я пытался:
curl http://[::1]:9000/...
curl http://127.0.0.1:9000/...
curl http://localhost:9000/...
Когда я убиваю приложение Docker, запросы обслуживаются локальным приложением.
Я заставил приложение Docker запускаться только на Ip4 с указанием адреса привязки:
app:
image: dmydlarz/foobar
ports:
- "127.0.0.1:9000:9000"
которые мешают запускать два процесса одновременно, но все же предыдущее поведение совершенно неловко для меня.
Итак, у меня есть 2 вопроса:
- Почему Docker молча скрывает порт на локальной машине? Почему он не блокирует запуск локального приложения на том же порте и позволяет обслуживать запросы, когда приложение Docker убивается?
- Почему мне удалось запустить 2 приложения по одному протоколу (ip6) и одному и тому же порту?