Docker コンテナ内で動作する Chromium ブラウザのリモートデバッグポート (9222) を、ホストマシンや他のコンテナから接続可能にする方法を解説します。
Selenium Grid や Playwright などを使った E2E テスト環境では、Docker コンテナ内でブラウザを動かすことが一般的です。デバッグや自動化のために Chrome DevTools Protocol (CDP) を使用する場合、リモートデバッグポートへの外部接続が必要になります。
通常、Chromium に --remote-debugging-port=9222 と --remote-debugging-address=0.0.0.0 を指定すれば外部からアクセスできるはずですが、最近のバージョンではこれが機能しません。
Chromium を以下のオプションで起動しても、外部から接続できません。
chromium \
--remote-debugging-port=9222 \
--remote-debugging-address=0.0.0.0 \
--no-sandbox \
about:blank
コンテナ内で確認すると、0.0.0.0:9222 ではなく 127.0.0.1:9222 でリッスンしています。
$ netstat -tlnp | grep 9222
tcp 0 0 127.0.0.1:9222 0.0.0.0:* LISTEN 11/chromium
Chromium M113/M114 以降、セキュリティ上の理由から --remote-debugging-address=0.0.0.0 は内部的に 127.0.0.1 に強制リマップされるようになりました。
Chromium のソースコードには以下のような処理が含まれています。
// headless/lib/headless_browser_main_parts.cc
if (remote_debugging_address.IsIPv4AllZeros()) {
remote_debugging_address = net::IPAddress::IPv4Localhost();
} else if (remote_debugging_address.IsIPv6AllZeros()) {
remote_debugging_address = net::IPAddress::IPv6Localhost();
}
この変更の理由は、リモートデバッグポートがブラウザを完全に制御できる強力な機能であり、ネットワークに公開することは深刻なセキュリティリスクになるためです。
Chromium の Bug Tracker (Issue 1425667) でも報告されていますが、ステータスは「WontFix」となっており、意図的な仕様変更として扱われています。
Chromium 公式が推奨するワークアラウンドは以下の3つです。
Docker 環境では SSH トンネリングは現実的ではないため、socat によるポートフォワーディングが最も簡単な解決策です。
FROM debian:trixie-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
chromium \
socat \
# ... その他必要なパッケージ
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
Chromium は 127.0.0.1 でしかリッスンしないため、内部用のポート (例: 9223) を使用します。
# start-chrome.sh
exec /usr/lib/chromium/chromium \
--remote-debugging-port=9223 \
--remote-allow-origins=* \
--no-sandbox \
--disable-gpu \
about:blank
socat を使って 0.0.0.0:9222 から 127.0.0.1:9223 にフォワードします。
supervisord を使用している場合の設定例:
[program:chromium]
command=/usr/local/bin/start-chrome.sh
autostart=true
autorestart=true
[program:socat-debug]
command=/usr/bin/socat TCP-LISTEN:9222,fork,reuseaddr TCP:127.0.0.1:9223
autostart=true
autorestart=true
docker run -p 9222:9222 your-image
コンテナ起動後、ホストマシンから以下のコマンドで確認できます。
$ curl -s http://127.0.0.1:9222/json
[ {
"description": "",
"devtoolsFrontendUrl": "https://chrome-devtools-frontend.appspot.com/...",
"id": "...",
"title": "about:blank",
"type": "page",
"url": "about:blank",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/..."
} ]
JSON が返ってくれば成功です。
Apple Silicon (M1/M2/M3) Mac で Docker を使用する場合、追加の注意が必要です。
--platform linux/amd64 を指定して x86_64 イメージをビルドすると、Rosetta 2 でエミュレーションが行われます。しかし、Chromium は SSE3 命令セットを要求するため、Rosetta では正常に動作しません。
The hardware on this system lacks support for the sse3 instruction set.
ローカル開発時は ARM64 ネイティブでビルドし、本番デプロイ時のみ x86_64 でビルドする運用が必要です。
# ローカル開発用 (ARM64)
docker build -t my-image .
# 本番デプロイ用 (x86_64)
docker build --platform linux/amd64 -t my-image .
--remote-debugging-address=0.0.0.0 はセキュリティ上の理由で無効化されていますこの変更は Chromium の意図的なセキュリティ強化であり、将来的に元に戻る可能性は低いと考えられます。