30
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

Docker for Macで立てたコンテナから、ホストOSで動いているAPIサーバーにアクセスする方法

状況

  • Docker for Macを使っている(Docker version 1.13.0)
  • ホストOSのローカル環境でRails製のAPIサーバーを動かしている(以下、APIサーバーと呼ぶ)
  • Dockerコンテナ内で別のRailsアプリが動いており、このRailsアプリからホストOSで動いているAPIサーバーのAPIにアクセスしたい(以下、コンテナAと呼ぶ)
  • コンテナAからAPIサーバーにcurlでアクセスできれば良いので、curlでアクセスできるようにしたい
- エンドポイント
APIサーバー http://localhost:3000/items/
コンテナAのRailsアプリ ホストOSでは http://localhost:3001/ (コンテナ内では http://localhost:3000/ )

何も考えずにコンテナAからcurlでAPIのエンドポイントにアクセスすると、当然ですがコンテナAのRailsアプリのコンテンツが返されます。

$ curl http://localhost:3000/items/

じゃあどうすれば良いのか?

解決方法

ホストOSのAPIサーバーにアクセスするには、ホストOSのIPアドレスを指定する必要があります。
しかし、コンテナA内でlocalhostと指定するとコンテナA自身を指定することになります。
それではどのIPアドレスを指定するかというと、ホストOS側で独自のIPアドレスを設定する必要があります。

独自IPアドレスの設定方法

ホストOSにて

ifconfigコマンドを使います。
ifconfigはネットワーク・インタフェースの参照・設定・起動・停止などを行うコマンドです。
以下のようにlo0に対してipの設定を行います。

ところでlo0とは

lo0はloopback(ループバック)のことです。

マスタリングTCP/IP入門編より

ループバックアドレス
同じコンピュータ内部のプログラム間で通信したい場合に利用されるのがループバックアドレスです。ループバックアドレスとしては127.0.0.1というIPアドレスが使われます。この127.0.0.1と同じ意味で、localhostというホスト名も利用されます。このアドレスを利用した場合、パケットはネットワークには流れません。

ホストOSにて$ ifconfig lo0とするとinet 127.0.0.1 netmask 0xff000000とあるように、ここで127.0.0.1(localhost)が設定されていることがわかります。

ここから設定

話を戻して、ここから設定に入ります。
こちらの「I want to connect from a container to a service on the host」を参考にし、独自のIPアドレスを設定します。

$ sudo ifconfig lo0 alias 10.200.10.1/24

ifconfigで確認します。

$ ifconfig lo0
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
    options=3<RXCSUM,TXCSUM>
    inet6 ::1 prefixlen 128
    inet 127.0.0.1 netmask 0xff000000
    inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
    inet 10.200.10.1 netmask 0xffffff00 <-- ここの行が追加された -->
    nd6 options=1<PERFORMNUD>

以下の設定が追加されていればOKです。

    inet 10.200.10.1 netmask 0xffffff00

コンテナAにて

以下のようにcurlを実行するとAPIにアクセスできるはずです。

$ curl http://10.200.10.1:3000/items/

これで、コンテナAからホストOSのAPIサーバーにアクセスできるようになりました。

※ちなみにここで設定した独自IPアドレスの設定は、Macを再起動するとリセットされるので、再起動時は毎回手で設定し直す必要があります。さすがに面倒くさいので、Macの起動時に自動的に設定する方法を探すとログインフックという仕組みがありましたので、設定しておくと便利だと思います(MacOSXのログインフック設定)。

補足(独自のドメインを設定している場合)

ホストOSのlocalhostに対して、/etc/hostsで独自のドメインを設定している場合です。
例えば、localhostにlocal-hoge.comというホスト名でアクセスできるように設定しているとします。

コンテナAにて以下のコマンドを実行すると、

$ curl http://local-hoge.com/items/
curl: (6) Couldn't resolve host 'local-hoge.com'

となりホストの解決ができません。

そこでコンテナAの/etc/hostsに以下のような設定を追加するとホストの解決ができるようになり、アクセスできるようになります。

$ vi /etc/hosts

(以下を追記)
10.200.10.1 local-hoge.com

またはコンテナ起動時(docker run時)に以下のようにオプションを指定すると追加できます。

--add-host=local-hoge.com

Docker Composeを使っているなら、docker-compose.ymlに以下のように指定すると追加できます。

extra_hosts:
  - local-hoge.com

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
30
Help us understand the problem. What are the problem?