ホストで動かしていたコンポーネント群をdocker-composeに乗せたところ、コンポーネント間の通信が通らなくなってしまった。
いずれもdocker-composeが作ったデフォルトのネットワークで動いているのでpingは通る。
コードを見てみたところサーバーがlocalhostでlistenしていたので 0.0.0.0
に修正した。
localhostは /etc/hosts
で 127.0.0.1
に解決されるわけだが、これはloopback interface lo
で通信するループバックアドレスで、自分自身を指す。
$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
...
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: si[email protected]: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
34: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
一方、0.0.0.0はDestinationに指定できないアドレスで、Sourceに指定するとネットワーク上のこのホスト、つまり全てのネットワークのアドレスで待ち受ける。この場合はlo
の 127.0.0.1
でも [email protected]
の 172.18.0.3
でもアクセスできる。
したがって、外部から通信するには 127.0.0.1
ではなく 0.0.0.0
または 172.18.0.3
でlistenする必要がある。
$ nc -l 0.0.0.0 12345 &
$ nc 127.0.0.1 12345
$ nc 172.18.0.3 12345