M1 Macでも快適なVSCode Remote Container用イメージ作成を試す


(2021年9月22日更新)
公式イメージがarm64/aarch64に対応してました。
https://github.com/microsoft/vscode-dev-containers/issues/558#issuecomment-919299497

例えば「Node.js & TypeScript」用イメージだと

/.devcontainer/devcontainer.json
"args": { "VARIANT": "14-bullseye" }
// "12-bullsey"  "16-bullsey" でもOK

とするだけ。便利になりました。

以下の内容は最早無駄作業ですが、過去の自分の作業記録として残しておきます。

M1 Macでも環境を汚さずにVSCodeで開発したいが…

Apple M1チップに対応した「Docker Desktop」が一般リリースされました。

Visual Studio Codeの「Remote - Containers」拡張機能を試してみようと、まずは3ステップ(?)で簡単に試せる「Quick start」通りの方法で、「Node.js & TypeScript」環境を選択して動かしてみると…

正直なところ、私の M1 Mac mini(メモリ8GB)環境では、動作がもっさりとしています。

よく見ると、Dockerイメージが x86-64 向けなのですね。

arm64 向けイメージをパッとは探せず、Intel Macもまだまだ使っているので、ここはマルチプラットフォームのイメージ作成を試してみるいい機会だと思い立ちました。

試作したイメージ

「Node.js & TypeScript」用イメージの使い方

/.devcontainer/Dockerfile
FROM earth422/vscode-dev-container-typescript-node:14

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"

# [Optional] Uncomment if you want to install more global node packages
# RUN su node -c "npm install -g <your-package-list -here>"
/.devcontainer/devcontainer.json
{
    "name": "Node.js & TypeScript",
    "build": {
        "dockerfile": "Dockerfile"
    },

    // Set *default* container specific settings.json values on container create.
    "settings": { 
        "terminal.integrated.shell.linux": "/bin/bash"
    },

    // Add the IDs of extensions you want installed when the container is created.
    "extensions": [
        "dbaeumer.vscode-eslint"
    ],

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [],

    // Use 'postCreateCommand' to run commands after the container is created.
    // "postCreateCommand": "yarn install",

    // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
    "remoteUser": "node"
}
  1. ワークスペースに上の2つのファイルを作成する
    • docker-composeを使うこともできます。
  2. コマンドパレット(F1キー)から、「Remote-Containers: Open Folder in Container...」を選択

私の環境では、もっさり感はなくなりました。

イメージ作成方法

Dockerの「マルチCPUアーキテクチャ」に対応したイメージをビルドする方法は、公式サイトのほか、こちらのサイトを参考にさせていただきました。

0. 「buildx」コマンドを使う準備をする

$ docker buildx create --name mybuilder
$ docker buildx use mybuilder

これだけでOKでした。

1. 公式イメージのルーツを調べる

詳しい方は一発で作成できるDockerfileを書けるのかもしれませんが、できるだけ労力をかけないで(ほとんど書き換えないで)やってみたいところ。

公式の「Node.js & TypeScript」用イメージは、「Node.js & JavaScript」用イメージから、その元はNode.js公式のbusterイメージから来ているようです。Node.js公式イメージはマルチプラットフォーム対応しているので、ここからスタートしてみました。

2. 「buildx」コマンドでビルドする

まずビルド環境と異なるプラットフォームのDockerイメージは出力することができないので、ビルドしたDockerイメージをローカルに保持することなく「Docker Hub」へ直接出力するために、Docker Hubへのログインを行います。

次に、とりあえず自分が必要なNode14用のDockerfileと必要なスクリプト(docker-entrypoint.sh)をローカルに落とします。(後で、この部分は必要なかったと気づきましたが、buildxコマンド自体初めての体験だったこともあり、実際の作業を記録しておきます。)

この状態でビルドを実行します。

$ docker login
$ docker buildx build --platform linux/amd64,linux/arm64 -t earth422/node:14 --push .

元々マルチプラットフォーム対応しているので当然ですが、うまくビルドできたようです。

3. 公式を元にDockerfileを書き換えてビルドする

公式の「Node.js & TypeScript」用イメージのソースを見たところ、CPUアーキテクチャに依存するようなところはなさそうです。

本当は公式のDockerfileのままでマルチプラットフォーム対応版の「Node.js & JavaScript」用イメージを作成できるはずですが、私の場合は先ほどビルドしたイメージを元に作成しました。

直したのは、もちろん最初だけです。

/vscode-dev-container-node/Dockerfile
FROM earth422/node:14

先ほどと同様にビルドを実行します。

$ docker buildx build --platform linux/amd64,linux/arm64 -t earth422/vscode-dev-container-node:14 --push .

今度もうまくビルドできたようです。このイメージを元に、更にマルチプラットフォーム対応版の「Node.js & TypeScript」用イメージを作成します。

今度も修正するのは頭だけでした。

/vscode-dev-container-typescript-node/Dockerfile
FROM earth422/vscode-dev-container-node:14
$ docker buildx build --platform linux/amd64,linux/arm64 -t earth422/vscode-dev-container-typescript-node:14 --push .

すんなり成功しました。

特に目新しいこともありませんが、ご自分で作成されるのが面倒な方は自己責任で使ってください。

公式もマルチプラットフォームに対応するといいなぁ。 →対応してました。(2021年9月22日更新)

参考文献等

最後に

読んでくださった方、ありがとうございました。

初めてのQiita投稿です。お手柔らかにお願いいたします。