複数のdevcontainerを連結して開発できるようにした話

こんにちは、GROWI.cloud の開発・運用を担当している WESEEK のエンジニアの伊勢です。
今回は、 GROWI.cloud の開発で困った問題が起きて、その問題を解消した時の話をご紹介します。

背景

  • GROWI.cloud は node.js を主な言語として開発しており、そのプロジェクトを役割に応じて「プロジェクトA」「プロジェクトB」... と分割しています
  • この「プロジェクトA」「プロジェクトB」... が互いに通信することで、 GROWI.cloud のサービスは成り立っています
  • また最近になって、開発環境は VSCode の devcontainer(, docker-compose) を利用することになりました
  • 各プロジェクト単体での開発に限っては、他のプロジェクトとの連係に社内テスト環境を利用していたため、devcontainer 化の影響はありませんでした
  • 開発環境内で「プロジェクトA」と「プロジェクトB」を連係して開発する場合において、両プロジェクトの devcontainer 同士が通信できない状態に陥ってしまい、開発に支障が出てしまいました
  • そこで、devcontainer のネットワーク周りの設定を見直し、複数の devcontainer 間で通信できるよう開発環境を改善することにしました

やったこと

  1. devcontainer の docker-compose 起動時に network を指定できるように、 devcontainer 構築時に Docker ネットワークが無ければ自動的に作成されるよう設定を追加

     "initializeCommand": "if ! docker network ls | awk '{ print $2 }' | grep -qx 'growi-cloud-common'; then docker network create --driver bridge growi-cloud-common; fi",

    projectB でも同様の設定を追加することで、プロジェクトA, B どちらの devcontainer が先に起動しても同じ名前空間のネットワークに接続できます

    • 同じ Docker ネットワーク上では service 名で名前解決できます
  2. .devcontainer/docker-compose.yml の service 名がプロジェクトA, B で被らないように修正
    ※同じ Docker ネットワーク内ではサービス名が被っていると名前解決が正しくできないため、別プロジェクトであってもサービス名が被らないようにする必要アリ

    services:
     node: -> node-project-b:
    • これで、projectA の node.js アプリが node, projectB の node.js アプリが node-project-b と、名前解決できるようになりました
  3. .devcontainer/docker-compose.yml の network を同一のネットワークに接続するように設定

    services:
     node:
       networks:
         - growi-cloud-common
    
    networks:
     growi-cloud-common:
       external: true
    services:
     node-project-b:
       networks:
         - growi-cloud-common
    
    networks:
     growi-cloud-common:
       external: true
  4. 通信先を見直し
    ※devcontainer 化以前は、 localhost の「ポート番号」で通信先を振り分けていたが、サービス名を指定して通信できるようになったので、修正
    例) projectA → projectB に POST リクエストを送る場合

    (修正前) const res = await axios.post('http://localhost:3001/growi', params);
      ↓ ↓
    (修正後) const res = await axios.post('http://node-project-b:3001/growi', params);
  5. Rebuild Container する

    select_rebuild_command

やったことは以上です!
では、よい devcontainer LIFE を!

project_image