Specification
Reference Implementation
The reference implementation for the specification is available through adevelopment container CLI.This CLI can take adevcontainer.json
and create and configure a dev container from it.
What is the Dev Container CLI?
When tools like VS Code and Codespaces detect adevcontainer.json
file in a user’s project, they use a CLI to configure a dev container. We’ve now opened up this CLI as a reference implementation so that individual users and other tools can read indevcontainer.json
metadata and create dev containers from it.
This CLI can either be used directly or integrated into product experiences, similar to how it’s integrated with Dev Containers and Codespaces today. It currently supports both a simple single container option and integrates withDocker Composefor multi-container scenarios.
The CLI is available in thedevcontainers/clirepository.
How can I try it?
We’d love for you to try out the Dev Container CLI and let us know what you think. You can quickly try it out in just a few simple steps, either by installing its npm package or building the CLI repo from sources.
You may learn more about building from sources in theCLI repo’s README.On this page, we’ll focus on using the npm package.
To install the npm package, you will need Python, Node.js (version 14 or greater), and C/C++ installed to build one of the dependencies. The VS CodeHow to Contributewiki has details about the recommended toolsets.
npm install
npminstall-g@devcontainers/cli
Verify you can run the CLI and see its help text:
devcontainer <command>
Commands:
devcontainer up Create and run dev container
devcontainer build[path] Build a dev container image
devcontainer run-user-commands Run user commands
devcontainer read-configuration Read configuration
devcontainer features Features commands
devcontainer templates Templates commands
devcontainerexec<cmd>[args..] Execute acommandon a running dev container
Options:
--helpShowhelp[boolean]
--versionShow version number[boolean]
Try out the CLI
Once you have the CLI, you can try it out with a sample project, like thisRust sample.
Clone the Rust sample to your machine, and start a dev container with the CLI’sup
command:
git clone https://github /microsoft/vscode-remote-try-rust
devcontainer up--workspace-folder<path-to-vscode-remote-try-rust>
This will download the container image from a container registry and start the container. Your Rust container should now be running:
[88 ms] dev-containers-cli 0.1.0.
[165 ms] Start: Run: docker build-f/home/node/vscode-remote-try-rust/.devcontainer/Dockerfile-tvsc-vscode-remote-try-rust-89420ad7399ba74f55921e49cc3ecfd2--build-argVARIANT=bullseye /home/node/vscode-remote-try-rust/.devcontainer
[+] Building 0.5s(5/5)FINISHED
=>[internal] load build definition from Dockerfile 0.0s
=>=>transferring dockerfile: 38B 0.0s
=>[internal] load.dockerignore 0.0s
=>=>transferring context: 2B 0.0s
=>[internal] load metadataformcr.microsoft /vscode/devcontainers/r 0.4s
=>CACHED[1/1] FROM mcr.microsoft /vscode/devcontainers/rust:1-bulls 0.0s
=>exporting to image 0.0s
=>=>exporting layers 0.0s
=>=>writing image sha256:39873ccb81e6fb613975e11e37438eee1d49c963a436d 0.0s
=>=>naming to docker.io/library/vsc-vscode-remote-try-rust-89420ad7399 0.0s
[1640 ms] Start: Run: docker run--sig-proxy=false-aSTDOUT-aSTDERR--mounttype=bind,source=/home/node/vscode-remote-try-rust,target=/workspaces/vscode-remote-try-rust-ldevcontainer.local_folder=/home/node/vscode-remote-try-rust--cap-add=SYS_PTRACE--security-optseccomp=unconfined--entrypoint/bin/sh vsc-vscode-remote-try-rust-89420ad7399ba74f55921e49cc3ecfd2-uid-cechoContainer started
Container started
{"outcome":"success","containerId":"f0a055ff056c1c1bb99cc09930efbf3a0437c54d9b4644695aa23c1d57b4bd11","remoteUser":"vscode","remoteWorkspaceFolder":"/workspaces/vscode-remote-try-rust"}
You can then run commands in this dev container:
devcontainerexec--workspace-folder<path-to-vscode-remote-try-rust> cargo run
This will compile and run the Rust sample, outputting:
[33 ms] dev-containers-cli 0.1.0.
Compiling hello_remote_world v0.1.0(/workspaces/vscode-remote-try-rust)
Finished dev[unoptimized + debuginfo] target(s)in1.06s
Running`target/debug/hello_remote_world`
Hello, VS Code Remote - Containers!
{"outcome":"success"}
Congrats, you’ve just run the Dev Container CLI and seen it in action!
These steps are also provided in the CLI repo’sREADME.You may also review frequently asked questionshere.
Prebuilding
We recommend pre-building images with the tools you need rather than creating and building a container image each time you open your project in a dev container. Using pre-built images will result in a faster container startup, simpler configuration, and allows you to pin to a specific version of tools to improve supply-chain security and avoid potential breaks. You can automate pre-building your image by scheduling the build using a DevOps or continuous integration (CI) service like GitHub Actions.
We recommend using theDev Container CLI(or other spec supporting utilities like theGitHub ActionorAzure DevOps task) to pre-build your images. Once you’ve built your image, you can push it to a container registry (like theAzure Container Registry,GitHub Container Registry,orDocker Hub) and reference it directly.
devcontainer build--workspace-folder.--pushtrue--image-name<my_image_name>:<optional_image_version>
You can also check out ourin-depth guide on prebuilds.
Metadata in image labels
You can include Dev Container configuration and Feature metadata in prebuilt images viaimage labels.This makes the image self-contained since these settings are automatically picked up when the image is referenced - whether directly, in aFROM
in a referenced Dockerfile, or in a Docker Compose file. This helps prevent your Dev Container config and image contents from getting out of sync, and allows you to push updates of the same configuration to multiple repositories through a simple image reference.
This metadata label isautomatically addedwhen you pre-build using theDev Container CLI(or other spec supporting utilities like theGitHub ActionorAzure DevOps task) and includes settings fromdevcontainer.json
and any referenced Dev Container Features.
This allows you to have a separatemore complexdevcontainer.json
you use to pre-build your image, and then a dramaticallysimplified onein one or more repositories. The contents of the image will be merged with this simplified devcontainer.json content at the time you create the container (see thethe specfor info on merge logic). But at its simplest, you can just reference the image directly indevcontainer.json
for the settings to take effect:
{
"image":"mcr.microsoft /devcontainers/go:1"
}
Note that you can also opt to manually add metadata to an image label instead. These properties will be picked up even if you didn’t use the Dev Container CLI to build (and can be updated by the CLI even if you do). For example, consider this Dockerfile snippet:
LABELdevcontainer.metadata='[{ \
"capAdd": [ "SYS_PTRACE" ], \
"remoteUser": "devcontainer", \
"postCreateCommand": "yarn install" \
}]'
See theDev Container metadata referencefor information on which properties are supported.
Domain Names
If you are behind a firewall that needs to allow specific domains used by the Dev Container CLI, here’s the list of hostnames you should allow communication to go through:
containers.dev
- Thehomepagefor everything about dev containers. It includes all official and community-supportedFeaturesandTemplates.ghcr.io
,*.azurecr.io
,mcr.microsoft
-OCI registrieslikeGitHub Container Registry,Azure Container Registry,andMicrosoft Container Registryserves as the primary distribution mechanism for dev container resources.