モノレポ開発におけるVSCode Dev Containersを活用した環境構築方法

こんにちは。 株式会社アドグローブ ソリューション事業部の平田です。

開発において開発環境がどのくらい整っているかは「保守のやりやすさ」や、単純に「やる気」に直結するものだと思います。
ということで今回は、モノレポ開発でVSCode Devcontainerを利用した、統一された綺麗な環境づくりを目指していきたいと思います。

これが正解ということではなく、自分が試してみたことの発信となりますが、ぜひ最後までご覧いただけますと幸いです。

目標

リポジトリに必要なサービス(今回は PHP と Node の両方)がすべて動作するコンテナをもう 1 つ用意し、そのコンテナ上で VSCode を開いて開発する」ことで、人による環境差異や環境構築を楽にすることが今回の記事の目標になります。

下記のような構成を目指します。

モノレポ開発について

1 つのリポジトリ内に複数のサービスを管理しながら開発していく手法です。
今回は、1 つのリポジトリ内にバックエンドとフロントエンドを含める形のモノレポ構成を前提に話を進めます。

Devcontainer について

簡単に言えば、開発者ごとに環境差異が発生しないようにするための仕組みです。
VSCode Dev Containers 拡張機能を利用して Docker コンテナ内を開発環境とすることで、全員で統一した環境で作業することができます。

marketplace.visualstudio.com

Multiple Containers(複数コンテナ構成) について

実は、もともとモノレポ開発ではMultiple Containersという利用方法があります。

root
├── .devcontainer
│   ├── backend
│   │   └── devcontainer.json
│   └── frontend
│       └── devcontainer.json
├── backend
├── frontend
└── docker-compose.yml

この方法は devcontainer.json を各サービスのコンテナ分用意して、接続したいコンテナを選択する形で運用します。

code.visualstudio.com

しかし、この方法は当然ですが backend のコンテナを選択した場合 frontend のソースをいじれませんし見ることもできません。
Git 操作とかも面倒になり複数の VSCode ウィンドウを開いたりコンテナを切り替える必要があるなど、運用が難しいケースがあります。

本題

では今回お勧めしたい運用方法を紹介します。(例としてbackendにLaravel, frontendにVueの構成です)

ディレクトリ構成

root
├── .devcontainer
│   ├── devcontainer.json
│   └── Dockerfile
├── backend
├── frontend
├── docker-compose.devcontainer.yml
└── docker-compose.yml

プロジェクトや言語により違いはあると思いますが、よくあるfrontendbackendが 1 つのリポジトリに存在しそれを docker-compose.yml で管理している構成です。

今回追加したのは.devcontainer/配下とdocker-compose.devcontainer.ymlファイルになります。
これらの追加したファイルで devcontainer 用の新しいコンテナを作成していきます。

.devcontainer/devcontainer.json

vscode の設定や拡張機能の指定、元にするコンテナイメージなどを json 形式で設定できます。

{
  "name": "DevContainer",
  "dockerComposeFile": [
    "../docker-compose.yml",
    "../docker-compose.devcontainer.yml"
  ],
  "service": "devcontainer",
  "workspaceFolder": "/workspace",
  "remoteUser": "root",
  "customizations": {
    "vscode": {
      "settings": {
        // VSCode設定
      },
      "extensions": [
        // VSCode拡張機能

      ]
    }
  },
  "remoteEnv": {
    "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
  }
}
  • dockerComposeFileでメインの docker-compose と devcontainer 用の docker-compose を指定します。
  • servicedocker-compose.devcontainer.ymlに記載されている devcontainer 用のコンテナ名を指定します。
  • remoteUserは root で指定してます。これは公式では推奨されていませんが大変なので割愛します。:参考
  • customizations.settingsは VSCode の設定を行います。customizations.extensionsは拡張機能の指定をします。
  • LOCAL_WORKSPACE_FOLDERはdevcontainer内からホストのPCとファイルパスを知りたい場合がある為定義しています。

containers.dev

.devcontainer/Dockerfile

devcontainer用のDockerfileになります。
好みやdevcontainer内で使いたいツールによって、大きく変わると思います。。

FROM ubuntu:latest

WORKDIR /workspace

RUN apt-get update && apt-get install -y \
    php-cli php-mbstring php-xml php-curl php-zip \
    npm nodejs \
    git unzip apt-transport-https ca-certificates curl gnupg2 lsb-release \
    && curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | apt-key add - 2>/dev/null \
    && echo "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list \
    && apt-get update && apt-get install -y \
    docker-ce-cli \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN curl -sSL "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \
    -o /usr/local/bin/docker-compose \
    && chmod +x /usr/local/bin/docker-compose
  • ベースイメージとしてUbuntuを指定しています。
     Microsoft系の元からphpやnodeなどが入ってるイメージ使うのもありだと思います。:参考
  • phpやnodeはvscodeでフォーマットするのに必要なので入れています。
  • dockerはdevcontainer内からも使用したいので入れています。
     実際はホストのdockerデーモンを使用するためCLIだけです。:参考
  • その他使用したいものを入れてください。

docker-compose.devcontainer.yml

devcontainer用のdocker-composeになります。

services:
  devcontainer:
    build:
      context: ./.devcontainer
      dockerfile: Dockerfile
    container_name: devcontainer
    volumes:
      - ${HOME}/.ssh:/root/.ssh
      - /var/run/docker.sock:/var/run/docker.sock
      - node_modules_volume:/workspace/frontend/node_modules
      - vendor_volume:/workspace/backend/vendor
      - .:/workspace
    networks:
      - common
    stdin_open: true
    tty: true
  • ホストPCのsshキーとdockerを使用できるようにマウントしてます。
  • パッケージ群はホストPCにマウントせずコンテナ間のみでマウントしてます。
  • .:/workspaceでワークスペースすべてをマウントしてます。
  • -itオプションはベースイメージubuntuの場合必要になります。

devcontainer を立ち上げるとビルドが始まり VSCode ウィンドウの左下が開発コンテナー:DevContainerとなり、WORKSPACE/配下にbackendfrontendのソースディレクトリがあり root ユーザーで開けていることがわかります。

終わり

モノレポ開発で VCode Devcontainer を使った環境構築を行いました。
ホスト PC を汚さない方法として Devcontainer は有名ですが、モノレポ開発においては結構不向きだったので今回実験的に作成してみました。

最終的に今回作成していた環境が、下図となります。

他にもさまざまな設定が可能ですので、プロジェクトに合わせて試行錯誤していただければと思います。
最後までお読みいただき、ありがとうございました。


アドグローブでは、さまざまなポジションで一緒に働く仲間を募集しています!
詳細については下記からご確認ください。みなさまからのご応募お待ちしております。

採用情報