Remote-Containersを使って、Dockerfileを書かずに開発環境を立ち上げる

[Increments × cyma (Ateam Inc.) Advent Calendar 2020](https://qiita.com/advent-calendar/2020/increments-cyma) の13日目は、
Increments株式会社の @fussy113 が担当します！

Remote-Containers を利用した開発環境の構築を試しての所感をまとめようと思います。

## Remote-Containerとは

Visual Studio Code (以下VSCode) で利用できる公式が提供している拡張機能[^1]になります。
めちゃくちゃ簡単に言ってしまうと、 Docker Container を立ち上げて、その内部での作業を VSCode がサポートするよという機能です。

ローカルから workspace ディレクトリへ必要なフォルダがマウント、コピーされ、スムーズに Docker を利用しての開発環境を整えることが可能になります。
また、専用の設定ファイル(`devcontainer.json`) を記述することで、以下のことが実現できます。

実際に Node.js の環境構築、立ち上げまでをやってみましょう。

## 使ってみる

### 準備

Macで実際に Remote-Containers を利用するにあたって必要なものは2つです。

- Remote-Containers 拡張機能をインストールした VSCode
- Docker Desktop

### Node.js環境を立ち上げる

- VSCode を立ち上げて、 `CMD` + `shift` + `P` でコマンドを表示します。
- Remote-Containers: Open Folder in Container... を選択、ディレクトリを選択するウィンドウが開かれます。新規ディレクトリを作成します。
- 何やら選択する画面が出てきますね。どんなコンテナを立ち上げるか、を選択するそうです。(公式提供のサンプルの量が豊富...)
  - `Show All Definitions...` -> `Node.js & TypeScript` を選択しましょう。

![スクリーンショット 2020-12-10 9.19.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/397c617f-951d-1478-694e-54dab6f4f9e3.png)

- バージョンは今回は14系を選択します。

はい、以上です、これで コンテナが立ち上げられ、VSCode が コンテナにアクセスした状態になります。
VSCode でターミナルを開いて、コマンドを実行してみるとわかりやすいかもしれません。

![スクリーンショット 2020-12-10 9.30.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/203f2b91-5515-a28b-301b-9d6c91447dab.png)

`docker run` や、 `docker exec` を付けずコマンドを実行できます。
Dockerfile も特に書いてないのにさっと環境構築出来てしまうのはとても良いですね！

### 生成されたファイルをみる

プロジェクトのルートディレクトリにファイルが追加されます。少し見てみましょう。

```dockerfile:.dev/Dockerfile
ARG VARIANT="14-buster"
FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-${VARIANT}
```

```json:.dev/devcontainer.json
{
 "name": "Node.js & TypeScript",
 "build": {
  "dockerfile": "Dockerfile",
  "args": { "VARIANT": "14" }
 },

 "settings": { 
  "terminal.integrated.shell.linux": "/bin/bash"
 },

 "extensions": [
  "dbaeumer.vscode-eslint",
  "ms-vscode.vscode-typescript-tslint-plugin"
 ],

 "remoteUser": "node"
}
```

devcontainer.json が大事そうですね。
どの Dockerfile をビルドするのかであったりが `build` の辺りに書かれてます。
`extentions` は、コンテナを立ち上げてVSCodeでアクセスする際、記述された VSCodeの拡張機能が、コンテナ内でインストールされます。
ローカルに拡張をめちゃくちゃ入れて管理する必要がなくなり、プロジェクト毎に必要な拡張を入れられるというのは、とても嬉しいです。

### 豊富なオプション

devcontainer.json は初期で記述されている以上に多彩な機能が備わってます。

- `postCreateCommand`
  - コンテナの生成後にコマンドを実行することができるようになります。`yarn install` など、初期に実行したいコマンドなどを入れておくと良さそうです。
- `runArgs`
  - こちらもコンテナを立ち上げる際の docker コマンドのオプションを指定できます。
- `appPort`
  - ローカルとのポートフォワーディングをします。

他にもたくさんのオプションがあるので是非リファレンス[^2]を見てみましょう。

### 実際に触ってみての所感

コンテナを利用して開発する上で、非常に便利なものだなと感じました。

VSCode の ESLint 拡張などを利用したい場合、これまではローカルに拡張を入れ、`node_modules`をマウント、もしくはローカルでインストールして取得するなど、コンテナ外での必要な作業があったかと思います。
コンテナ内で直接作業ができる、必要な拡張をコンテナ内インストールできることでこの問題が解消されました。

また、コンテナ内に入ってしまえば、あまり Docker を意識せず、コマンドを実行したり、作業が出来るなど、Docker を使っての開発が不慣れな方でもスムーズな開発が実現できるような気がしますね！

気になったのは、下記です。

- エディタがVSCodeに限定されてしまうこと
- 初回の立ち上げに限り、時間がかかること(image のビルドも行われるため)

それでも便利だなと思うものなので、気になった方がいたら是非今すぐ VSCode を開いて試してみてください！

## 終わりに

[Increments × cyma (Ateam Inc.) Advent Calendar 2020](https://qiita.com/advent-calendar/2020/increments-cyma) の14日目は、株式会社エイチーム EC事業本部の @nemuneru がお送りします、楽しみですね！！

[^1]: Remote-Containersの公式ドキュメントは[こちら](https://code.visualstudio.com/docs/remote/containers)
[^2]: devcontainer.jsonのリファレンスは[こちら](https://code.visualstudio.com/docs/remote/devcontainerjson-reference)