Dockerコンテナをrunで一度作ってしまうと、ポートフォワードの設定も一緒に固定されるようです。それのポートを変更する話です。
(※2016年当時の話で、今だとDocker Toolboxと呼ばれているもののTipsになります。当時もToolboxだったのかこれしかなかったのかは覚えてない…)
Dockerホストでポートフォワーディングする
Dockerコンテナはホスト内部でLANが組まれているような状態なので、単純にポートフォワードの設定をしてやればいいです。
Windowsの場合はVirtualBoxのコンソールからになります。
例えば172.16.0.2に向かって6006ポートを開けたいときは、
iptables -t nat -A DOCKER ! -i docker0 -p tcp -m tcp --dport 6006 -j DNAT --to-destination 172.17.0.2:6006
とします。
これで、ブラウザから http://192.168.99.100:6006/としてやると繋がります。
この192.168.99.100はWindowsの場合、Dockerホストが実行されているVMに設定されているIPで、VMのコンソールからifconfig eth1としてやるとついていることがわかります。
LinuxでDockerを設定してる場合は普通にhttp://localhost:6006/とかでいいと思います。
参考
コンテナを作り直す
とはいえ、上記の方法だと実はrunしたときと同じようにはなっていません。
runのときのオプションでポートを指定した場合、そのコンテナを開始するとiptablesにもポートフォワード設定がなされ、停止するとiptablesの設定も一緒に消えてくれるようになっています。
このあたりをオプションや設定ファイルの変更などで対応したかったのですが、どこにもみあたらなかったです…
なので、コンテナの内容を引き継ぎながら作り直してしまうのがよいかもしれません。
今度は通常のDockerを操作しているコンソールから、操作を行います。
コンテナイメージの作成
対象のコンテナを停止してから、
docker commit hoge fuge:fuga
のようにします。hogeはCONTAINER_IDまたはNAME、fugeはREPOSITORY、fugaがTAGになります。
これで
docker images
としてイメージを確認してみると、
REPOSITORY TAG IMAGE ID CREATED SIZE fuge fuga cefa656dde84 Less than a second ago 2.38 GB
というように作成されています。
イメージからコンテナを実行する
これは普通に
docker run --name new_container -itd -p 6006:6006 fuge:fuga
で、起動した状況を確認すると、
docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f1ac66e243be fuge:fuga "/bin/bash" Less than a second ago Up 17 seconds 0.0.0.0:6006->6006/tcp, 8888/tcp new_container
となっています。
参考:
docker-composeはどうしているのか
(2019/02/07追記)
docker-comopose.ymlにはports設定オプションがあり、ここにポートフォワードの設定をすることが出来ます。
もちろん途中で変更もできるのですが、ではどうしているのか確認してみました。
環境はWindows10Pro、Docker for Windowsです。
まず次のようなdocker-compose.ymlを用意します。
version: '3' services: app: image: nginx ports: - "8000:80"
nginxのイメージを使用してポート80を8000にフォワードしていいます。
こちらをupすると、http://localhost:8000でnginxのページが見えます。
>docker-compose up
このとき、コンテナは次のようになっていました。
>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3f3714f952e nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:8000->80/tcp tmp_app_1
コンテナIDはa3f3714f952eです。
このコンテナにexecして、ホームディレクトリにファイルを作っておいてみます。
>docker-compose exec app bash root@a3f3714f952e:/# cd root@a3f3714f952e:~# touch test root@a3f3714f952e:~# ls test root@a3f3714f952e:~#
このコンテナを停めてupしても、ファイルはあります。
>docker-compose stop Stopping tmp_app_1 ... done >docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES >docker-compose up -d Starting tmp_app_1 ... done >docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3f3714f952e nginx "nginx -g 'daemon of…" 8 minutes ago Up 4 seconds 0.0.0.0:8000->80/tcp tmp_app_1 >docker-compose exec app bash root@a3f3714f952e:/# cd root@a3f3714f952e:~# ls test root@a3f3714f952e:~#
ポートを8010に変更してみます。
version: '3' services: app: image: nginx ports: - "8010:80"
変更してからupしてみると、ファイルは消えて、コンテナIDも変わっています。
p>docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72872c27cc58 nginx "nginx -g 'daemon of…" 7 seconds ago Up 6 seconds 0.0.0.0:8010->80/tcp tmp_app_1 >docker-compose exec app bash root@72872c27cc58:/# cd root@72872c27cc58:~# ls root@72872c27cc58:~#
どうもコンテナを再作成しているようです。
リファレンスにも次のようにありました。
もしサービス用のコンテナが存在している場合、かつ、コンテナを作成後にサービスの設定やイメージを変更している場合は、 docker-compose up -d を実行すると、 設定を反映するためにコンテナを停止・再作成します(マウントしているボリュームは、そのまま保持します)。Compose が設定を反映させないようにするには、 --no-recreate フラグを使います。
コンテナは基本使い捨てで、消したくないファイルはちゃんとマウントしたところに作るのがよさそうです。
コメント
[…] iptablesで設定する。 Dockerコンテナのポートを後から解放する方法 の記事を見て、早速iptablesで設定をしてみる。 […]