👩‍🍳

Docker Compose な開発環境にちょい足し3分で作るVSCode devcontainer

2022/05/08に公開

こんにちは、devcontainer職人です🧑‍🍳

今回紹介するのはDocker Composeを既に利用している開発環境にかんたんにdevcontainerを構築する方法を紹介します。

VSCodedevcontainerはとても良くできた開発環境構築方法なのですが、ちょっと難しそうと思われていたり、VSCode以外のエディタを使う人の開発体験が悪くなるのでは、などの懸念がありまだあまり使われていないような印象があります。今回はそんなdevcontainerを3分で作れるtipsを紹介します。

準備するもの

Docker Composeで構築した開発環境のサンプル

今回用意するのはサンプルとしてRuby on Railsの開発環境のdocker-compose.ymlを用意しました。RubyとPostgreSQLの構成です。

※ Node.js, Pythonの環境のサンプルは文末のサンプルを参照してください

docker-compose.yml, Dockerfile
docker-compose.yml
version: '3'

services:
  app:
    build:
      context: .
      dockerfile: docker/app/Dockerfile
    env_file: .env
    ports:
      - 3000:3000
    volumes:
      - .:/workspace:cached
      - bundle-volume:/workspace/vendor/bundle
      - node-module-volume:/workspace/node_modules
    depends_on:
      - postgres
    command: 'bin/rails s'
  postgres:
    image: postgres:14
    restart: unless-stopped
    volumes:
      - postgres-volume:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: pg
      POSTGRES_PASSWORD: password
    ports:
      - 5432:5432
volumes:
  postgres-volume:
  bundle-volume:
  node-module-volume:
Dockerfile
FROM ruby:2.7.6-bullseye

ENV BUNDLE_APP_CONFIG=/workspace/.bundle

# Install nodejs, yarn
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get update && apt-get install -y nodejs
RUN npm install -g yarn

RUN gem install bundler -v 2.3.13

WORKDIR /workspace

仕様をざっと説明すると

  • app, postgresのコンテナがある
  • app
    • volumes
      • .:/workspace:cached ← カレントディレクトリとコンテナのworking_dirとでbind mountしている
      • bundle-volume:/workspace/vendor/bundle
      • node-module-volume:/workspace/node_modules
    • command: bin/rails s ← サーバーが起動するコマンドが指定されている

ターミナル等でdocker compose up app を実行するとサーバーが立ち上がるように構成されています。

では、こちらのappをdevcontainer化します。

devcontainer化する

用意する2つのファイル

今回は2つのファイルを用意します。

  • devcontainer.json: devcontainerの設定ファイル。必須
  • docker-compose.yml: 今回は既存のdocker-composeをオーバーライドするために作成する

今回はdevcontainerを"かんたん"につくるを目的とするため、devcontainerに必要な最小の設定だけ行います。2つのファイルを既存のプロジェクトに .devcontainer ディレクトリを作成し配置します。

.devcontainer/devcontainer.json
{
  "dockerComposeFile": ["../docker-compose.yml", "docker-compose.yml"],
  "service": "app",
  "workspaceFolder": "/workspace"
}
.devcontainer/docker-compose.yml
version: '3'

services:
  app:
    command: sleep infinity

以上です。

※ ご自身の環境で作成する場合は、ご自身が持つ手元のdocker-composeのサービス名をご利用ください。

devcontainerを起動する

VSCodeでプロジェクトのディレクトリを開き、 Reopen folder in Container を実行します。

これで完了です。devcontainerを起動することができました。

解説

解説を読みたい人はよんでください

devcontainer.json

  • dockerComposeFile: devcontainerを起動するのに利用するdocker-compose.ymlの場所を指定します。複数指定可能でその場合は設定がオーバーライドされる。
  • service: devcontainerとして起動するコンテナ名
  • workspaceFolder: devcontainerで展開するワークスペースのルート

devcontainer.jsonのプロパティの詳細はこちら

docker-compose.yml

既存のdocker-compose.ymlをオーバーライドするために用意している。

services:yml:.devcontainer/docker-compose.yml
  app:
    command: sleep infinity

とすることで、既存の command: 'bin/rails s' をオーバーライドし、単に何もせずプロセスを起動しっぱなしにする。

devcontainerの要件としては、 起動しているコンテナにアタッチできればよい ので設定としてはこれだけでokです。

devcontainerを立ち上げる方法

devcontainerを立ち上げる方法として主に

  1. imageを利用する
  2. devcontainer用のDockerfileを用意する
  3. devcontainer用のdocker-compose.ymlを用意する
  4. 既存のDokcer Composeをオーバーライドする
  5. kurbernetes上のcontainerにアタッチする

などがあります。 devcontainerはテンプレートがVSCode公式でDockerfileが公開されていて Remote - Containers extensionAdd Development Container Configuration Files.. から利用することができます。各言語の即席の環境が用意されていて多くは2か3の方式です。

今回は4の既存のDokcer Composeをオーバーライドする方式をとっています。

※ 今回紹介する2つの設定ファイルは Existing Docker Compose (Extend) テンプレート から最小限の設定に変更したものです。

既存のDokcer Composeをオーバーライドする方式のメリット

  • これまでのDocker Composeの知識を使い回せる
  • 既に作成しているdocker-compose.ymlを使い回せる
  • VSCodeを使う人はdevcontainerで最高の開発体験が得られる
  • named volumeを使うとHostOSからは隠蔽されるためファイルの参照ができなくなるが、devcontainer内からは見えるため、Dockerの高速化とIntellisenseやGo to Definitionのコードの参照が両立できる
  • VSCode以外のエディタで作業する人もこれまで通りDocker Composeを利用して開発できる
  • ファイル操作が不要でプログラムを起動する場合は従来どおり docker compose up から起動できる

などがあります。devcontainerは便利だけど、VSCode以外の開発環境で開発している人の開発体験の質を落としたくないという理由から、この方式を個人的にはよく使います。

おわりに

今回はdevcontainerを3分で作る方法を紹介しました。開発環境をdevcontainerのために1から作り直す必要がなく、今までのDocker Composeな開発環境にすぐ導入することができます。

devcontainer.jsonextensionssettings VSCodeの拡張機能や設定をdevcontainerとしてパッケージできたり、ライフサイクルスクリプトで起動時に実行するスクリプトを自動化することでより便利に利用できますが、今回はかんたんに構築することを紹介することで利用のハードルが下がればなと思って省略しました。興味が出た方は設定方法を学ぶとより幸せになれます。

サクッと作れるのでぜひお試しください。

良い devcontainer ライフを🧑‍🍳

おまけ devcontainerのサンプル

rails-devcontainer

https://github.com/saboyutaka/rails-devcontainer

apollo-server-devcontainer

https://github.com/saboyutaka/apollo-server-devcontainer

nuxt-devcontainer

https://github.com/saboyutaka/nuxt-devcontainer

fastapi-devcontainer

https://github.com/saboyutaka/fastapi-devcontainer

sinatra-devcontainer

https://github.com/saboyutaka/sinatra-devcontainer

P.S.

m1なmacOSでDocker Desktopが爆速になるオプションが提供されたので最高 🚀🚀
[追記] virtiofsはexperimental featureであり、最近ファイル数の多いプロジェクトで遅くなる経験があったので運用をやめました。named volemeを利用した高速化を利用するのが良さそうです。

合同会社春秋テックブログ

Discussion