これは、なにをしたくて書いたもの?
個人的にはあまり使ってきていないのですが、Development Container(Dev Container)について1度見ておこうと思いまして。
Development Container(Dev Container)
Development ContainerのWebサイトはこちら。
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.
フィーチャーやテンプレートがあり、これらを使ってDev Containerをセットアップするようです。
Dev Containerをサポートしているツール、エディター、サービスはこちら。
よくVisual Studio Codeと一緒に使われている印象がありますが、今回はDev Container CLIで使ってみたいと思います。
この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です。
まずはこちらを試してみましょう。
$ 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はメタデータと呼ばれるものです。
devcontainer.jsonの配置先は以下のいずれかに配置することになっています。上から順に高い優先度になります。
Specification / Metadata / devcontainer.json
devcontainer.jsonはJSONで記述しますが、コメントも含めることができます。
devcontainer.jsonの仕様はこちら。
Dev Container metadata reference
一般的なプロパティー。
Specification / General devcontainer.json properties
イメージはimageで指定する、Dockerfileを使用する(ビルドする)、Docker Composerを使用するといった選択肢があるようです。
- Specification / Scenario specific properties / Image or Dockerfile specific properties
- Specification / Scenario specific properties / Docker Compose specific properties
つまり、最初の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",
イメージを使う場合は、こちらから探すのがよいのかもしれません。
どんなイメージがあるのかを見る場合は、こちらですね。
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).
フィーチャーはこちらのページに一覧があります。
フィーチャーの構成は以下のようになっていて、install.shを見ると動作がわかりそうですね。
+-- feature | +-- devcontainer-feature.json | +-- install.sh | +-- (other files)
使う時は、devcontainer.jsonにfeaturesとして指定します。
"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
一覧はこちらのページにあります。
テンプレートはこういう構成になっています。
+-- template | +-- devcontainer-template.json | +-- .devcontainer.json | +-- (other files)
といってもちょっとイメージがわかないので、リポジトリーを見てみましょう。
たとえばJavaとPostgreSQLのテンプレート。
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が少しは読めるようになりそうです。