🤖

VSCode Dev Containersでユーザーが追加した拡張機能を保持

2023/07/28に公開

はじめに

VSCodeの拡張機能Dev Containersを使用すると、より簡単に開発環境を構築できますよね。
.devcontainer/devcontainer.jsonで指定していれば、コンテナー構築時にVSCodeの拡張機能をインストールしたり、VSCodeの設定も指定できます。

こちらで開発環境を構築した後にユーザーが使用したい拡張機能も追加することも可能です。
ただ、コンテナーをリビルドした場合、ユーザーが追加していた拡張機能は再度追加しないといけません。
そのため、コンテナーをリビルドしてもユーザーが追加した拡張機能を保持できるようにしてみました。

Dev Containersで開発環境を用意

まず、Dev Containersを使用した開発環境を用意します。
rubyのDocker imageを使用したサンプルを以下に記載します。

docker-compose.yml

version: '3'

services:
  app:
    image: ruby:3.2.2-slim-bookworm
    command: sleep infinity
    volumes:
      - .:/workspace:delegated
    working_dir: /workspace
    hostname: app

sample.rb

puts 'Hello World!'

.devcontainer/devcontainer.json

{
  "name": "Dev Container",
  "dockerComposeFile": [
    "../docker-compose.yml"
  ],
  "service": "app",
  "runServices": [
    "app"
  ],
  "workspaceFolder": "/workspace",
  "customizations": {
    "vscode": {
      "extensions": [
        "rebornix.ruby"
      ],
      "settings": {
        "ruby.useLanguageServer": true
      }
    }
  }
}

customizations > vscode > extensions, settingsにこの開発環境で必須な拡張機能や設定を指定できて便利です。

ユーザーが追加した拡張機能を保持

拡張機能の保存先を確認

Dev Containersでは、追加した拡張機能はコンテナー内に保存されています。
保存されているパスは$HOME/.vscode-server/extensionsになります。

以下の例では、GitHub Copilotを追加したので、github.copilot-1.99.289があります。

root@app:/workspace# ls -l ~/.vscode-server/extensions
total 20
-rw-r--r-- 1 root root 2344 Jul 27 13:31 extensions.json
drwxr-xr-x 4 root root 4096 Jul 27 13:31 github.copilot-1.99.289
drwxr-xr-x 3 root root 4096 Jul 27 13:23 ms-ceintl.vscode-language-pack-ja-1.80.2023071209
drwxr-xr-x 7 root root 4096 Jul 27 13:23 rebornix.ruby-0.28.1
drwxr-xr-x 6 root root 4096 Jul 27 13:23 wingrunr21.vscode-ruby-0.28.0

docker volumeで永続化し、拡張機能を保持

拡張機能の保存場所がわかったので、docker volumeで永続化して拡張機能を保持します。

.devcontainer/docker-compose.yml

version: '3'

services:
  app:
    volumes:
      - vscode_server_volume:/root/.vscode-server

volumes:
  vscode_server_volume:
    driver: local

.vscode-serverディレクトリ内は拡張機能以外も保持していたので、一旦.vscode-serverディレクトリを指定しています。

.devcontainer/devcontainer.json

   "dockerComposeFile": [
-    "../docker-compose.yml"
+    "../docker-compose.yml",
+    "docker-compose.yml"
   ],

dockerComposeFileに上記の.devcontainer/docker-compose.ymlを追加しています。

まとめ

コンテナー内に保存されている拡張機能をdocker volumeで永続化することで、コンテナーをリビルドしてもユーザー追加した拡張機能を保持することがでしました。
ただDev Containersを使用した開発環境は、私自身もまだ模索している最中なので、もっとよい方法などあれば教えていただきたいです。

Discussion