以下の内容はhttps://kazuhira-r.hatenablog.com/entry/2025/11/01/003055より取得しました。


Development Container(Dev Container)をCLIで使ってみる

これは、なにをしたくて書いたもの?

個人的にはあまり使ってきていないのですが、Development Container(Dev Container)について1度見ておこうと思いまして。

Development Container(Dev Container)

Development ContainerのWebサイトはこちら。

Development containers

Development Container、略してDev Containerはコンテナをフル機能の開発環境として使うものです。

A development container (or dev container for short) allows you to use a container as a full-featured development environment.

アプリケーションの実行と、コードベースの操作に必要なツール、ライブラリーやランタイムを分離しCIやテストなどに利用できます。
またローカルやリモート、プライベートクラウドパブリッククラウドで利用でき、様々なツールやエディターがサポートしています。

It can be used to run an application, to separate tools, libraries, or runtimes needed for working with a codebase, and to aid in continuous integration and testing. Dev containers can be run locally or remotely, in a private or public cloud, in a variety of supporting tools and editors.

Dev Containerには仕様があります。

The Development Container Specification seeks to find ways to enrich existing formats with common development specific settings, tools, and configuration while still providing a simplified, un-orchestrated single container option – so that they can be used as coding environments or for continuous integration and testing.

そしてGitHubリポジトリーで管理されているようです。

GitHub - devcontainers/spec: Development Containers: Use a container as a full-featured development environment.

フィーチャーやテンプレートがあり、これらを使ってDev Containerをセットアップするようです。

Features

Templates

Dev Containerをサポートしているツール、エディター、サービスはこちら。

Supporting tools and services

よくVisual Studio Codeと一緒に使われている印象がありますが、今回はDev Container CLIで使ってみたいと思います。

GitHub - devcontainers/cli: A reference implementation for the specification that can create and configure a dev container from a devcontainer.json.

このCLIはリファレンス実装だそうです。

環境

今回の環境はこちら。

$ docker version
Client: Docker Engine - Community
 Version:           28.5.1
 API version:       1.51
 Go version:        go1.24.8
 Git commit:        e180ab8
 Built:             Wed Oct  8 12:17:26 2025
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          28.5.1
  API version:      1.51 (minimum version 1.24)
  Go version:       go1.24.8
  Git commit:       f8215cc
  Built:            Wed Oct  8 12:17:26 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.28
  GitCommit:        b98a3aace656320842a23f4a392a33f46af97866
 runc:
  Version:          1.3.0
  GitCommit:        v1.3.0-0-g4ca628d1
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Dev Container CLIはNode.jsで動作するようなので、こちらも。

$ node --version
v24.11.0


$ npm --version
11.6.1

Dev Container CLIをインストールする

まずはDev Container CLIをインストールします。

$ npm install -g @devcontainers/cli

Dev Container CLI / Try it out / npm install

バージョン。

$ devcontainer --version
0.80.1

ヘルプ。

$ devcontainer --help
devcontainer <command>

Commands:
  devcontainer up                   Create and run dev container
  devcontainer set-up               Set up an existing container as a dev container
  devcontainer build [path]         Build a dev container image
  devcontainer run-user-commands    Run user commands
  devcontainer read-configuration   Read configuration
  devcontainer outdated             Show current and available versions
  devcontainer upgrade              Upgrade lockfile
  devcontainer features             Features commands
  devcontainer templates            Templates commands
  devcontainer exec <cmd> [args..]  Execute a command on a running dev container

Options:
  --help     Show help                                                                                         [boolean]
  --version  Show version number                                                                               [boolean]

devcontainer@0.80.1 /home/user/.nvm/versions/node/v24.11.0/lib/node_modules/@devcontainers/cli

Rustのサンプルを動かす

README.mdでは、最初にRustのサンプルを動かすようになっています。

Dev Container CLI / Try it out / Try out the CLI

こちらを見てもOKです。

Reference Implementation

まずはこちらを試してみましょう。

$ git clone https://github.com/microsoft/vscode-remote-try-rust
$ cd vscode-remote-try-rust

