Вот история. У меня есть приложение (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 вопроса:

  1. Почему Docker молча скрывает порт на локальной машине? Почему он не блокирует запуск локального приложения на том же порте и позволяет обслуживать запросы, когда приложение Docker убивается?
  2. Почему мне удалось запустить 2 приложения по одному протоколу (ip6) и одному и тому же порту?

0