LoginSignup
1
1

実行済みのDockerコンテナに後からポート公開設定を行う

Last updated at Posted at 2024-01-06

実行済み(docker runした後)のDockerコンテナのポートを直ぐに公開したくなることがたまにある。
Dockerfileを作成するために、ベース(FROMで指定するDockerイメージ)のコンテナをdocker runで起動し、実際にパッケージのインストールなどを行いながら、Dockerfileにコマンド行を追加して行く作業は普通に行われることだと思う。
その途中にコンテナのポートを公開したくなったら、通常は以下の手順を経ることになる。

  • 一旦docker commitでDockerイメージとして保存
  • 現在のコンテナを停止&削除
  • 保存したDockerイメージをdocker runで起動する際に-pオプションでポート公開を設定

上記手順は1回だったら我慢できるが、それ以上は無駄で時間が掛かる作業が我慢できなくなる。

そこで市井の情報を漁ったところ、「iptablesでfirewall設定~Dockerのポートフォワードを後から変える方法~」が見つかった。
上記サイトを参考として、実行済みのDockerコンテナのポート公開設定を行うスクリプトを作成したので共有する。

※使い方はスクリプト内の usage: ~ __USAGE__ の間のメッセージを参照

dkport.sh
#!/bin/bash

# ref: https://momozo.tech/2020/05/16/iptables%E3%81%A7firewall%E8%A8%AD%E5%AE%9Adocker%E3%81%AE%E3%83%9D%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%92%E5%BE%8C%E3%81%8B%E3%82%89%E5%A4%89%E3%81%88%E3%82%8B/

if [ "$1" = "-s" ]; then
        echo "*** nat table ***"
        sudo iptables -t nat -S DOCKER | sed "/^-N/d" | sed "/RETURN$/d"
        echo "*** filter table ***"
        sudo iptables -t filter -S DOCKER | sed "/^-N/d"
        exit 0
fi

if [ "$3" = "" ]; then
        cat <<__USAGE__
usage:
  - show tables
    $0 -s
  - expose port
    $0 <running container> <source host port> <destination container port>
  - delete setting
    $0 <running container> <source host port> <destination container port> -d
__USAGE__
        exit 1
fi

option="-A"
optname="expose"
if [ "$4" = "-d" ]; then
        option="-D"
        optname="delete"
fi

set -euo pipefail

container=$1
srcport=$2
destport=$3

ipaddr=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $container`

sudo iptables -t nat $option DOCKER ! -i docker0 -p tcp -m tcp \
        --dport $srcport -j DNAT --to-destination $ipaddr:$destport
sudo iptables -t filter $option DOCKER -d $ipaddr/32 ! -i docker0 -o docker0 \
        -p tcp -m tcp --dport $srcport -j ACCEPT

echo "$optname: host $srcport -> $container $ipaddr:$destport"

exit 0

なお、docker container portでコンテナの公開ポートを表示することはできない。
また、コンテナを停止しても、dkport.shで追加したiptablesの設定は削除されない。

Docker Desktop for Windowsの話

Windowsの場合、netshコマンドで同様のことができるだろうと思い調べたところ、以下のドキュメントに記載の通り、ホストからアクセス可能なIPアドレスがLinuxコンテナに割り当てられないことが分かった。
Windowsコンテナには割り当てられるようだが、Windowsコンテナは個人的に使い道がない。

docker inspectでLinuxコンテナの情報を見ると、確かにNetworkSettings.IPAddressが空になっていることが分かる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1