Docker Engine SDK でホストポートを範囲指定する
コードは Go 言語ですが、他の SDK でも困っていたら、試してみるとうまくいくかもしれません。
検索しても、いまいち解決していなさそう
https://stackoverflow.com/questions/63236679/unable-to-port-forward-with-the-port-range-syntax-in-docker-sdk
"80-85:80"
(ホストポートを範囲指定する場合)
Dockerfile で EXPOSE
していても ExposedPorts
が必要な模様
https://qiita.com/ryskiwt/items/27cb74f621c9e9ee18be#%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E4%BD%9C%E6%88%90
起動途中や停止中に Docker Desktop 等で確認すると localhost:80-85
と表記されるが、起動が完了すると正しく 0.0.0.0:80
や 0.0.0.0:81
と表示される。
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: imageName,
ExposedPorts: nat.PortSet{nat.Port("80"): struct{}{}},
}, &container.HostConfig{
PortBindings: nat.PortMap{
nat.Port("80"): []nat.PortBinding{{HostPort: "80-85"}},
},
}, nil, nil, "")
if err != nil {
panic(err)
}
"80"
(ホストポートを指定しない場合、使用可能なポート番号を Docker が選択)
探すのにだいぶ時間を溶かした…
HostPort
に 0
を入れると Docker が使用可能なポート番号を選択するようになった。
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: imageName,
ExposedPorts: nat.PortSet{nat.Port("80"): struct{}{}},
}, &container.HostConfig{
PortBindings: nat.PortMap{
nat.Port("80"): []nat.PortBinding{{HostPort: "0"}},
},
}, nil, nil, "")
if err != nil {
panic(err)
}
または、書いてる途中で見つけた下記のように書いてもうまく行った。
こっちのほうが自然かも?
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: imageName,
ExposedPorts: nat.PortSet{nat.Port("80"): struct{}{}},
}, &container.HostConfig{
PortBindings: nat.PortMap{
nat.Port("80/tcp"): []nat.PortBinding{{HostPort: ""}},
},
}, nil, nil, "")
if err != nil {
panic(err)
}
試行錯誤した記録
// NG (127.0.0.1:49179 になってしまう)
nat.Port("80"): []nat.PortBinding{{HostPort: ""}},
// NG (ポートバインドされない)
nat.Port("80"): []nat.PortBinding{{HostIP: "0.0.0.0"}},
// NG (ポートバインドされない)
nat.Port("80"): []nat.PortBinding{{}},
Docker Engine Go SDK リファレンスやAPI リファレンスで見つからなかったため、SDKリファレンスでリンクされていたリポジトリも探したが力不足で見つからなかった。
ふと、お手本でコマンドで起動させていたポート範囲指定コンテナを停止すると、localhost:80-85
と表示されている…(起動時は 0.0.0.0:81
だった)
ホストポート指定なしのお手本コンテナも停止させて、ポートを確認すると 0.0.0.0:0
の表示
もしやと思い、
nat.Port("80"): []nat.PortBinding{{HostPort: "0"}},
としたところ、Docker が使用可能なポート番号を探して使用するようになった!
最後に
Docker Engine SDK のドキュメントもう少し情報が欲しい…