1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Linux / docker] docker containerから、localhostへアクセスしたいときのHack

1
Last updated at Posted at 2023-11-27

概要

dockerコンテナ内からlocalhostにアクセスしようとすると、アクセス先はコンテナ内になってしまいますよね。
でも、コンテナの外にあるホストOS上に他のサービスが立ち上がっていて、そのサービスにアクセスしたい場合って、きっとありますよね?(*´﹃`*)

(いつか図を書こう)

そんなときの対策。

結論

良さそうな方法は2つあるかなと思っています。

  1. container 内から host.docker.internal にアクセスする (※ リモートサーバでは使えない)
  2. localhostのIPアドレスをコンテナのネットワークに設定

それぞれ見ていきましょう。

1. container 内から host.docker.internal にアクセスする

host.docker.internal を使うと、 localhost へのアクセスとなるようです。動作検証してみます。

まず localhost 側で適当なサービスを起動します。

localhost で実行
python3 -m http.server 80

ここに、 docker コンテナ内からアクセスしてみましょう。ローカルマシンの MacOS 上では以下のような結果が確認できました。

dokcer コンテナ内
# curl host.docker.internal
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
<ul>
<li><a href=".env">.env</a></li>
<li><a href=".env.sample">.env.sample</a></li>
<li><a href=".gitignore">.gitignore</a></li>
<li><a href="docker-compose.yml">docker-compose.yml</a></li>
<li><a href="Dockerfile">Dockerfile</a></li>
<li><a href="requirements.txt">requirements.txt</a></li>
</ul>
<hr>
</body>
</html>

確かにいけますね。

ただ、これは本番環境用ではないと docker の公式ドキュメントに書かれているので、あくまでも実験環境用ですね。
Docker Desktop for Mac などの外では使えないようです。実際、リモートの EC2 上では確認できませんでしたし、おそらくリモートの Ubuntu サーバ上などでも使えないと思われます。

2. localhostのIPアドレスをコンテナのネットワークに設定

こっちは本番でも使えるかな、と思います。

次のコマンドで、HOST_IP_ADDRESSという環境変数にlocalhostのIPアドレスを設定できました。

$ export HOST_IP_ADDRESS=`ip -4 a show ens5 | grep inet | grep -v inet6 | sed -E "s/inet ([0-9]{1,3}.[0-9]{1,3}.[0-9].{1,3}.[0-9]{1,3}).*$/\1/" | tr -d "\t"`

※ens5は、AWS EC2上においてlocalhostのIPアドレスを指す名前でした。
 環境によってこの名前は異なるので、自身で$ ip aコマンドを打ってみて、どんな名前のブロックにlocalhostのIPアドレスがあるかを事前に確認してみましょう(^ワ^*)

 たとえば、私のwsl2で実行してみたところ、ens5ではなくeth0でした。

2-1. このコマンドはどうやって生まれたか

2-1-1. 最初 (ifconfigコマンドを利用)

最初はこの記事に書かれている方法でlocalhostのIPアドレス抽出を行っていました。

次のような感じです。

$ ifconfig en0 | grep inet | grep -v inet6 | sed -E "s/inet ([0-9]{1,3}.[0-9]{1,3}.[0-9].{1,3}.[0-9]{1,3}) .*$/\1/" | tr -d "\t"`
    172.000.000.255

2-1-2. 最終系 (ipコマンドを利用)

しかし、ifconfigコマンドは非推奨という次のような記事を見かけたので、

今度は、次の記事に書かれていた$ ip -4 a show ens4というコマンドを流用させていただきました。

スペースをちょっと書き換えて次のように修正したら、期待通りの動きになりました。

$ ip -4 a show ens5 | grep inet | grep -v inet6 | sed -E "s/inet ([0-9]{1,3}.[0-9]{1,3}.[0-9].{1,3}.[0-9]{1,3}).*$/\1/" | tr -d "\t"
    172.000.000.255

(正規表現あんまりわかってないので、偶然の産物です)

感想

元の記事からほんのちょっとしか書き換えてないけど、とはいえ、これだけのために結構時間を食ったので、記事にしておくことにしました(。ŏ﹏ŏ)

参考資料

--add-host

docker compose は使っていなくて、あくまでも docker 単体であれば、--add-host というオプションを使う方法もあるらしい。以下の記事で解説されていました。

色々な方法

自分は試していないけれども、以下の記事に色々な方法が書かれている。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?