LoginSignup
3
6

More than 1 year has passed since last update.

VSCode devcontainer + Dockerでシームレスな開発環境を構築してみた

Last updated at Posted at 2022-12-31

はじめに

先日参加したハッカソンでDockerで環境構築してチームメンバーと開発をしたが、メンバーの1人がVSCodeの設定によるエラーで苦戦していた。そこで今回は、VSCode devcontainerとDockerを使って、Dockerのコンテナ内でVSCodeを起動して開発する方法についてまとめる。

前提知識:Docker / Docker-composeの概念をある程度理解している。
実行環境:Windows10, DockerHub, VSCode
到達レベル:面倒な環境構築をVScodeのエディタごとチームメンバーと共有できる

VSCode devcontainerとは?

VSCode の拡張機能パックである Dev Container(旧 Remote-Containers)を使用して構築する開発環境のことを指す。
image.png
引用元:Dev Container 公式ドキュメント

ローカルのワークスペースからファイルシステムをマウントするかコンテナにコピーまたは複製することでコンテナ上で作業することができる。また、どうやらVSCodeの拡張機能もコンテナにインストールして利用するみたい。つまり、コンテナごとでエディタを含めた開発環境全体をシームレスに切り替えることができる。

これでチームメンバー間でのエディタの設定等によるエラーを防ぐことができる。
ただし、エディタはVSCodeに限られてしまうが......

利用手順

Docker のインストール

詳細についてはここでは割愛します。
Docker Desktop のインストールはここから

Dev Container のインストール

VSCodeを起動して拡張機能検索からDev Containerを見つける。
拡張機能.png
発見したらInstallボタンをクリック!

ちなみに、Dev Containerの下にRemote Developmentという似たような拡張機能があるが、これはVSCode Remote Developmentといい、Remote - WSLと、Remote - Containers、Remote - SSHをひとまとまりでインストールできる拡張機能パッケージのようなものらしい。

devcontainerコンテナのビルド

Dev Containerをインストールすると、左端に新しいステータスバー項目が表示される。
ステータスバー.png

ステータスバーをクリックすると、以下のようにコンテナのメニュバーが表示される。
image.png
既に.devcontainerディレクトリが存在するリポジトリがあれば、Open Folder in Container...を選択してコンテナを展開すればOK。

ここでは、Try a Dev Container Sample...でサンプルの Node.js コンテナを展開する。
選択後は、コンテナがビルドされるのでしばらく待機...

ビルドが完了すると、左端のステータスバーにコンテナ名が表示される。
これでVSCodeとビルドしたコンテナとの接続は完了。
image.png

コンテナのビルド後は、以下のようなディレクトリ構造になる(Node.jsの場合

.
├── CODE_OF_CONDUCT.md
├── .devcontainer
├── .eslintrc.json
├── .git
├── .gitattributes
├── .gitignore
├── LICENSE
├── node_modules
├── package.json
├── README.md
├── SECURITY.md
├── server.js
├── .vscode
└── yarn.lock

devcontainer.json

devcontainer.jsonは、開発コンテナの構築方法と起動方法を決定する構成ファイル。
.devcontainerディレクトリ直下にある。

devcontainer.json
{
	"name": "Node.js",
	"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18-bullseye",

	"customizations": {
		"vscode": {
			"settings": {},
			"extensions": [
				"streetsidesoftware.code-spell-checker"
			]
		}
	},

	"portsAttributes": {
		"9000": {
			"label": "Hello Remote World",
			"onAutoForward": "notify"
		}
	},

	"postCreateCommand": "yarn install"
}
主なオプション 内容
dockerfile Dockerイメージとして使用したいファイルへの相対パス
customizations VSCodeなどのツール固有のプロパティを設定
settings コンテナ/マシン固有の設定ファイルの追加
extensions コンテナ作成時にインストールする拡張機能を指定
forwardPorts コンテナ内のポートをローカルで利用できるようにする
postCreateCommand コンテナ作成後に実行されるコマンド
remoteUser コンテナ内でVSCodeを実行するユーザーを上書き

remoteUserのデフォルトはcontainerUser
全てのオプション集はこちら

Dockerfile と docker-compose.ymlの作成

特にDockerコンテナをカスタマイズしない人は作成する必要はないが、大抵は開発していく中で色々といじりたくなってくる。そこで.devcontainer ディレクトリ下に Dockerfileとdocker-compose.ymlを作成してコンテナを好きなようにカスタマイズする。

Dev Containerのような Docker コンテナ内で Docker を使用する方法には、docker-from-docker という方式と docker-in-docker という方式の 2 つがあるらしい。

今回は、Docker コンテナにホストの Docker ソケットをバインドマウントすることにより、コンテナ内からホストの Docker を使用するため、前者のdocker-from-dockerの方式を採用する。

詳細は以下を参照。

Dockerfile

Dockerfile
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18-bullseye
# 以下略

docker-compose.yml

docker-compose.yml
version: "3"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile

    volumes:
      - ${LOCAL_WORKSPACE_FOLDER}:/app

    working_dir: /app
    command: sh -c "yarn install"

${localWorkspaceFolder}devcontainer.jsonで使用できる変数で、ホスト側のフォルダのパスを指す。

詳細は以下を参照。


追記[2022/12/31]:

docker-compose の ver.3.2以降はvolumesはlong syntaxで記述すると、良いそう。

docker-compose.yml
version: "3.9"

# 略
volumes:
      - type: bind
        source: ${LOCAL_WORKSPACE_FOLDER}
        target: /app
# 略

short syntaxの場合、

  • 意図せずroot権限でホストにディレクトが自動生成される。
  • ファイルをマウントしようとしたが、ディレクトリがマウントされる。
  • docker-compose upでエラーを吐く場合が度々ある。
    などのデメリットがあるみたい。

詳細は以下を参照。


devcontainer.json

devcontainer.json
{
    "name": "Node.js",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
	"remoteEnv": {
		"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
	},
    "extensions": [
        "streetsidesoftware.code-spell-checker"
    ]
}

ローカルサーバの起動

ひと通り環境が整ったのでサーバを立ち上げてみる。

$ node server.js

上記のコマンドでローカルサーバを起動。

server.js
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

const express = require('express');

// Constants
const PORT = 3000;
const HOST = '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
	res.send('Hello remote world!\n');
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

ルートディレクトリ直下にserver.jsがあるので、「Hello remote world!」と返されれば成功。

image.png

コンテナのリモート接続を閉じる

File->Close Remote ConnectionでローカルのVSCodeに戻すことができる。

接続終了.png

参考文献

まとめ

今回は、VSCode devcontainerを使って、Dockerコンテナ上でシームレスな開発環境を構築してみた。ファイルシステムだけでなく、開発環境全体を揃えられることで、チーム開発で不必要なエラーで悩まされることは無くなりそう。ただ、メンバー全員がVSCode縛りになってしまうのが少し痛い......

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6