Docker Compose な開発環境にちょい足し3分で作るVSCode devcontainer
こんにちは、devcontainer職人です🧑🍳
今回紹介するのはDocker Composeを既に利用している開発環境にかんたんにdevcontainerを構築する方法を紹介します。
VSCodeのdevcontainerはとても良くできた開発環境構築方法なのですが、ちょっと難しそうと思われていたり、VSCode以外のエディタを使う人の開発体験が悪くなるのでは、などの懸念がありまだあまり使われていないような印象があります。今回はそんなdevcontainerを3分で作れるtipsを紹介します。
準備するもの
Docker Composeで構築した開発環境のサンプル
今回用意するのはサンプルとしてRuby on Railsの開発環境のdocker-compose.ymlを用意しました。RubyとPostgreSQLの構成です。
※ Node.js, Pythonの環境のサンプルは文末のサンプルを参照してください
docker-compose.yml, Dockerfile
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:
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
-
vendor/bundle
,node_module
をnamed volume化している(高速化のtips)
-
-
- command:
bin/rails s
← サーバーが起動するコマンドが指定されている
- volumes
ターミナル等でdocker compose up app
を実行するとサーバーが立ち上がるように構成されています。
では、こちらのappをdevcontainer化します。
devcontainer化する
用意する2つのファイル
今回は2つのファイルを用意します。
-
devcontainer.json
: devcontainerの設定ファイル。必須 -
docker-compose.yml
: 今回は既存のdocker-composeをオーバーライドするために作成する
今回はdevcontainerを"かんたん"につくるを目的とするため、devcontainerに必要な最小の設定だけ行います。2つのファイルを既存のプロジェクトに .devcontainer
ディレクトリを作成し配置します。
{
"dockerComposeFile": ["../docker-compose.yml", "docker-compose.yml"],
"service": "app",
"workspaceFolder": "/workspace"
}
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を立ち上げる方法として主に
- imageを利用する
- devcontainer用のDockerfileを用意する
- devcontainer用のdocker-compose.ymlを用意する
- 既存のDokcer Composeをオーバーライドする
- kurbernetes上のcontainerにアタッチする
などがあります。 devcontainerはテンプレートがVSCode公式でDockerfileが公開されていて Remote - Containers extension の Add 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.json
は extensions
や settings
VSCodeの拡張機能や設定をdevcontainerとしてパッケージできたり、ライフサイクルスクリプトで起動時に実行するスクリプトを自動化することでより便利に利用できますが、今回はかんたんに構築することを紹介することで利用のハードルが下がればなと思って省略しました。興味が出た方は設定方法を学ぶとより幸せになれます。
サクッと作れるのでぜひお試しください。
良い devcontainer ライフを🧑🍳
おまけ devcontainerのサンプル
rails-devcontainer
apollo-server-devcontainer
nuxt-devcontainer
fastapi-devcontainer
sinatra-devcontainer
P.S.
m1なmacOSでDocker Desktopが爆速になるオプションが提供されたので最高 🚀🚀
[追記] virtiofsはexperimental featureであり、最近ファイル数の多いプロジェクトで遅くなる経験があったので運用をやめました。named volemeを利用した高速化を利用するのが良さそうです。
Discussion