Dockerコンテナからホストへのアクセス:host.docker.internalとhost-gateway設定ガイド

「開発中のWebアプリをDockerコンテナで起動し、ホストマシンのローカル開発用MySQLに接続したい。」
これは非常に一般的なシナリオですが、多くの開発者がここで躓きます。
コンテナの設定でDB_HOST=localhostと指定しても、接続エラーが発生するのです。
「なぜ?ローカルでMySQLは動いているのに!」
理由は簡単です。コンテナにとってのlocalhost(127.0.0.1)はコンテナ自身であり、あなたのPC(ホスト)ではないからです。
この記事では、コンテナの中から「外側」のホストマシンに正しくアクセスするための、モダンでクロスプラットフォームな解決策を紹介します。
問題の理解:なぜlocalhostではダメなのか
Dockerコンテナは、独立したネットワーク名前空間を持っています。これは、コンテナが独自のIPアドレス、ポート範囲、ルーティングテーブルを持っていることを意味します。
- ホストのlocalhost: あなたの物理マシン(127.0.0.1)
- コンテナのlocalhost: そのコンテナ内部(127.0.0.1)
コンテナ内でcurl http://localhost:3306を実行するのは、コンテナ自身の3306番ポートにアクセスしようとしているのと同じです。もちろん、そこにはMySQLはいません。
解決策:host.docker.internal
Dockerは、この問題のために特別なDNS名を用意しています:host.docker.internal です。
これを使うと、Dockerが自動的にホストマシンの内部IPアドレスに解決してくれます。
ケース1: MacとWindows (Docker Desktop)
MacとWindowsのDocker Desktopユーザーにとって、話は非常に簡単です。この機能はデフォルトで有効になっています。
接続文字列を以下のように変更するだけです:
- Before:
mysql://user:pass@localhost:3306/db - After:
mysql://user:[email protected]:3306/db
これだけで繋がります。設定変更は不要です。
ケース2: Linux (Docker Engine)
Linux版のDockerでは、歴史的にこの機能はサポートされていませんでした。しかし、Docker 20.10以降、--add-hostフラグを使うことで簡単にサポートできるようになりました。
docker runコマンドの場合:
docker run -d \
--add-host host.docker.internal:host-gateway \
--name my-app \
node-apphost-gatewayというキーワードがポイントです。これは「ホストへのゲートウェイIP」に自動置換されます。
全プラットフォーム対応の究極の設定 (Docker Compose)
チーム開発では、Macユーザー、Windowsユーザー、Linuxユーザーが混在することがあります。OSごとに設定を変えるのは面倒ですよね。
そこで、docker-compose.ymlに以下の設定を追加することをお勧めします。これで全OSでhost.docker.internalが使えるようになります。
version: '3.8'
services:
app:
build: .
# これを追加!
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
# これで統一できる
DB_HOST: host.docker.internalこの設定の素晴らしい点は:
- Linux:
host-gatewayが正しく解決され、機能します。 - Windows/Mac: もともと機能していますが、この設定があっても上書きされるか無視されるだけで、害はありません(Docker Desktopのバージョンによっては明示的な指定が推奨されることもあります)。
これで、OSを問わず DB_HOST=host.docker.internal で統一できます。
実践例:コンテナからホストのRedisに接続する
具体的な手順を見てみましょう。
前提: ホストマシン(あなたのPC)でRedisが動いていて、ポート6379で待受している。
重要: ホスト側のRedis設定で、bind 127.0.0.1となっている場合、外部(コンテナ含む)からの接続を受け付けません。bind 0.0.0.0にするか、DockerネットワークのIP範囲を許可する必要があります。
第一歩:ホスト側サービスの準備
Redisの設定ファイル(redis.conf)を確認します。
# 変更前
bind 127.0.0.1
# 変更後(注意:セキュリティリスクあり。ファイアウォールで制限することを推奨)
bind 0.0.0.0
# または特定のインターフェースのみ許可
# bind 127.0.0.1 172.17.0.1設定を変更したらRedisを再起動します。
第二歩:コンテナから接続確認
redis-cliを含むコンテナを使ってテストしてみましょう。
Mac/Windowsの場合:
docker run --rm -it redis redis-cli -h host.docker.internal
# host.docker.internal:6379> ping
# PONGLinuxの場合:
docker run --rm -it --add-host host.docker.internal:host-gateway redis redis-cli -h host.docker.internal
# PONG接続成功です!
よくあるトラブルシューティング
Q. host.docker.internalが解決できないと言われる
- Linux:
--add-host host.docker.internal:host-gatewayを忘れていませんか? - Docker Compose:
extra_hosts設定を入れていますか? - Alpine Linux: まれに
glibcの問題で名前解決できないことがありますが、最近のバージョンではほぼ解消されています。
Q. Connection refusedになる
名前解決はできている(IPはわかっている)が、接続が拒否されています。
- ファイアウォール: ホスト側のファイアウォール(UFWやWindows Firewall)がDockerネットワークからの接続をブロックしていませんか?
- Bindアドレス: ホスト側のサービス(MySQLなど)が
127.0.0.1しかリッスンしていない可能性があります。0.0.0.0に変更して確認してください。
結論
コンテナからホストへのアクセスは、開発環境では頻出の要件です。
OSごとの違いに悩まされるのはもう終わりにしましょう。docker-compose.ymlにextra_hostsを1行追加するだけで、チーム全員が幸せになれます。
extra_hosts:
- "host.docker.internal:host-gateway"この魔法の1行を、あなたのプロジェクトのボイラープレートに追加しておくことを強くお勧めします。
Dockerコンテナホストアクセス設定フロー
host.docker.internalを使用してコンテナからホスト上のサービスに接続するための設定手順
⏱️ Estimated time: 15 min
- 1
Step1: 問題と解決策を理解する
問題:コンテナ内のlocalhostはコンテナ自身を指すため、ホストに繋がらない。
解決策:host.docker.internalという特殊ドメインを使用する。これはホストのIPに自動解決される。 - 2
Step2: Mac/Windowsでの設定
設定不要。Docker Desktopはデフォルトでhost.docker.internalをサポートしている。
使用例:
environment:
DB_HOST: host.docker.internal - 3
Step3: Linuxでの設定(またはクロスプラットフォーム対応)
Linuxではデフォルトでサポートされていないため、docker-compose.ymlに設定を追加する。
設定例:
services:
app:
extra_hosts:
- "host.docker.internal:host-gateway"
これにより、Linuxでもhost.docker.internalが使えるようになり、Mac/Windowsでも問題なく動作する。 - 4
Step4: ホスト側のサービス設定確認
重要:ホスト側のサービス(MySQL, Redis等)が 127.0.0.1 のみでリッスンしている場合、コンテナからの接続は届かない(コンテナは外部扱い)。
対処:設定ファイルのbind addressを 0.0.0.0 に変更するか、ファイアウォール設定を確認する。
FAQ
なぜコンテナ内からlocalhostでホストに繋がらないのですか?
host.docker.internalは全OSで使えますか?
Linuxでは、Docker 20.10以降で --add-host host.docker.internal:host-gateway オプションを使うことで使用可能です。
Docker Composeなら extra_hosts を設定することで全OS対応にできます。
ホスト側のポートに繋がりません(Connection refused)
例えばMySQLが bind-address = 127.0.0.1 となっていると、ローカルループバック以外からの接続を拒否します。
コンテナはネットワーク的には「外部」からの接続となるため、0.0.0.0でリッスンするように変更する必要があります。
--network hostを使えば解決しませんか?
しかし、これはLinuxでしか動作せず(Mac/WindowsではVMの中で動くためホストに繋がらない)、コンテナのネットワーク隔離が失われるため、推奨される解決策ではありません。
2 min read · 公開日: 2025年12月17日 · 更新日: 2026年1月22日
関連記事
Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践

Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践
Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド

Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド
Next.js ユニットテスト実践:Jest + React Testing Library 完全設定ガイド


コメント
GitHubアカウントでログインしてコメントできます