LoginSignup
7
4

More than 1 year has passed since last update.

Dockerでlocalhostが立たない!そんな時はここをみて!

Last updated at Posted at 2022-10-14

最近、GoTypeScriptを使って個人開発しているときに、Goのサーバーが立たないということがありました。

色々調べても中々分からず結構手こずってしまい、友達に聞いたところ3分くらいで解決しました。
そこで言われたのが、Docker ポートフォワーディングで調べてみてって言われて調べたら解決したので、今回はそれを記事にしようと思います。

Dockerのポートフォワーディングとは

まず、docker-compose.ymlファイルを見てみましょう。

docker-compose.yml
version: '3.9'
services:
  backend:
    build:
      context: .
      dockerfile: ./docker/backend/app/Dockerfile
    tty: true
    volumes:
      - type: bind
        source: ./backend
        target: /api
    ports:
      - "8080:8080"

これでサーバーを立ててみると、
image.png
このようになるわけです。

その原因の部分が、

docker-compose.yml
    ports:
      - "8080:8080"

このポート番号が「:」で右と左に分かれています。
この記号を使うことで、コンテナのポート番号と、ローカルのポート番号を紐づけることができます。
右がコンテナのポート番号で左がホスト(あなた自身のパソコン)のポート番号です。

今回go run main.goを叩くと、ポート番号3000が呼ばれていたので、アクセスできなかったんですね。

アクセスできるようにするには、

docker-compose.yml
    ports:
      - "3000:8080"

こうすることで、ちゃんと接続することができます。
image.png

ここで少し公式ドキュメントを見てみると、このように書いてありました。

デフォルトの Docker コンテナは外の世界と通信できます。しかし、外の世界からはコンテナに接続できません。
公式ドキュメント

つまり、ブラウザからコンテナのポート番号にアクセスしようとしてもアクセスできないということが公式ドキュメントにも書いてありましたね。

Dockerのネットワークを調べてみる

ネットワークドライバー

Dockerではネットワークの扱いが重要で、Dockerのコンテナ内ではコンテナで1つのプロセスだけを動かすのが定石です。
つまり、1つのコンテナにGoUbuntuを動かすといったことはあまりしない方がいいんですね。
1つのコンテナにつき、1つのプロセスで構成し、それぞれで通信をするのがいいんですね。
以下の画像のような感じです。
image.png
入門 Dockerより引用)

そのネットワークを構成するものとして代表的なものが2つあります。
それが、bridgehostです。

bridge

Dockerのネットワークを構成する上で、デフォルトがbridgeです。
何も指定しなければ、ネットワークを構成するものとして、ブリッジが採用されます。
ブリッジは、簡単にいうと、次にどこにいくかを指示してくれる機械です。(厳密には違いますが、ここでは気にしないこととします)

ブリッジを使うことで、コンテナ間で通信をしてくれるわけですね。

実際に見てみましょう。
以下のようなコマンドを叩くことで、dockerのネットワークにブリッジがあることがわかります。

$ docker network ls  

NETWORK ID     NAME                    DRIVER    SCOPE
47ddb51d32a4   bridge                  bridge    local
d7d8e86102f6   host                    host      local
ca24a558faf1   none                    null      local

bridgeがあることが確認できました。

host

hostネットワークは、そのホスト(あなた自身のPC)の構成と同じで、コンテナとホストで使用できるポートを共有します。つまり、
コンテナとローカルのネットワーク分離は行われないため、性能は向上します。
ですが、現在ホストPCのOSがLinuxの時にしか、このネットワークは使えないんです。
Docker Desktop for MacDocker Desktop for WindowsDocker EE for Windows Serverでは使えないんですね。
その根拠が公式ドキュメントで書かれています。

ホストネットワークにおけるドライバーは Linux ホスト上においてのみ動作します。 Docker Desktop for Mac、Docker Desktop for Windows、Docker EE for Windows Server ではサポートされていません。

このような経緯があるから、docker networkのデフォルトにはブリッジが採用されているのかもしれませんね。

【参考資料】

7
4
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
7
4