Docker上のNode.jsサーバーにcurlしたらConnection reset by peerが返ってくる

VirtualBoxでUbuntuを立ててその中でDockerコンテナを使っていて嵌ったので備忘録として書いておく。

#結論
Docker上のNode.jsサーバーの`host`を`0.0.0.0`に変更

```shell-session:host-machine
$ docker exec -it node-container_1 bash
bash-5.0$ cd /path/to/project/
bash-5.0$ gatsby develop --host=0.0.0.0
```


---

#状況

- Vagrant(VirtualBox)でUbuntuのVMを作成している
- VM上でNode.js(Alpine)のDockerコンテナを立てている

VMのUbuntuにて

```shell-session:Ubuntu(vm)
$ curl localhost:8000
curl: (56) Recv failure: Connection reset by peer
```
`Connection reset`される

しかし、`docker exec -it node-container_1 bash` 等でコンテナに入ると

```shell-session:docker
$ docker exec -it node-container_1 bash
bash-5.0$ curl localhost:8000
<!DOCTYPE html><html><head><meta charSet="utf-8"/>  ...
```
レスポンスが返ってくる。

#環境
##Ubuntu
```shell-session:ubuntu-version
$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```




##Docker

```shell-session:docker-version
$ docker version 
Client: Docker Engine - Community
 Version:           20.10.5
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        55c4c88
 Built:             Tue Mar  2 20:18:20 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.5
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       363e9a8
  Built:            Tue Mar  2 20:16:15 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```

##Docker-compose
一般的なNode.jsコンテナです。

```yml
version: "3.7"
services:
  node:
    build: 
      context: ./node
    user: "node"
    working_dir: /home/node/app
    environment:
      - NODE_ENV=development
    volumes:
      - ./node/app:/home/node/app
    restart: always
    expose: 
      - "8000"
    ports:
      - 8000:8000
    stdin_open: true
```

#原因

Dockerコンテナ内で `gatsby develop` すると通常は
`localhost:8000` をLISTENするようなサーバーが立ち上がる。

コンテナ内では `localhost`=>`127.0.0.1` に解決されるが、  
ホストマシンから見たコンテナのIPアドレスを確認すると、

```shell-session:ubuntu
$ ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:b8ff:feeb:e3a8  prefixlen 64  scopeid 0x20<link>
        ether 02:42:b8:eb:e3:a8  txqueuelen 0  (Ethernet)
        RX packets 21  bytes 3292 (3.2 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 27  bytes 12702 (12.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```
となり、ホストから見たコンテナのIPアドレスは`172.17.0.1` である。
(これはDockerによって自動的に決まるIPアドレス)


`127.0.0.1:8000` =x=> `172.17.0.1:8000`
となり`Connection Refuse`されてしまい、
コンテナとホストでLISTENしているIPアドレスが異なることが原因。

#対応
ホストからLISTENされているポートを確認すると、

```shell-session:ubuntu
$ docker ps -l
CONTAINER ID   IMAGE              COMMAND                  PORTS                                                                                                                NAMES
831fc56b8d87   node-container_1   "docker-entrypoint.s…"   0.0.0.0:8000->8000/tcp
```

なので、コンテナ内のアプリケーションでLISTENするホストを`0.0.0.0`(any IPv4-addresses) に変更すれば良さそうなので、


```shell-session:docker
$ docker exec -it node-container_1 bash
bash-5.0$ cd /path/to/project/
bash-5.0$ gatsby develop --host=0.0.0.0

```

コマンド実行時に `--host=0.0.0.0` を追加する。

#結果

```shell-session:ubuntu
$ curl localhost:8000
<!DOCTYPE html><html><head><meta charSet="utf-8"/>...
```

無事正常なレスポンスが得られました。



#参考
- https://qiita.com/amuyikam/items/01a8c16e3ddbcc734a46
- https://qiita.com/toshihirock/items/f5b9f7799ec8bf8c328e
- https://www.gatsbyjs.com/docs/reference/gatsby-cli/
- https://ja.wikipedia.org/wiki/0.0.0.0