.devcontainer/devcontainer.jsonを見てみます。

.devcontainer/devcontainer.json

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/rust
{
        "name": "Rust",
        // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
        "image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",

        // Features to add to the dev container. More info: https://containers.dev/features.
        // "features": {},

        // Configure tool-specific properties.
        "customizations": {
                // Configure properties specific to VS Code.
                "vscode": {
                        "settings": {},
                        "extensions": [
                                "streetsidesoftware.code-spell-checker"
                        ]
                }
        }

        // 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": "rustc --version",

        // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
        // "remoteUser": "root"
}

Dev Containerを起動。Dockerイメージがダウンロードされ、コンテナが起動します。--workspace-folder.devcontainer/devcontainer.json
あるディレクトリーを指定する必要があるみたいです。

$ devcontainer up --workspace-folder .

まあまあ時間をかけて、起動しました。

[1 ms] @devcontainers/cli 0.80.1. Node.js v24.11.0. linux 6.8.0-87-generic x64.
[+] Building 163.8s (6/6) FINISHED                                                                                                                              docker:default
 => [internal] load build definition from updateUID.Dockerfile-0.80.1                                                                                                     0.1s
 => => transferring dockerfile: 1.52kB                                                                                                                                    0.0s
 => WARN: InvalidDefaultArgInFrom: Default value for ARG $BASE_IMAGE results in empty or invalid base image name (line 4)                                                 0.1s
 => [internal] load metadata for mcr.microsoft.com/devcontainers/rust:1-1-bullseye                                                                                        0.6s
 => [internal] load .dockerignore                                                                                                                                         0.1s
 => => transferring context: 2B                                                                                                                                           0.0s
 => [1/2] FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye@sha256:6817e2f836956c5034933e52f305b6c1112b628d3fbad0e87f472a2839ad5fe0                                161.5s
 => => resolve mcr.microsoft.com/devcontainers/rust:1-1-bullseye@sha256:6817e2f836956c5034933e52f305b6c1112b628d3fbad0e87f472a2839ad5fe0                                  0.0s
 => => sha256:6817e2f836956c5034933e52f305b6c1112b628d3fbad0e87f472a2839ad5fe0 1.61kB / 1.61kB                                                                            0.0s
 => => sha256:a40f0ba575c6f72759113ee9d656181e87693e9a9ca23bc0710edf2f2763ba11 2.78kB / 2.78kB                                                                            0.0s
 => => sha256:c86e3ebfb4e039fe8cd35c5d407933a87abcfe6e20d34162530bd0d74c6f7b63 17.36kB / 17.36kB                                                                          0.0s
 => => sha256:06408a499c9b569e198473b636afa8c383e459ee6fe76ba4159b758c84e68f10 15.77MB / 15.77MB                                                                          5.2s
 => => sha256:2d765646d883a37610a09973a079fbba4c7596e54d18d0447bdfff142389d1f7 53.75MB / 53.75MB                                                                         64.3s
 => => sha256:06772a4eff3df697497bb68b4dcdeb97fdb9338b5e7dde7d1a53579c3203c9ba 54.76MB / 54.76MB                                                                         63.1s
 => => sha256:6fd49c17bd36c59d7bf7afe446ee52f36cad8a6393628526989f2db44b4486c1 197.14MB / 197.14MB                                                                       36.5s
 => => sha256:6b35768b15c47fe75ef345baf1601f003231cf7fa1353d4b05177acb4b38d712 205.06MB / 205.06MB                                                                      151.8s
 => => sha256:678459a459dcd6a035698441c64c30130c57dbee85d2c9501467f0dc709a1f08 14.40MB / 14.40MB                                                                         66.5s
 => => extracting sha256:2d765646d883a37610a09973a079fbba4c7596e54d18d0447bdfff142389d1f7                                                                                 1.1s
 => => sha256:8be3692f9fda4e2e4a32b6cad9b93695e2316734943e30cdf80dfa210993dc96 408B / 408B                                                                               64.7s
 => => sha256:9bed3b92df8dd88416d63f28aad4e7ddc1e61b7d0fccda02569f6a598b9deece 135B / 135B                                                                               65.1s
 => => sha256:96be28a192c43a2a8318f8ddf8a3d6590a4d2b578e272792c5306aad93f0a9dd 224B / 224B                                                                               65.6s
 => => extracting sha256:06408a499c9b569e198473b636afa8c383e459ee6fe76ba4159b758c84e68f10                                                                                 0.3s
 => => sha256:65d159f72bb8a2aec769a3461851f023b38cb160b804b0b3f3e69c291d6afe5b 233B / 233B                                                                               66.2s
 => => extracting sha256:06772a4eff3df697497bb68b4dcdeb97fdb9338b5e7dde7d1a53579c3203c9ba                                                                                 1.3s
 => => sha256:49beb5d3393920bed4b74fd6812ddc8248e42f08bae7d8a27edd9d303400a2b2 49.61MB / 49.61MB                                                                        123.6s
 => => sha256:5586939a709aaf0a895755c43932dfde36c36b5c6cbf79e5610466028f4bc4a1 66.29MB / 66.29MB                                                                        126.8s
 => => extracting sha256:6fd49c17bd36c59d7bf7afe446ee52f36cad8a6393628526989f2db44b4486c1                                                                                 3.7s
 => => sha256:42d0d13f3d845eaa4c5c3fac480643752b9b2996b294a5165a826944f91488c6 155.56MB / 155.56MB                                                                      153.3s
 => => extracting sha256:6b35768b15c47fe75ef345baf1601f003231cf7fa1353d4b05177acb4b38d712                                                                                 2.7s
 => => extracting sha256:678459a459dcd6a035698441c64c30130c57dbee85d2c9501467f0dc709a1f08                                                                                 0.2s
 => => extracting sha256:8be3692f9fda4e2e4a32b6cad9b93695e2316734943e30cdf80dfa210993dc96                                                                                 0.0s
 => => extracting sha256:9bed3b92df8dd88416d63f28aad4e7ddc1e61b7d0fccda02569f6a598b9deece                                                                                 0.0s
 => => extracting sha256:96be28a192c43a2a8318f8ddf8a3d6590a4d2b578e272792c5306aad93f0a9dd                                                                                 0.0s
 => => extracting sha256:65d159f72bb8a2aec769a3461851f023b38cb160b804b0b3f3e69c291d6afe5b                                                                                 0.0s
 => => extracting sha256:49beb5d3393920bed4b74fd6812ddc8248e42f08bae7d8a27edd9d303400a2b2                                                                                 1.4s
 => => extracting sha256:5586939a709aaf0a895755c43932dfde36c36b5c6cbf79e5610466028f4bc4a1                                                                                 0.9s
 => => extracting sha256:42d0d13f3d845eaa4c5c3fac480643752b9b2996b294a5165a826944f91488c6                                                                                 2.8s
 => [2/2] RUN eval $(sed -n "s/vscode:[^:]*:\([^:]*\):\([^:]*\):[^:]*:\([^:]*\).*/OLD_UID=\1;OLD_GID=\2;HOME_FOLDER=\3/p" /etc/passwd);  eval $(sed -n "s/\([^:]*\):[^:]  1.1s
 => exporting to image                                                                                                                                                    0.2s
 => => exporting layers                                                                                                                                                   0.1s
 => => writing image sha256:b40d09567a196bccfb59f58414b85a9d9bf2f5180376cbeeda5212d75ec50573                                                                              0.0s
 => => naming to docker.io/library/vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid                                        0.0s

 1 warning found (use docker --debug to expand):
 - InvalidDefaultArgInFrom: Default value for ARG $BASE_IMAGE results in empty or invalid base image name (line 4)
[165292 ms] Start: Run: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/home/user/workspaces/vscode-remote-try-rust,target=/workspaces/vscode-remote-try-rust -l devcontainer.local_folder=/home/user/workspaces/vscode-remote-try-rust -l devcontainer.config_file=/home/user/workspaces/vscode-remote-try-rust/.devcontainer/devcontainer.json --cap-add SYS_PTRACE --security-opt seccomp=unconfined --entrypoint /bin/sh -l devcontainer.metadata=[{"id":"ghcr.io/devcontainers/features/common-utils:2"},{"id":"ghcr.io/devcontainers/features/git:1","customizations":{"vscode":{"settings":{"github.copilot.chat.codeGeneration.instructions":[{"text":"This dev container includes an up-to-date version of Git, built from source as needed, pre-installed and available on the `PATH`."}]}}}},{"id":"ghcr.io/devcontainers/features/rust:1","capAdd":["SYS_PTRACE"],"securityOpt":["seccomp=unconfined"],"customizations":{"vscode":{"extensions":["vadimcn.vscode-lldb","rust-lang.rust-analyzer","tamasfe.even-better-toml"],"settings":{"files.watcherExclude":{"**/target/**":true},"github.copilot.chat.codeGeneration.instructions":[{"text":"This dev container includes Rust, common Rust utilities, and needed dependencies pre-installed and available on the `PATH`, along with the Rust language extension for Rust development."}]}}}},{"remoteUser":"vscode"},{"customizations":{"vscode":{"settings":{},"extensions":["streetsidesoftware.code-spell-checker"]}}}] vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid -c echo Container started
Container started
{"outcome":"success","containerId":"01a5fe858ad6316e5e761953c00ef9e57f643ebee0dd926f961243e2cc3e93f0","remoteUser":"vscode","remoteWorkspaceFolder":"/workspaces/vscode-remote-try-rust"}

コンテナ内でコマンドを実行。

$ devcontainer exec --workspace-folder . cargo run
warning: no edition set: defaulting to the 2015 edition while the latest is 2024
   Compiling hello_remote_world v0.1.0 (/workspaces/vscode-remote-try-rust)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s
     Running `target/debug/hello_remote_world`
Hello, VS Code Remote - Containers!

動きました。

ちなみに、この時のイメージはけっこう大きいです。

$ docker image ls
REPOSITORY                                                                                        TAG       IMAGE ID       CREATED              SIZE
vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid   latest    b40d09567a19   About a minute ago   2.28GB

開発用ですしね。

$ docker container ps
CONTAINER ID   IMAGE                                                                                             COMMAND                   CREATED         STATUS         PORTS     NAMES
01a5fe858ad6   vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid   "/bin/sh -c 'echo Co…"   2 minutes ago   Up 2 minutes             lucid_jang

コンテナを止めます。

$ docker container stop lucid_jang

1度ビルドしていれば、次回はビルド済みイメージで起動するようです。

$ devcontainer up --workspace-folder .

ビルド済みイメージを1度削除。

$ docker image rm vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid:latest

ビルドだけを行うこともできます。

$ devcontainer build --workspace-folder .
{"outcome":"success","imageName":["vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-features"]}

ビルドされたイメージ。

$ docker image ls
REPOSITORY                                                                                             TAG       IMAGE ID       CREATED        SIZE
vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-features   latest    9ad2cbf74c81   3 months ago   2.28GB

起動してみます。

$ devcontainer up --workspace-folder .

すると、初回のビルドと起動を同時に行った時よりも高速になりますね。

[1 ms] @devcontainers/cli 0.80.1. Node.js v24.11.0. linux 6.8.0-87-generic x64.
[+] Building 0.8s (6/6) FINISHED                                                                                                                                docker:default
 => [internal] load build definition from updateUID.Dockerfile-0.80.1                                                                                                     0.0s
 => => transferring dockerfile: 1.52kB                                                                                                                                    0.0s
 => WARN: InvalidDefaultArgInFrom: Default value for ARG $BASE_IMAGE results in empty or invalid base image name (line 4)                                                 0.0s
 => [internal] load metadata for mcr.microsoft.com/devcontainers/rust:1-1-bullseye                                                                                        0.1s
 => [internal] load .dockerignore                                                                                                                                         0.0s
 => => transferring context: 2B                                                                                                                                           0.0s
 => CACHED [1/2] FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye@sha256:6817e2f836956c5034933e52f305b6c1112b628d3fbad0e87f472a2839ad5fe0                           0.0s
 => [2/2] RUN eval $(sed -n "s/vscode:[^:]*:\([^:]*\):\([^:]*\):[^:]*:\([^:]*\).*/OLD_UID=\1;OLD_GID=\2;HOME_FOLDER=\3/p" /etc/passwd);  eval $(sed -n "s/\([^:]*\):[^:]  0.3s
 => exporting to image                                                                                                                                                    0.1s
 => => exporting layers                                                                                                                                                   0.1s
 => => writing image sha256:7a9211ecf14854a45652edae60a4d02161355ceeca89df15bc998e49e3414f73                                                                              0.0s
 => => naming to docker.io/library/vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid                                        0.0s

 1 warning found (use docker --debug to expand):
 - InvalidDefaultArgInFrom: Default value for ARG $BASE_IMAGE results in empty or invalid base image name (line 4)
[2073 ms] Start: Run: docker run --sig-proxy=false -a STDOUT -a STDERR --mount type=bind,source=/home/user/workspaces/vscode-remote-try-rust,target=/workspaces/vscode-remote-try-rust -l devcontainer.local_folder=/home/user/workspaces/vscode-remote-try-rust -l devcontainer.config_file=/home/user/workspaces/vscode-remote-try-rust/.devcontainer/devcontainer.json --cap-add SYS_PTRACE --security-opt seccomp=unconfined --entrypoint /bin/sh -l devcontainer.metadata=[{"id":"ghcr.io/devcontainers/features/common-utils:2"},{"id":"ghcr.io/devcontainers/features/git:1","customizations":{"vscode":{"settings":{"github.copilot.chat.codeGeneration.instructions":[{"text":"This dev container includes an up-to-date version of Git, built from source as needed, pre-installed and available on the `PATH`."}]}}}},{"id":"ghcr.io/devcontainers/features/rust:1","capAdd":["SYS_PTRACE"],"securityOpt":["seccomp=unconfined"],"customizations":{"vscode":{"extensions":["vadimcn.vscode-lldb","rust-lang.rust-analyzer","tamasfe.even-better-toml"],"settings":{"files.watcherExclude":{"**/target/**":true},"github.copilot.chat.codeGeneration.instructions":[{"text":"This dev container includes Rust, common Rust utilities, and needed dependencies pre-installed and available on the `PATH`, along with the Rust language extension for Rust development."}]}}}},{"remoteUser":"vscode"},{"customizations":{"vscode":{"settings":{},"extensions":["streetsidesoftware.code-spell-checker"]}}}] vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid -c echo Container started
Container started
{"outcome":"success","containerId":"5c2252118a44cd7e2ef77a0eb03ed2d2a97f62ed877d0d1e44c3766fce5fece4","remoteUser":"vscode","remoteWorkspaceFolder":"/workspaces/vscode-remote-try-rust"}

ちなみに、イメージは2個になりました。

$ docker image ls
REPOSITORY                                                                                             TAG       IMAGE ID       CREATED          SIZE
vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-uid        latest    7a9211ecf148   37 seconds ago   2.28GB
vsc-vscode-remote-try-rust-dfdb2e85f474ba0b13589be4af660c1a83de1c1fcaa29f7c6ba3950a0749b05b-features   latest    9ad2cbf74c81   3 months ago     2.28GB

これが基本でしょうか。

仕様

Dev Containerの仕様はこちらに書かれています。

Development Container Specification

出てきた時に触れませんでしたが、devcontainer.jsonメタデータと呼ばれるものです。

Specification / Metadata

devcontainer.jsonの配置先は以下のいずれかに配置することになっています。上から順に高い優先度になります。

  • .devcontainer/devcontainer.json
  • .devcontainer.json
  • .devcontainer//devcontainer.json
    • フォルダーは1階層

Specification / Metadata / devcontainer.json

devcontainer.jsonJSONで記述しますが、コメントも含めることができます。

devcontainer.jsonの仕様はこちら。

Dev Container metadata reference

一般的なプロパティー

Specification / General devcontainer.json properties

イメージはimageで指定する、Dockerfileを使用する(ビルドする)、Docker Composerを使用するといった選択肢があるようです。

つまり、最初のRustのサンプルはimageを使ってイメージを指定していたわけです。

        "name": "Rust",
        // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
        "image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",

イメージを使う場合は、こちらから探すのがよいのかもしれません。

devcontainers / Docker Hub

GitHub - devcontainers/images: Repository for pre-built dev container images published under mcr.microsoft.com/devcontainers

どんなイメージがあるのかを見る場合は、こちらですね。

https://github.com/devcontainers/images/tree/main/src

フィーチャーとテンプレート

フィーチャーとテンプレートも見ておきましょう。

フィーチャーは、インストールコードとDev Containerの設定をまとめたものです。

Dev Container Features reference

フィーチャーを使うことで、Dev Containerにツールやランタイム、ライブラリーなどのフィーチャーを追加できます。

インストールはLinuxディストリビューションのコマンドを使うこともあるので、ベースのディストリビューションは合わせておいた方が
よさそうですね。

Note: While Features may be installed on top of any base image, the implementation of a Feature might restrict it to a subset of possible base images. For example, some Features may be authored to work with a certain Linux distro (e.g. debian-based images that use the apt package manager).

フィーチャーはこちらのページに一覧があります。

Features

GitHubリポジトリーとしてはこちらですね。

GitHub - devcontainers/features: A collection of Dev Container Features managed by Dev Container spec maintainers. See https://github.com/devcontainers/feature-starter to publish your own

フィーチャーの構成は以下のようになっていて、install.shを見ると動作がわかりそうですね。

+-- feature
|    +-- devcontainer-feature.json
|    +-- install.sh
|    +-- (other files)

使う時は、devcontainer.jsonfeaturesとして指定します。

"name": "my-project-devcontainer",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",  // Any generic, debian-based image.
"features": {
    "ghcr.io/devcontainers/features/go:1": {
        "version": "1.18"
    },
    "ghcr.io/devcontainers/features/docker-in-docker:1": {
        "version": "latest",
        "moby": true
    }
}

テンプレートは、開発環境の設定をエンコードしたソースファイルをまとめてパッケージにしたものです。

Dev Container Templates reference

一覧はこちらのページにあります。

Templates

テンプレートはこういう構成になっています。

+-- template
|    +-- devcontainer-template.json
|    +-- .devcontainer.json
|    +-- (other files)

といってもちょっとイメージがわかないので、リポジトリーを見てみましょう。

GitHub - devcontainers/templates: Repository for Dev Container Templates that are managed by Dev Container spec maintainers. See https://github.com/devcontainers/template-starter to create your own!

たとえばJavaPostgreSQLのテンプレート。

https://github.com/devcontainers/templates/tree/main/src/java-postgres

これはフィーチャーと違い、Dev Container自体のテンプレートといった感じですね。

使う時は、以下のようにCLIで実行したりすると

$ devcontainer templates apply --workspace-folder . \
    --template-id ghcr.io/devcontainers/templates/cpp:latest \
    --template-args '{ "imageVariant": "debian-12" }' \
    --features '[{ "id": "ghcr.io/devcontainers/features/azure-cli:1", "options": { "version" : "1" } }]'

こんな感じでDev Container用のファイルが生成されます。

[1 ms] @devcontainers/cli 0.80.1. Node.js v24.11.0. linux 6.8.0-87-generic x64.
[1491 ms] Files to omit: 'devcontainer-template.json, README.md, NOTES.md'
{"files":["./.devcontainer/Dockerfile","./.devcontainer/devcontainer.json","./.devcontainer/reinstall-cmake.sh","./.github/dependabot.yml"]}

自分でもdevcontainer.jsonを書いてみる

最後に、自分でもdevcontainer.jsonを作成してみましょう。

こんな感じで作成。

.devcontainer/devcontainer.json

{
        "name": "Java Development",
        "image": "mcr.microsoft.com/devcontainers/java:3-25-jdk-trixie",

        "features": {
                "ghcr.io/devcontainers-extra/features/maven-sdkman:2": {
                        "version": "3.9.11",
                        "jdkDistro": "none",
                        "jdkVersion": "none"
                },
                "ghcr.io/devcontainers-extra/features/terraform-asdf:2": {
                        "version": "1.13.4"
                }
        },

        "remoteEnv": {
                "JAVA_HOME": "/usr/lib/jvm/msopenjdk-current"
        }
}

イメージにはこちらを採用。

        "image": "mcr.microsoft.com/devcontainers/java:3-25-jdk-trixie",

現時点では正確には3.0.0-21-jdk-trixieなのですが、あまり細かくバージョンを指定しないことを推奨しているみたいです。

Alternatively, you can use the contents of .devcontainer to fully customize your container's contents or to build it for a container host architecture not supported by the image.

https://github.com/devcontainers/images/blob/main/src/java/README.md

To keep up to date, we recommend using partial version numbers. Use the major version number to get all non-breaking changes (e.g. 0-) or major and minor to only get fixes (e.g. 0.200-).

https://github.com/devcontainers/images/blob/main/src/java/history/3.0.0.md

フィーチャーにはApache MavenとTerraformを選んでみました。

        "features": {
                "ghcr.io/devcontainers-extra/features/maven-sdkman:2": {
                        "version": "3.9.11",
                        "jdkDistro": "none",
                        "jdkVersion": "none"
                },
                "ghcr.io/devcontainers-extra/features/terraform-asdf:2": {
                        "version": "1.13.4"
                }
        },

Apache Mavenについては、Javaのフィーチャーを使えばいいのでは?というところもあったりします。むしろ、これでJavaもインストール
できますし。

https://github.com/devcontainers/features/blob/main/src/java/README.md

今回はフィーチャーを使う例ということで。

ただ、こんなムリヤリな構成にしたせいでJAVA_HOMEを設定することになりました…。

        "remoteEnv": {
                "JAVA_HOME": "/usr/lib/jvm/msopenjdk-current"
        }

この後で起動したコンテナでmvnコマンドを実行すると、こうなったので…。

vscode ➜ /workspaces/sample $ mvn --version
The JAVA_HOME environment variable is not defined correctly,
this environment variable is needed to run this program.

では、ビルド。

$ devcontainer build --workspace-folder .

起動。

$ devcontainer up --workspace-folder .

コンテナに入ってみます。

$ devcontainer exec --workspace-folder . bash

コマンドの実行。

vscode ➜ /workspaces/sample $ java --version
openjdk 25 2025-09-16 LTS
OpenJDK Runtime Environment Microsoft-12398176 (build 25+36-LTS)
OpenJDK 64-Bit Server VM Microsoft-12398176 (build 25+36-LTS, mixed mode, sharing)
vscode ➜ /workspaces/sample $ mvn --version
Apache Maven 3.9.11 (3e54c93a704957b63ee3494413a2b544fd3d825b)
Maven home: /usr/local/sdkman/candidates/maven/current
Java version: 25, vendor: Microsoft, runtime: /usr/lib/jvm/msopenjdk-current
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-87-generic", arch: "amd64", family: "unix"
vscode ➜ /workspaces/sample $ terraform version
Terraform v1.13.4
on linux_amd64

こんなところでしょうか。

参考)

Java アプリケーションのコンテナーの概要 | Microsoft Learn

おわりに

Development Container(Dev Container)をCLIで使ってみました。

今までDev Containerがどういうものなのかちゃんと見てきていなかったので、良い勉強になりました。

これでdevcontainer.jsonが少しは読めるようになりそうです。




以上の内容はhttps://kazuhira-r.hatenablog.com/entry/2025/11/01/003055より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14