VSCode+devcontainerでGatsby開発環境を立ち上げる

# はじめに
　VSCodeのdevcontainerを使うと、開発ツールをローカルマシンにではなくコンテナ内にインストールして開発を進めることができます。そのため、ローカルマシンの環境を汚すことがなくなり、またプロジェクトごとの開発ツールのバージョン違いなどの懸念もなくなります。
　また、コンテナの導入から立ち上げまでの処理も設定ファイルとしてバージョン管理下に置かれるため、チームメンバ内で開発環境を統一することにもつながります。
　ここでは、Gatsbyプロジェクトの新規立ち上げを題材に、VSCodeでdevcontainer環境を一から構築する方法を説明します。

# 前提
- 環境
    - macOS Monterey 12.1 (Apple M1 Mac mini)
- インストール済みのソフトウェア
    - Docker Desktop 4.4.2 (73305)
        - [公式](https://www.docker.com/products/docker-desktop "Docker Desktop for Mac and Windows")のインストーラでインストールして起動、設定は全てデフォルトのまま。Docker Hubへのログインは無し。
    - VSCode 1.64 (January 2022)
        - 拡張機能に、Microsoftの**Remote - Containers**をインストール済み(v0.217.1)

# Gatsby用devcontainerの作成
VSCodeを起動し、特定のフォルダが開かれていない状態にします（下図）。
![スクリーンショット 2022-02-04 10.46.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/ca6448cc-f704-8634-a49b-6ca84a9b1f4c.png)

青い**フォルダーを開く**ボタンを押し、ファイルダイアログにて新しいフォルダを作成してそのフォルダを開きます。ここではsampleという新規フォルダを選択しました（下図）。
![スクリーンショット 2022-02-04 10.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/97dea777-c7bc-c210-4f36-0b798ec748c7.png)

ソース管理機能拡張にて青い**リポジトリを初期化する**ボタンを押し、このsampleフォルダのリポジトリを初期化しておきます。以下では省略しますが、ファイルの追加・変更があれば適切なタイミングでコミットしてください。
![スクリーンショット 2022-02-04 10.58.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/393e3c6d-310b-b6ee-aa63-f4772f35285d.png)

次に、VSCode下部のステータスライン左端にある緑のアイコン(**><**みたいな形)をクリックすると、コマンドパレットに以下の表示がされるので、ここから**Add Development Container Configuration Files...**を選択します。
![スクリーンショット 2022-02-04 10.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/183a974d-3eba-7c36-966a-e1a30dc60646.png)

すると、開発環境のメニューリストが表示されるので、この中から**Node.js & TypeScript**を選択します。
![スクリーンショット 2022-02-04 9.38.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/e95dec84-f9eb-4812-9294-aff1cd99920e.png)

続いて、ベースとするUbuntu環境の選択肢が表示されるので、デフォルトの**16-bullseye**を選択します（注意書きにあるようにApple M1チップの場合はbullseye版でないと正しく動作しません）。
![スクリーンショット 2022-02-04 9.40.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/be469857-790e-25d5-5b03-34eb7f262a54.png)

次に、コンテナ内にオプションでインストールするツールの選択肢が表示されますが、ここでは何も選択せずにそのまま**OK**ボタンを押します（またはリターンキー）。
![スクリーンショット 2022-02-04 9.44.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/19ad31d1-4e8a-2b72-928d-2cd341290e88.png)

すると、devcontainerの設定ファイルがsampleフォルダ内に作成されます（下図）。VSCodeの右下に表示されるダイアログで**Reopen in Container**を押すと、上で選択した通り、Node.jsがインストール済みのUbuntu 16コンテナが立ち上がりますが、ここでは起動されるコンテナにあらかじめGatsbyをインストールしておきたいので、xボタンを押してダイアログを閉じます。
![スクリーンショット 2022-02-04 10.55.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/85647c38-03cc-0463-abc9-d0915156a8eb.png)

生成されたファイルDockerfileをVSCodeで開き、下図17行目にある通り、ファイル末尾にGatsbyのインストールコマンド(**RUN su node -c "npm install -g gatsby-cli"**)を追加します。
![スクリーンショット 2022-02-04 10.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/34ce0523-8662-72fd-d56e-a121eaa2cdc8.png)

変更したDockerfileを保存した後に、VSCode下部のステータスライン左端にある緑のアイコン(**><**みたいな形)をクリックすると、コマンドパレットに以下の表示がされるので、ここから**Reopen in Container**を選択します。これにより、Node.jsコンテナが起動され、今開いていたsampleフォルダをそのコンテナ内で開くことになります。
![スクリーンショット 2022-02-04 10.23.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/917c8f3e-7952-1cf5-146d-662261f28f7f.png)

コンテナイメージがダウンロードされてNode.js開発用コンテナが起動されます（下図）。VSCode下部にあるステータスライン左の緑の領域に表示されている通り、今のVSCodeは**Node.js & TypeScript**設定の開発用コンテナ(Dev Container)の中に接続されている状態となります。下図は、さらに新しいターミナルを開いた状態です。
![スクリーンショット 2022-02-04 11.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/643aae0f-ca33-4ae1-06f1-376a01edb660.png)

# Gatsbyサイトの作成
次にGatsbyサイトの新規作成を行います。

Dockerfile内にGatsbyのインストールコマンドを追加してあるので、コンテナの起動直後からGatsbyが使えるようになっています（下図）。
![スクリーンショット 2022-02-04 10.28.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/e9da1e70-c7a3-6942-e2c7-324c7e079167.png)

ターミナルから```gatsby new site```を実行し、新しいGatsbyサイトをsiteフォルダ内に作成します（siteという名前は任意）。Gatsbyのスターター設定を使いたい場合などは適宜修正してください。初期サイトの生成が終わったら、作成されたsiteフォルダ内に移動してから```gatsby develop```を実行し、サイトが正しく表示されることを確認してください（下図）。
![スクリーンショット 2022-02-04 11.20.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/39d7b500-1ecd-9f9e-c9f5-41b8e10bc658.png)

生成されたGatsbyサイトの.gitconfigでは site/node_modules フォルダはgit管理下に置かれません。そのため、今後、このsampleプロジェクトをgitリポジトリからクローンした直後に```gatsby develop```を実行すると、node_modulesがないというエラーが表示されます。そこで、devcontainerの設定でDockerコンテナの起動直後に```npm install```を実行させるようにします。VSCodeでdevcontainer.jsonファイルを開き、下図28行目にある**postCreateCommand**を以下のように修正します。フォルダ名siteは適宜変更ください。
![スクリーンショット 2022-02-04 11.39.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/78edf24a-fad1-91e7-e0f4-d09fd671ebc5.png)

# devcontainer環境の確認
最後に、ここで作成したGatsbyサイト開発環境を他のメンバーでもリポジトリクローンだけで立ち上げられるようになっていることを確認します。

まず、作成したプロジェクトフォルダsampleをGitHub等に上げておきます。全ての変更をコミットしたのちに、ソース管理拡張機能から青い**Publish Branch**ボタンを押して適切なホスティングサービスにアップロードします。以下ではGitHubの個人用privateプロジェクトとしてアップロードしました。
![スクリーンショット 2022-02-04 11.51.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/53717457-3a64-2c1e-47ec-788fc1b2153d.png)

ここで一旦、VSCodeを終了させます。

まっさらの状態にするため、Macのファインダーで今回のsampleフォルダを全て削除します。また、Docker Desktopのダッシュボードから、さっきまで使用していたコンテナ、イメージ、ボリュームを削除しておきます。下図3つのようにそれぞれ一つずつ削除します。
![スクリーンショット 2022-02-04 12.10.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/eadce211-97f1-d18b-cb07-1e633afef15e.png)
![スクリーンショット 2022-02-04 12.11.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/2b5e2de0-b8a7-72f7-2921-ecac4df1df9a.png)
![スクリーンショット 2022-02-04 12.11.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/aa754c97-c71e-987f-3f73-5182b1356ec4.png)

次に、VSCodeを起動し、ソース管理機能拡張から青い**リポジトリのクローン**ボタンを押して、先ほどアップロードしたホスティングサービスから先ほどのプロジェクトをローカルにクローンします。
![スクリーンショット 2022-02-04 12.14.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/91b07188-2aec-da2d-10f6-afc299604046.png)

クローンが終わると、VSCodeが表示するダイアログに従って、そのフォルダをVSCodeで開き、さらに表示されるダイアログから**Reopen in Container**ボタンを押して、コンテナ内でプロジェクトを開き直します。すると、再度、コンテナイメージのダウンロードから起動、さらに先ほど設定したpostCreateCommand処理が実行され、gatsbyサイトの表示が可能な状態になります（下図）。
![スクリーンショット 2022-02-04 12.22.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/eb37b47c-6056-5145-ac73-24c7fd7567c6.png)

ここで新しいターミナルを開き、```cd site; gatsby develop```を実行すると、先ほどと同様にGatsbyサイトがブラウザで表示できます。
![スクリーンショット 2022-02-04 11.20.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520595/39d7b500-1ecd-9f9e-c9f5-41b8e10bc658.png)

これで、同じリポジトリをクローンするだけでどのメンバ、どの環境からでも同じ開発環境をコンテナで立ち上げることができるようになりました。

以上。
2022/2/4 初版