host.docker.internal とは

host.docker.internal はDockerコンテナからホストマシンに接続するための特別なホスト名。

ホストOSで動作しているPostgreSQLやRedisに、開発環境のコンテナから接続したい場面で利用できる。

Mac / Windows での利用

MacとWindowsではDocker Desktopが自動的に host.docker.internal を設定するため、追加の設定なしにコンテナからホストに接続できる。

Linux での利用

Linuxでは自動的に設定されないため、明示的な設定が必要。

docker run の場合

--add-host オプションで host.docker.internalhost-gateway に設定する。

$ docker run --add-host=host.docker.internal:host-gateway [イメージ名]

docker-compose の場合

extra_hosts に設定する。

services:
  app:
    image: [イメージ名]
    extra_hosts:
      - "host.docker.internal:host-gateway"

host-gateway はDocker 20.10以降で利用できる特別な値。ホストのブリッジネットワークのIPアドレスに解決される。

PostgreSQL への接続例

ホストOSで動作しているPostgreSQLにコンテナから接続する例。

ホストOSの PostgreSQL の設定

コンテナからの接続を受け付けるようにホストOSのPostgreSQLを設定する。

postgresql.conflisten_addresses* を設定して全アドレスでリッスンするようにする。

listen_addresses = '*'

次に pg_hba.conf にDockerのネットワーク(172.17.0.0/16)からの接続を許可する設定を追加する。

host    all             all             172.17.0.0/16           md5

設定変更後にPostgreSQLを再起動する。

$ sudo systemctl restart postgresql

コンテナから接続する

コンテナ内から host.docker.internal を使ってPostgreSQLに接続する。

$ psql -h host.docker.internal -U postgres -d mydb

アプリケーションの接続先URLは以下のように設定する。

postgresql://postgres:password@host.docker.internal:5432/mydb

Redis への接続例

ホストOSで動作しているRedisにコンテナから接続する例。

ホストOSの Redis の設定

デフォルトではRedisは 127.0.0.1 のみでリッスンしているため、Dockerからの接続を受け付けるように設定を変更する。

redis.confbind を変更する。

bind 0.0.0.0

設定変更後にRedisを再起動する。

$ sudo systemctl restart redis

コンテナから接続する

コンテナ内から host.docker.internal を使ってRedisに接続する。

$ redis-cli -h host.docker.internal ping
PONG

アプリケーションの接続先URLは以下のように設定する。

redis://host.docker.internal:6379

接続確認

host.docker.internal が正しく設定されているかは、コンテナ内の ping コマンドで確認できる。

$ ping host.docker.internal
PING host.docker.internal (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: icmp_seq=0 ttl=64 time=0.138 ms

172.17.0.1 がDockerのブリッジネットワークのゲートウェイアドレス(ホストのIPアドレス)に解決されていれば正しく設定されている。