2018/09/03

Dockerコンテナ内のNginxからホストOSのlocalhostにアクセスする

開発するサービスが増えてくると、同じホスト名だけどパスによって違うサービスを表示したいことがある。たとえば、https://example.comならRailsで作ったメニューページ、https://example.com/serviceならNuxt.jsで作った別サービスといった具合だ。

できれば環境はローカルマシン内だけで完結させたいので、DockerコンテナにNginxでリバースプロキシを立ててパスによってlocalhostの違うポートにプロキシしたい。しかし、Dockerコンテナ内でlocallhostにアクセスしようとすると、コンテナ内のゲストOSのlocalhostにアクセスしてしまう。

ということでDockerコンテナ内からホストOSにアクセスする方法とまとめる。


環境は以下の通り。

  • macOS High Sierra
  • Docker CE Version 18.06.0-ce-mac70 (26399)
  • Nginx(Dockerコンテナ内)


Dockerコンテナ内のNginxからホストOSのサーバーにアクセスする


これからやることのイメージは下図のとおり。

ホストOS(ローカルマシン)に2つのサーバーを立ち上げる。ポート番号はそれぞれ3001と3002。ブラウザでhttp://localhost/service-aにアクセスしたときはlocalhost:3001に、http://localhost/service-bにアクセスしたときはlocalhost:3002にそれぞれプロキシする。


Dockerコンテナ内からホストOSにアクセスする

Dockerコンテナ内でcurl localhostをするとどこに行くか?もちろんコンテナのlocalhostになり、ホストOSにはアクセスできない。

そんなときは「host.docker.internal」をつかう。
### コンテナ内 ###

# localhostでアクセスする
$ curl localhost
curl: (7) Failed to connect to localhost port 80: Connection refused

# ホストOSにアクセスする
$ curl host.docker.internal
// response

$ curl host.docker.internal:3001

これでコンテナ内からホストOSにアクセスできるようになった。


Dockerコンテナ内のNginxからホストOSにアクセスする

次にNginxでリバースプロキシを立てて、そこからホストOSにアクセスできるようにする。
server {
  listen 80;
  server_name localhost 127.0.0.1;

  location /service-a/ {
    # http://localhost:3001/service-a になる
    proxy_pass http://host.docker.internal:3001;

    # OR  

    # http://localhost:3001 になる
    proxy_pass http://host.docker.internal:3001/;
  }

  location /service-b/ {
    proxy_pass http://host.docker.internal:3002/;
  }
}

proxy_passの最後に「/」をつけるかどうかでプロキシ先が変わるので注意。

  • http://host.docker.internal:3001
    • http://localhost:3001/service-aにプロキシされる
  • http://host.docker.internal:3001/
    • http://localhost:3001にプロキシされる



参考サイト






以上

written by @bc_rikko

0 件のコメント :

コメントを投稿