Dockerのnetwork_mode: hostとは?CodespacesでMaven Centralに繋がらない原因と回避策

2026年9月17日
DockerインフラLinux
Dockerのnetwork_mode hostとbridgeの違いのイメージ

Dockerのネットワークモードは、コンテナがどの経路で外部と通信するかを決める設定です。

普段はあまり意識しません。bridgeという標準モードが、面倒な部分を裏で処理してくれるからです。

ところが今回、GitHub Codespaces上のMavenコンテナだけが、この標準モードでつまずきました。

ホストOSからは repo.maven.apache.org を問題なく名前解決できます。同じCodespaces上のMavenコンテナからは、これができませんでした。

「Mavenかpom.xmlの設定が悪いのでは」と疑いたくなるところですが、そうではありません。原因は、Dockerコンテナ側のネットワーク経路にありました。

本記事では、bridgeとhostで通信経路がどう変わるのかを図で整理します。そのうえで、なぜ network_mode: "host" への変更だけで直ったのかを解説します。

主なネットワークモード

Dockerには、コンテナの通信経路を決める設定がいくつか用意されています。代表的なのは、次の4つです。

モードコンテナのネットワーク用途
bridgeDocker専用ネットワークを使う一般的なDocker
hostホストOSのネットワークを直接使うネットワーク制約を回避したい場合など
noneネットワークなし完全に通信させたくない場合
container:<名前>別コンテナとネットワークを共有特殊な構成

このうち、何も指定しなければ自動的に選ばれるのが bridge です。今回のMavenコンテナも、本来はこの設定でした。

services:
  java:
    image: maven:3.8.5-openjdk-11

これだけの記述で、Dockerはコンテナ専用のネットワークを作り、その中にコンテナを接続してくれます。普段は、この自動処理を意識する必要がありません。

bridge のイメージ

今回の構成を単純化すると、次のようになります。

bridge モードの経路
GitHub CodespacesホストOS

Docker bridge network

Mavenコンテナ127.0.0.11 Docker DNS
インターネット

GitHub Codespacesというホストの中に、Docker bridge networkという「もう一枚のネットワーク」が重なっている構造です。今回つまずいたのは、この二重構造の内側でした。

コンテナから curl https://repo.maven.apache.org を実行すると、まず名前解決が必要になります。ドメイン名をIPアドレスに変換する、あの処理です。

コンテナ内の名前解決
repo.maven.apache.org
Docker DNS127.0.0.11
外部DNS
IPアドレス

そこで切り分けのため、ホストとコンテナの両方から同じドメインを引いてみました。結果は、次のとおりです。

場所名前解決
CodespacesホストOK
DockerコンテナNG

同じCodespaces環境なのに、片方だけ失敗する。つまりMavenそのものではなく、Dockerコンテナ側のネットワーク経路で名前解決できていなかったわけです。

host モードとは

ここで network_mode: "host" を指定すると、構成が大きく変わります。

host モードの経路
GitHub CodespacesホストOSのネットワーク
Mavenコンテナhost network
インターネット

コンテナはDocker独自のネットワークを持たなくなり、ホスト側のネットワークをそのまま借りる形になります。いわば、コンテナとホストが同じ土俵に立つイメージです。

これにより、コンテナ → Docker bridge → Docker DNS(127.0.0.11) という、先ほど詰まっていた経路そのものを使わなくなります。

要するに、ホストでは通信できるのに、Docker bridge側だけがおかしい——そんなケースに host はよく効きます。問題のある経路を丸ごと迂回してしまうからです。

なぜ今回これで直ったのか

状況を整理すると、原因はシンプルです。Codespacesホストは repo.maven.apache.org を名前解決できるのに、Dockerコンテナだけができない。この一点に尽きます。

そこで network_mode: "host" にすると、経路は次のように変わります。

Mavenコンテナ → ホストのネットワーク → DNS → repo.maven.apache.org

コンテナが自前のDocker DNSを介さず、ホストの名前解決をそのまま使えるようになるわけです。結果として、mvn clean package はMaven Centralへ問題なく接続できました。

ここで押さえておきたいのは、Mavenの設定を直したわけではないという点です。Spring Bootのバージョンも、pom.xmlも変更していません。変えたのは、Dockerコンテナが外部ネットワークへ出ていくルートだけです。

ports が不要になる理由

もう一つ、見落とされがちな変化があります。それが ports の扱いです。

通常のDocker Composeでは、次のように書きます。

ports:
  - "8080:8080"

これは、ホストの8080番ポートとDockerコンテナの8080番ポートを橋渡しする、いわゆるポートフォワーディングです。

ところが host モードでは、この橋渡し自体が要らなくなります。コンテナがホストのネットワークをそのまま使うため、アプリがコンテナ内で 0.0.0.0:8080 で待ち受けていれば、その8080番ポートはホスト側でそのまま公開されるからです。そのため network_mode: "host" の場合、Dockerのポートマッピングは基本的に使いません。

つまり今回の構成は、次の形で成立します。

services:
  java:
    image: maven:3.8.5-openjdk-11
    network_mode: "host"

host は万能な解決策ではない

ここは、誤解しやすいポイントです。

host は、「ネットワーク周りが面倒だから、とりあえずhostにする」という便利設定ではありません。Dockerが本来持っているネットワーク分離を、意図的に弱める設定だからです。

たとえば frontend、backend、database を同時に動かす構成を考えてみてください。この場合は、通常どおり bridge network を使う方が自然です。frontend ── backend ── database のように、Dockerネットワークの中で安全につなぐ形が向いています。

一方、今回はそもそも条件が違いました。登場するのは GitHub Codespaces と Docker、Maven、そして外部の Maven Central です。問題はDocker側のネットワーク経路だけに限定されていました。だからこそ、host が有効な回避策になったわけです。

今回のケースを一言で言うと

通常の経路は、コンテナ → Docker bridge → Docker DNS → インターネット、です。今回は、まさにこの経路の途中で失敗していました。

そこで host モードに切り替え、コンテナ → ホストのネットワーク → インターネット、というシンプルな経路に変更しました。

今回やったことの対比

通常(失敗)

コンテナ
Docker bridge
Docker DNS
インターネット

hostモード(成功)

コンテナ
ホストのネットワーク
インターネット

Docker独自のネットワーク経路をバイパスした。 これが、今回 network_mode: "host" で解決した理由です。設定を疑う前に、まず経路を疑う——今回の教訓は、その一点に尽きます。

クラウドや業務システム、インフラ構成など、ITまわりでお悩みの際は、まずはお気軽にご相談ください。課題の整理から設計・開発まで、コンサルティングの形で伴走し、サイト構築や業務システム開発にも対応しています。

お問い合わせページへ