docker composeのdocker networkでフロントエンドとバックエンドの通信が名前解決できない

2021/12/06に公開
3

概要

docker-compose で、フロントエンド、バックエンド、DB サーバのコンテナを立ち上げました。
そのときに、コンテナネットワークでそれぞれの通信をすれば、開発者以外からは完全に閉じているネットワークができると思って作成しました。

今回作成した docker-compose は以下ようになります。
フロントエンドが React、バックエンドが Node.js(TypeORM)、DB サーバが MySQL といった構成で作成して、それぞれのコンテナに名前をつけました。

backend-container が db-container を参照し、frontend-container が backend-container を参照するように名前解決をしています。

version: "3.5"
services:
  frontend:
    build:
      context: "./project01_frontend"
      dockerfile: "Dockerfile.prod"
    container_name: frontend-container
    restart: always
    tty: true
    ports:
      - "80:80"
    env_file:
      - "./project01_frontend/.env"
    depends_on:
      - "db"
      - "backend"
  backend:
    build:
      context: "./project01_backend"
      dockerfile: "Dockerfile.dev"
    container_name: backend-container
    restart: always
    tty: true
    expose:
      - "4000"
    env_file:
      - "./project01_backend/.env"
    depends_on:
      - "db"
    command: ["./wait-for-db-container.sh", "yarn", "start"]
  db:
    image: mysql:5.7.34
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    container_name: db-container
    volumes:
      - ./project01_backend/initdb.d:/docker-entrypoint-initdb.d
    environment:
      MYSQL_DATABASE: "typeorm_db"
      MYSQL_ROOT_PASSWORD: "password"
      TZ: "Asia/Tokyo"
    restart: "always"
    expose:
      - "3306"

結論

できません。ブラウザでnet::ERR_NAME_NOT_RESOLVEDというエラーが発生します。

コンテナ内で frontend-container から backend-container の名前解決はできます。
しかし、ブラウザからすると backend-container の名前解決ができないので、エラーが発生しています。
backend-container から db-container の名前解決は一応できています。

ですので、docker-compose を使うとしても DB とバックエンドをまとめてフロントエンドは別にするか、docker-compose を使わずに別々に作成することになります。

参考

https://stackoverflow.com/questions/69110280/how-to-take-place-name-resolution-neterr-name-not-resolved-error-is-occurred

https://qiita.com/ngplus6655/items/62a147afa74ca929dd2d

https://stackoverflow.com/questions/48573612/unable-to-have-docker-containers-communicate-with-each-other

https://stackoverflow.com/questions/57143314/cant-access-rails-api-backend-with-hostname-in-docker-compose

https://mherman.org/blog/dockerizing-a-react-app/

https://syoblog.com/react-nginx-docker/

https://qiita.com/penpenta/items/345abe43f8621cbdbbe5

https://marsquai.com/745ca65e-e38b-4a8e-8d59-55421be50f7e/f83dca4c-79db-4adf-b007-697c863b82a5/3956cdb7-44ac-410b-b9bc-508c341a45ca/

https://codechacha.com/ja/dockerizing-react-with-nginx/?_gl=17ol36q_ga*MGVZRGtkTVFIUk8xaUllRlZiQTk1TmRoay00UU92ZDJNUFZTb2NrUHJRTEFsZnpGZmZRWjdxYldtUTlHMzdyVQ

Discussion

hiszukhiszuk

フロントエンドが違うので参考なるか分かりませんが、nuxtでは以下の様に解決しました。
https://zenn.dev/hiszuk/articles/b91fca05f38949784390
フロントエンド起動時に環境変数を渡せればなんとかなります。

mskmsk

コメントのほどありがとうございます。
紹介していただいた記事は、バックエンドもコンテナで起動してコンテナ名を与えている場合ですかね?
この記事で書きたかったのはコンテナに環境変数を与える方法ではなく、「docker-composeで複数のコンテナを起動したときに、コンテナ名をつける。そのコンテナ名をつかってブラウザからバックエンドにアクセスできるか」ということでした。
結局のところ、フロントエンドのコンテナがバックエンドのコンテナを名前解決できても、ブラウザはバックエンドのコンテナを名前解決できない、ということを伝えたかった次第です。

hiszukhiszuk

そういう意味では、フロントエンドとバックエンドは直接通過は出来ませんね。