VSCode Remote Containers 事始め
はじめに
この記事は Visual Studio Code アドベントカレンダー 2021 の記事です。タイトル通り VSCode の拡張機能の一つ Remote Containers を使って Docker コンテナの中で VSCode を開くまでの流れと、私が実際に使っている設定を紹介します。
Remote Containers に出会うまで
私は新し物好きなので新しいプログラミング言語/フレームワーク/ライブラリで気になったものがあるととりあえずローカル PC にインストールすることが多いです。触ってみたものをそのままガッツリ使い続けることもなくはないですが、Hello World 止まりのものも多いです。
また私は整理整頓が苦手で面倒くさがりだったりもします。きちんとバージョン管理しないといけないとわかっていながら、面倒に思ってグローバル空間にライブラリをインストールしてしまうことがありました。そして放置してしばらく経って別のライブラリをインストールしようとすると何かがバッティングして動かなくなり途方に暮れることが何度もありました。
環境の分離とは別の観点として再現性にも悩まされました。手元の PC では動くコードがクラウドにデプロイすると動かないとき、なんでだろうと思って調べてみると環境構築の手順を一部すっ飛ばしているところにあったりしました。対策として README に実行したコマンドを全てメモしたりもしましたが結局これもコマンドの実行し忘れが発生します。ローカル環境をそのままクラウドにデプロイしたいなと思いました。
こういった環境分離や可搬性を考えた時にコンテナは有力な解決策の一つだと思います。そして幸いなことに自分が普段使うエディタの VSCode にはコンテナの中でエディタを開くことができる Remote Containers という拡張機能があります。これを使えばディレクトリごとに Dockerfile を置いて環境を分け、ローカルで開発したコンテナイメージをそのままクラウド上にデプロイする、さらに開発にはいつも使っている VSCode をそのまま使うということができるわけです。
というわけでこれから VSCode Remote Containers を使っていきます。以下の環境で試しました。
OS: MacOS Catalina 10.15.7
Docker: Docker version 20.10.7
Remote Containers を始めてみる
拡張機能のインストール
Cmd+Shift+x
で拡張機能の検索画面を開き remote containers で検索します。Remote Containers (拡張機能の id は ms-vscode-remote.remote-containers です)をインストールします。
Dockerfile を書く
適当なディレクトリに Dockerfile を置きます。せっかくなので Zenn CLI をインストールしたコンテナを作成しましょう。Zenn CLI のインストール手順はこちらです。Node.js のバージョンは特に指定がなかったので v16 を使います。
FROM node:16
RUN npm install -g zenn-cli
EXPOSE 8000
この Dockerfile が置かれたディレクトリを VS Code で開き左下の緑のボタンをクリックします。 そして Reopen in Container をクリックします。
設定ファイルは Dockerfile から作成します。
するとコンテナのビルドが始まって最終的には左下の緑の部分が Dev Container: Existing Dockerfile になっています。これでコンテナの中で VS Code を開くことができました。
devcontainer.json
の編集
よくみると .devcontainer/devcontainer.json
というファイルが作成されています。これはコンテナの中で開く VS Code の設定を定義するファイルです。例えば settings の項目でファイル保存時にフォーマットするかどうかやその時に使うフォーマッターを指定できますし、extensions の項目でコンテナの中で使う VS Code の拡張機能を指定できます。Zenn の記事は markdown 記法で書いていくので markdown 用の拡張機能を入れておきましょう。
{
"name": "Existing Dockerfile",
"context": "..",
"dockerFile": "../Dockerfile",
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "mervin.markdown-formatter"
},
"extensions": [
"yzhang.markdown-all-in-one",
"mervin.markdown-formatter"
]
}
そして左下の緑の部分をクリックして Rebuild Container をクリックします。これで新しい設定が反映されてコンテナの中で VS Code を開くことができます。
動作確認
コンテナの中には Zenn CLI がインストールされていて markdown 用の拡張機能がインストールされています。早速 Zenn CLI を使ってみましょう。
npx zenn init
これでコンテナの中で Zenn の記事を執筆することができます。
使っている設定の例
他に使っている VS Code Remote Containers 用の Dockerfile や設定ファイルを紹介します。
CloudFormation 用
仕事で CloudFormation テンプレートを書くときに yaml をそのまま書くのは色々と大変です。というわけでリンターとして cfn-lint を、便利な CLI ツールとして Rain をインストールします。
Dockerfile がこちらで
FROM python:3.8.3
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install
RUN pip install cfn-lint
ADD https://github.com/aws-cloudformation/rain/releases/download/v1.2.0/rain-v1.2.0_linux-amd64.zip /tmp/rain.zip
# Install Rain
RUN apt-get update \
&& apt-get install -y less \
&& unzip -j /tmp/rain.zip */rain -d /usr/local/bin/ \
&& chmod 755 /usr/local/bin/rain \
&& rm /tmp/rain.zip
devcontainer.json がこちら。
{
"name": "Existing Dockerfile",
"context": "..",
"dockerFile": "../Dockerfile",
"extensions": [
"kddejong.vscode-cfn-lint"
]
}
Rust 用
Rust は完全に趣味で触っているだけでとりあえず formatOnSave だけ有効にしています。
Dockerfile はこちらで
FROM rust:1.51.0
RUN rustup component add rust-src rls rust-analysis rustfmt
RUN cargo install --version 0.7.0 cargo-edit
devcontainer.json はこちら。
{
"name": "Existing Dockerfile",
"context": "..",
"dockerFile": "../Dockerfile",
"settings": {
"git.ignoreLimitWarning": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "matklad.rust-analyzer"
},
"extensions": [
"matklad.rust-analyzer",
]
}
Amplify 用
自分がフロントエンドのサンプルアプリを作るときは React + TypeScript を使うのでそれらの設定を書いています。バックエンドを Amplicy CLI で作るときはそれもインストールしてます。
Dockerfile はこちらで
FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-14
RUN npm install -g create-react-app
RUN npm install -g @aws-amplify/cli@7.5.3
EXPOSE 3000
.eslintrc.js はこちらで
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {}
};
devcontainer.json はこちらです。
{
"name": "Existing Dockerfile",
"context": "..",
"dockerFile": "../Dockerfile",
"settings": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
},
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
"forwardPorts": [
3000
],
}
おわりに
というわけで VSCode Remote Containers の始め方でした。
Discussion