### Parallel Lifecycle Script Execution Example Source: https://github.com/devcontainers/spec/blob/main/docs/specs/parallel-lifecycle-script-execution.md Defines 'postCreateCommand' to run 'npm start' and a 'mysql' command in parallel. Each command must succeed for the stage to be considered successful. ```json { "postCreateCommand": { "server": "npm start", "db": ["mysql", "-u", "root", "-p", "my database"] } } ``` -------------------------------- ### Full-featured devcontainer.json Example Source: https://context7.com/devcontainers/spec/llms.txt This example demonstrates a comprehensive `devcontainer.json` configuration, covering image/Dockerfile scenarios, Features, port forwarding, environment variables, user configuration, mounts, lifecycle scripts, host requirements, container behavior, workspace settings, and declarative secrets. ```jsonc // .devcontainer/devcontainer.json — full-featured example { "name": "My Node.js App", // --- Image / Dockerfile scenario --- "build": { "dockerfile": "Dockerfile", "context": "..", "args": { "VARIANT": "18-bullseye" }, "target": "development" }, // --- OR: use a prebuilt image directly --- // "image": "mcr.microsoft.com/devcontainers/typescript-node:18", // --- OR: Docker Compose scenario --- // "dockerComposeFile": ["../docker-compose.yml", "docker-compose.dev.yml"], // "service": "app", // "runServices": ["app", "db"], // Features — add tooling on top of the base image "features": { "ghcr.io/devcontainers/features/github-cli:1": {}, "ghcr.io/devcontainers/features/python:1": { "version": "3.11", "pip": true } }, // Override Feature install order "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/python", "ghcr.io/devcontainers/features/github-cli" ], // Port forwarding "forwardPorts": [3000, "db:5432"], "portsAttributes": { "3000": { "label": "App", "onAutoForward": "openPreview" } }, "otherPortsAttributes": { "onAutoForward": "silent" }, // Environment variables "containerEnv": { "NODE_ENV": "development" }, "remoteEnv": { "PATH": "${containerEnv:PATH}:/home/node/.local/bin" }, // Users "remoteUser": "node", "containerUser": "node", "updateRemoteUserUID": true, "userEnvProbe": "loginInteractiveShell", // Mounts "mounts": [ { "source": "node-modules-${devcontainerId}", "target": "/workspace/node_modules", "type": "volume" } ], // Lifecycle scripts "initializeCommand": "echo 'Running on host'", "onCreateCommand": "npm ci", "updateContentCommand": "npm run build", "postCreateCommand": { "deps": "npm install", "dbseed": ["node", "scripts/seed-db.js"] }, "postStartCommand": "npm run dev -- --no-open", "postAttachCommand": "git fetch --all", "waitFor": "postCreateCommand", // Minimum host requirements "hostRequirements": { "cpus": 4, "memory": "8gb", "storage": "32gb", "gpu": "optional" }, // Container behaviour "overrideCommand": true, "shutdownAction": "stopContainer", "init": false, "privileged": false, "capAdd": ["SYS_PTRACE"], "securityOpt": ["seccomp=unconfined"], "runArgs": ["--device-cgroup-rule=c 188:* rmw"], // Workspace (image/Dockerfile only) "workspaceFolder": "/workspace", "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", // Tool-specific customizations "customizations": { "vscode": { "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"], "settings": { "editor.formatOnSave": true } } }, // Declarative secrets "secrets": { "OPENAI_API_KEY": { "description": "OpenAI API key for AI features.", "documentationUrl": "https://platform.openai.com/docs/api-reference/authentication" } } } ``` -------------------------------- ### Feature Installation Order and Dependencies Source: https://context7.com/devcontainers/spec/llms.txt Illustrates how to control feature installation order using `dependsOn` for hard dependencies and `installsAfter` for soft hints in devcontainer-feature.json. Users can override this order with `overrideFeatureInstallOrder` in devcontainer.json. ```jsonc // devcontainer-feature.json for a Feature that needs common-utils first { "id": "mydb-client", "version": "1.0.0", "name": "My DB Client", // Hard dependency: common-utils MUST be installed before mydb-client. // If common-utils is not already in the user's feature list, it is auto-added. "dependsOn": { "ghcr.io/devcontainers/features/common-utils:2": { "installZsh": true } }, // Soft hint: if node is already queued, install it first. "installsAfter": ["ghcr.io/devcontainers/features/node"] } ``` ```jsonc // User's devcontainer.json — override the resolved order { "image": "mcr.microsoft.com/devcontainers/base:bullseye", "features": { "ghcr.io/devcontainers/features/node:1": {}, "ghcr.io/devcontainers/features/python:1": {}, "ghcr.io/devcontainers/features/common-utils:2": {} }, // Installs common-utils first, then python, then node "overrideFeatureInstallOrder": [ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/python", "ghcr.io/devcontainers/features/node" ] } ``` -------------------------------- ### Devcontainer-template.json Options Property Example Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-templates.md Example of the 'options' property in `devcontainer-template.json`, used to define customizable settings for a development environment. ```json { "options": { "optionId": { "type": "string", "description": "Description of the option", "proposals": ["value1", "value2"], "default": "value1" } } } ``` -------------------------------- ### Install Dev Container Features with features Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Use the `features` property to include Dev Container Features and their configurations in your primary container. Options vary per feature. ```json "features": { "ghcr.io/devcontainers/features/github-cli": {} } ``` -------------------------------- ### Devcontainer Lockfile Example Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-lockfile.md This example shows a basic devcontainer lockfile structure for OCI and tarball features. ```json { "features": { "ghcr.io/devcontainers/features/node:1": { "version": "1.0.4", "resolved": "ghcr.io/devcontainers/features/node@sha256:567d704b3f4d3eca3acee51ded7c460a8395436d135d53d1175fb565daff42b8", "integrity": "sha256:567d704b3f4d3eca3acee51ded7c460a8395436d135d53d1175fb565daff42b8" }, "https://mycustomdomain.com/devcontainer-feature-myfeature.tgz": { "version": "1.2.3", "resolved": "https://mycustomdomain.com/devcontainer-feature-myfeature.tgz", "integrity": "sha256:567d704b3f4d3eca3acee51ded7c460a8395436d135d53d1175fb565daff42b8" } } } ``` -------------------------------- ### Dev Container Feature File Structure Example Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features-distribution.md Illustrates the typical directory structure for a Dev Container Feature collection in a Git repository. Includes source files, metadata, and optional test files. ```bash . \ ├── README.md \ ├── src \ │ ├── dotnet \ │ │ ├── devcontainer-feature.json \ │ │ ├── install.sh \ │ │ └── ... \ │ ├ \ │ ├── go \ │ │ ├── devcontainer-feature.json \ │ │ └── install.sh \ │ ├── ... \ │ │ ├── devcontainer-feature.json \ │ │ └── install.sh \ ├── test \ │ ├── dotnet \ │ │ ├── test.sh \ │ │ └── ... \ │ └── go \ │ | └── test.sh \ │ ├── ... \ │ │ └── test.sh \ ├── ... ``` -------------------------------- ### Example Secrets JSON File Source: https://github.com/devcontainers/spec/blob/main/docs/specs/secrets-support.md Demonstrates the JSON file format for passing secrets to a supporting tool. This approach allows for simple adoption and secure input of sensitive variables. ```json { "API_KEY": "adsjhsd6dfwdjfwde7edwfwedfdjedwf7wedfwe", "NUGET_CONFIG": "\n \n \n", "PASSWORD": "Simple Passwords" } ``` -------------------------------- ### Install Script Accessing Feature Options Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md A bash script demonstrating how an 'install.sh' entrypoint script can access the environment variables that were set based on the Feature's options. The variables are directly available for use within the script. ```bash #!/usr/bin/env bash echo "Version is $VERSION" echo "Pip? $PIP" echo "Optimize? $OPTIMIZE" ``` -------------------------------- ### Devcontainer.json with Multiple Features and Hooks Source: https://github.com/devcontainers/spec/blob/main/docs/specs/features-contribute-lifecycle-scripts.md Example of a devcontainer.json file that includes multiple Features and user-defined lifecycle hooks. This demonstrates the order of execution for both Feature and user commands. ```jsonc { "image": "ubuntu", "features": { "featureA": {}, "featureB": {}, }, "postCreateCommand": "userPostCreate.sh", "postAttachCommand": { "server": "npm start", "db": ["mysql", "-u", "root", "-p", "my database"] }, } ``` -------------------------------- ### Docker-in-Docker Feature Mount Example Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-id-variable.md Example of how the `docker-in-docker` feature can utilize the `${devcontainerId}` variable to create a persistent volume for Docker's data directory, ensuring it's unique to each dev container. ```json { "id": "docker-in-docker", "version": "1.0.4", // ... "mounts": [ { "source": "dind-var-lib-docker-${devcontainerId}", "target": "/var/lib/docker", "type": "volume" } ] } ``` -------------------------------- ### Devcontainer Lockfile with Dependencies Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-lockfile.md This example demonstrates a devcontainer lockfile that includes feature dependencies, showing how 'dependsOn' links features. ```json { "features": { "ghcr.io/codspace/dependson/a": { "version": "1.2.1", "resolved": "ghcr.io/codspace/dependson/a@sha256:932027ef71da186210e6ceb3294c3459caaf6b548d2b547d5d26be3fc4b2264a", "integrity": "sha256:932027ef71da186210e6ceb3294c3459caaf6b548d2b547d5d26be3fc4b2264a", "dependsOn": [ "ghcr.io/codspace/dependson/e:2" ] }, "ghcr.io/codspace/dependson/e:2": { "version": "2.3.4", "resolved": "ghcr.io/codspace/dependson/e@sha256:9f36f159c70f8bebff57f341904b030733adb17ef12a5d58d4b3d89b2a6c7d5a", "integrity": "sha256:9f36f159c70f8bebff57f341904b030733adb17ef12a5d58d4b3d89b2a6c7d5a" } } } ``` -------------------------------- ### User Input for Template Options Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-templates.md Provides example user inputs for template options. These values are used to replace the ${templateOption:optionName} placeholders in the devcontainer.json. Ensure the provided values match the expected types and proposals. ```json { imageVariant:"17-bullseye", nodeVersion: "latest", installMaven: "false" } ``` -------------------------------- ### User Environment Variables in Feature Install Scripts Source: https://context7.com/devcontainers/spec/llms.txt Feature install scripts receive special environment variables for handling non-root container setups correctly. These variables provide information about the container user and their home directory. ```bash #!/usr/bin/env bash # install.sh — Feature install entrypoint (runs as root) # _CONTAINER_USER: the user the container process runs as (e.g. from Dockerfile USER) # _REMOTE_USER: the devcontainer.json remoteUser (defaults to _CONTAINER_USER) # _CONTAINER_USER_HOME / _REMOTE_USER_HOME: their respective home directories echo "Container user: $_CONTAINER_USER (home: $_CONTAINER_USER_HOME)" echo "Remote user: $_REMOTE_USER (home: $_REMOTE_USER_HOME)" # Install tool globally as root curl -fsSL https://example.com/install.sh | bash # Configure tool for the dev user without requiring sudo su "$_REMOTE_USER" -c "mytool config set theme dark --home $_REMOTE_USER_HOME" # Copy a config file to the non-root home directory cp /tmp/mytool.conf "$_REMOTE_USER_HOME/.config/mytool/config" chown "$_REMOTE_USER" "$_REMOTE_USER_HOME/.config/mytool/config" ``` -------------------------------- ### Example overrideFeatureInstallOrder in JSON Source: https://github.com/devcontainers/spec/blob/main/docs/specs/feature-dependencies.md Defines the order in which features should be installed, overriding the default dependency-based order. Features listed earlier have higher priority. This property does not affect the dependency graph itself. ```json overrideFeatureInstallOrder = [ "foo", "bar", "baz" ] ``` -------------------------------- ### Example roundPriority calculation Source: https://github.com/devcontainers/spec/blob/main/docs/specs/feature-dependencies.md Illustrates how `overrideFeatureInstallOrder` translates into `roundPriority` values for Features. Higher numerical values indicate higher installation priority after dependencies are met. This is a conceptual representation. ```javascript const roundPriority = { "foo": 3, "bar": 2, "baz": 1 } ``` -------------------------------- ### Example User devcontainer.json Configuration Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md This JSONC snippet illustrates how a user would configure the 'python' Feature in their 'devcontainer.json'. It specifies the Feature ID and overrides the default values for 'version' and 'pip'. ```jsonc "features": { "ghcr.io/devcontainers/features/python:1": { "version": "3.10", "pip": false } } ``` -------------------------------- ### Define Soft Dependencies with `installsAfter` Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md Use the `installsAfter` property to indicate a soft dependency, influencing the installation order of Features already queued. This property is not recursive and only affects Features explicitly set for installation. ```json { "name": "My Feature", "id": "myFeature", "version": "1.0.0", "installsAfter": [ "foo", "bar" ] } ``` -------------------------------- ### Example Feature Options Declaration Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md This JSONC snippet shows the 'options' property within a Feature's 'devcontainer-feature.json'. It defines configurable parameters like 'version', 'pip', and 'optimize' with their types, allowed values (enum), default values, and descriptions. ```jsonc // ... "options": { "version": { "type": "string", "enum": ["latest", "3.10", "3.9", "3.8", "3.7", "3.6"], "default": "latest", "description": "Select a Python version to install." }, "pip": { "type": "boolean", "default": true, "description": "Installs pip" }, "optimize": { "type": "boolean", "default": true, "description": "Optimize python installation" } } ``` -------------------------------- ### Dev Container Feature Install Script Source: https://context7.com/devcontainers/spec/llms.txt The install script for a Dev Container Feature, written in bash. It uses environment variables derived from feature options and user context variables provided by the tooling. ```bash # src/myfeature/install.sh #!/usr/bin/env bash set -e # Options are injected as env vars (uppercased option IDs) echo "Installing mytool version: $VERSION" echo "Install extras: $INSTALL_EXTRAS" # User context variables injected by the tooling echo "Container user: $_CONTAINER_USER" echo "Remote user: $_REMOTE_USER" echo "Remote home: $_REMOTE_USER_HOME" curl -fsSL "https://mytool.example.com/install.sh" | bash -s -- "$VERSION" if [ "$INSTALL_EXTRAS" = "true" ]; then mytool plugin install all fi # Run a step as the non-root user su "$_REMOTE_USER" -c "mytool init --profile default" ``` -------------------------------- ### Devcontainer.json Features Object Example Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md Illustrates how to define multiple devcontainer features with different versions and sources within the 'features' object. ```json "features": { "ghcr.io/user/repo/go": {}, "ghcr.io/user/repo1/go:1": {}, "ghcr.io/user/repo2/go:latest": {}, "https://github.com/user/repo/releases/devcontainer-feature-go.tgz": { "optionA": "value" }, "./myGoFeature": { "optionA": true, "optionB": "hello", "version" : "1.0.0" } } ``` -------------------------------- ### Example Dev Container Template File Structure Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-templates-distribution.md Illustrates the typical directory structure for a Dev Container Template collection within a git repository. Each template resides in its own subdirectory under 'src', containing its metadata and configuration files. ```tree . ├── README.md ├── src │ ├── dotnet │ │ ├── devcontainer-template.json │ │ ├── .devcontainer │ │ ├── devcontainer.json │ │ └── ... │ │ ├── ... | | ├── docker-from-docker │ │ ├── devcontainer-template.json │ │ ├── .devcontainer │ │ ├── devcontainer.json │ │ ├── Dockerfile │ │ └── ... │ │ ├── ... | | ├── go-postgres │ │ ├── devcontainer-template.json │ │ ├── .devcontainer │ │ ├── devcontainer.json │ │ ├── docker-compose.yml │ │ ├── Dockerfile │ │ └── ... │ │ ├── ... ``` -------------------------------- ### Emitted Environment Variables for Feature Options Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md This example shows the environment variables that would be emitted into 'devcontainer-features.env' based on the user's 'devcontainer.json' configuration and the Feature's 'options' declaration. These variables are sourced by the 'install.sh' script. ```env VERSION="3.10" PIP="false" OPTIMIZE="true" ``` -------------------------------- ### Dev Container Lifecycle Scripts Source: https://context7.com/devcontainers/spec/llms.txt Configures commands to run at different stages of the container lifecycle, including initialization, creation, content updates, starting, and attaching. Supports string, array, or object formats for commands. ```jsonc { "image": "mcr.microsoft.com/devcontainers/base:bullseye", // Runs on the HOST during init (including on subsequent starts). "initializeCommand": "docker info", // Runs INSIDE the container on first creation — cacheable by cloud services. "onCreateCommand": "sudo apt-get update && sudo apt-get install -y jq", // Runs inside container when new source content is available; re-run on prebuild refresh. "updateContentCommand": ["bash", "-c", "pip install -r requirements.txt"], // Runs inside container once, after being assigned to a user (user secrets available). "postCreateCommand": { "server": "npm install", "db": ["python", "manage.py", "migrate"] }, // Runs every time the container STARTS (not only on creation). "postStartCommand": "service ssh start", // Runs every time a tool ATTACHES to the running container. "postAttachCommand": "git fetch --prune", // Which command must finish before the tool connects. "waitFor": "postCreateCommand" } ``` -------------------------------- ### Execute Bundled Script in FeatureB Source: https://github.com/devcontainers/spec/blob/main/docs/specs/features-contribute-lifecycle-scripts.md Shows how to use a postCreateCommand to execute a script bundled within the Feature. The install.sh script must copy the bundled script to a persistent location in the container. ```jsonc { "id": "featureB", "version": "1.0.0", "postCreateCommand": "/usr/myDir/bundledScript.sh", "installsAfter": [ "featureA" ] } ``` ```sh #!/bin/sh cp ./bundleScript /usr/myDir ... ... ``` -------------------------------- ### Using Variables in devcontainer.json Source: https://context7.com/devcontainers/spec/llms.txt Demonstrates how to use various dynamic variables like ${localEnv:VAR}, ${containerEnv:VAR}, ${localWorkspaceFolder}, and ${devcontainerId} to configure environment variables, mounts, and other settings. ```jsonc { "name": "Demo of variables", "image": "mcr.microsoft.com/devcontainers/base:bullseye", // ${localEnv:VAR} — reads from the host machine's environment "remoteEnv": { "LOCAL_HOME": "${localEnv:HOME}${localEnv:USERPROFILE}", // Linux/macOS or Windows "NPM_TOKEN": "${localEnv:NPM_TOKEN:}" // empty string default }, // ${containerEnv:VAR} — reads an already-set container env variable "remoteEnv": { "PATH": "${containerEnv:PATH}:/opt/mytools/bin" }, // ${localWorkspaceFolder} — host path containing .devcontainer/ // ${containerWorkspaceFolder} — path inside the container // ${localWorkspaceFolderBasename} / ${containerWorkspaceFolderBasename} "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", // ${devcontainerId} — stable, unique alphanumeric ID for this dev container // (use only in runtime properties, not image-build properties) "mounts": [ { "source": "cache-${devcontainerId}", "target": "/home/vscode/.cache", "type": "volume" } ] } ``` -------------------------------- ### Override Feature Install Order Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Use `overrideFeatureInstallOrder` to manually define the sequence in which Dev Container Features are installed, overriding the default `installsAfter` logic. ```json "overrideFeatureInstallОrder": [ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/github-cli" ] ``` -------------------------------- ### Configure Workspace Mount and Folder Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Override the default workspace mount point using `workspaceMount` and set the default path for tools to open with `workspaceFolder`. Both require each other. ```json { "workspaceMount": "source=${localWorkspaceFolder}/sub-folder,target=/workspace,type=bind,consistency=cached", "workspaceFolder": "/workspace" } ``` -------------------------------- ### Specify Docker Build Options Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Provide Docker image build options using the `build.options` array. These are passed directly to the `docker build` command. ```json { "build": { "options": [ "--add-host=host.docker.internal:host-gateway" ] } } ``` -------------------------------- ### OCI Image Manifest with Dev Container Metadata Annotation Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features-distribution.md An example of an OCI image manifest that includes the `dev.containers.metadata` annotation. This annotation contains the escaped JSON object of the `devcontainer-feature.json`. ```json { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", "config": { "mediaType": "application/vnd.devcontainers", "digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "size": 0 }, "layers": [ { "mediaType": "application/vnd.devcontainers.layer.v1+tar", "digest": "sha256:738af5504b253dc6de51d2cb1556cdb7ce70ab18b2f32b0c2f12650ed6d2e4bc", "size": 3584, "annotations": { "org.opencontainers.image.title": "devcontainer-feature-myFeature.tgz" } } ], "annotations": { "dev.containers.metadata": "{\"name\": \"My Feature\",\"id\": \"myFeature\",\"version\": \"1.0.0\",\"dependsOn\": {\"ghcr.io/myotherFeature:1\": {\"flag\": true},\"features.azurecr.io/aThirdFeature:1\": {}\,"features.azurecr.io/aFourthFeature:1.2.3\": {}}}" } } ``` -------------------------------- ### Configure Container Security Options with securityOpt Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Use `securityOpt` to set container security options like `seccomp=unconfined`. Defaults to an empty array. ```json "securityOpt": [ "seccomp=unconfined" ] ``` -------------------------------- ### Disable Automatic Configuration in GitHub Codespaces Source: https://github.com/devcontainers/spec/blob/main/docs/specs/supporting-tools.md Set 'disableAutomaticConfiguration' to true within the 'codespaces' customization to prevent GitHub Codespaces from performing default setup when a 'postCreateCommand' is not specified in devcontainer.json. ```jsonc "customizations": { // Configure properties specific to Codespaces. "codespaces": { "disableAutomaticConfiguration": true } } ``` -------------------------------- ### Pushing Dev Container Features to OCI Registry Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features-distribution.md Use `oras push` to publish a Feature tarball to an OCI registry. This example demonstrates pushing multiple versions of the 'go' Feature to ghcr.io/devcontainers/features. ```bash # ghcr.io/devcontainers/features/go:1 REGISTRY=ghcr.io NAMESPACE=devcontainers/features FEATURE=go ARTIFACT_PATH=devcontainer-feature-go.tgz for VERSION in 1 1.2 1.2.3 latest do oras push ${REGISTRY}/${NAMESPACE}/${FEATURE}:${VERSION} \ --manifest-config /dev/null:application/vnd.devcontainers \ ./${ARTIFACT_PATH}:application/vnd.devcontainers.layer.v1+tar done ``` -------------------------------- ### Dev Container Configuration Using Template Options Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-templates.md Configures a dev container using template options. The 'image' and 'features' properties reference template options using the ${templateOption:optionName} syntax. This allows dynamic configuration based on user selections. ```json { "name": "Java", "image": "mcr.microsoft.com/devcontainers/java:0-${templateOption:imageVariant}", "features": { "ghcr.io/devcontainers/features/node:1": { "version": "${templateOption:nodeVersion}", "installMaven": "${templateOption:installMaven}" } }, // ... } ``` -------------------------------- ### Define Feature Dependencies with `dependsOn` Source: https://github.com/devcontainers/spec/blob/main/docs/specs/feature-dependencies.md Use the `dependsOn` property in `devcontainer-feature.json` to declare hard dependencies on other features. This ensures dependent features are installed before the current feature. Pinning to version tags or digests is supported. ```json { "name": "My Feature", "id": "myFeature", "version": "1.0.0", "dependsOn": { "ghcr.io/second:1": { "flag": true }, "features.azurecr.io/third:1": {}, "features.azurecr.io/fourth:1.2.3": {}, "features.azurecr.io/fifth@sha256:a4cdc44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855": {} } } ``` -------------------------------- ### Build Dev Container from Dockerfile Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Use `build.dockerfile` to specify the Dockerfile for building your dev container. The path is relative to the `devcontainer.json` file. ```json { "build": { "dockerfile": "Dockerfile" } } ``` -------------------------------- ### Configure Files to Open in GitHub Codespaces Source: https://github.com/devcontainers/spec/blob/main/docs/specs/supporting-tools.md Specify files to be automatically opened when a codespace is created using the 'openFiles' property within the 'codespaces' customization. Files are opened in the order listed. ```jsonc "customizations": { // Configure properties specific to Codespaces. "codespaces": { "openFiles": [ "README" "src/index.js" ] } } ``` -------------------------------- ### Forwarding Ports in Dev Container Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Specify ports to forward from the container to the local machine. Supports direct port numbers or host:port mappings, useful for services not automatically detected or in Docker Compose setups. ```json "forwardPorts": [3000, "db:5432"] ``` -------------------------------- ### Feature Option Resolution and Environment Variables Source: https://context7.com/devcontainers/spec/llms.txt Shows how feature options defined in devcontainer-feature.json are mapped to uppercase environment variables within the Feature's install.sh script. User-provided options override defaults. ```jsonc // devcontainer-feature.json options definition { "options": { "version": { "type": "string", "enum": ["latest", "3.10", "3.9", "3.8"], "default": "latest", "description": "Select a Python version." }, "pip": { "type": "boolean", "default": true, "description": "Install pip." }, "optimize": { "type": "boolean", "default": true, "description": "Optimize the installation." } } } ``` ```jsonc // User's devcontainer.json { "features": { "ghcr.io/devcontainers/features/python:1": { "version": "3.10", "pip": false // "optimize" omitted → uses default: true } } } ``` ```bash # Resulting devcontainer-features.env sourced into install.sh: # VERSION="3.10" # PIP="false" # OPTIMIZE="true" #!/usr/bin/env bash echo "Version: $VERSION" # 3.10 echo "Pip? $PIP" # false echo "Optimize? $OPTIMIZE" # true ``` -------------------------------- ### Dev Container Template Folder Structure Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-templates.md Illustrates the required and optional files within a Dev Container Template folder. ```plaintext +-- template | +-- devcontainer-template.json | +-- .devcontainer | +-- devcontainer.json | +-- (other files) | +-- (other files) ``` -------------------------------- ### Publish a Dev Container Template Source: https://context7.com/devcontainers/spec/llms.txt This script demonstrates how to package a devcontainer template and push it to an OCI registry using oras. It iterates through multiple tags to publish the template. ```shell NAMESPACE=myorg/mytemplates TEMPLATE=mytemplate tar -czf devcontainer-template-${TEMPLATE}.tgz -C src/${TEMPLATE} . for TAG in 1 1.0 1.0.0 latest; do oras push ${REGISTRY}/${NAMESPACE}/${TEMPLATE}:${TAG} \ --config /dev/null:application/vnd.devcontainers \ ./devcontainer-template-${TEMPLATE}.tgz:application/vnd.devcontainers.layer.v1+tar done ``` -------------------------------- ### Resulting `.devcontainer/devcontainer.json` after Option Replacement Source: https://context7.com/devcontainers/spec/llms.txt Shows the final `.devcontainer/devcontainer.json` file generated after a user selects template options. Placeholders are replaced with the chosen values, creating a project-specific configuration. ```jsonc // Resulting .devcontainer/devcontainer.json written into the user's project { "name": "Java", "image": "mcr.microsoft.com/devcontainers/java:0-17-bullseye", "features": { "ghcr.io/devcontainers/features/node:1": { "version": "latest" }, "ghcr.io/devcontainers/features/java:1": { "installMaven": "false" } } } ``` -------------------------------- ### JavaScript Function for Option Name Sanitization Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md This JavaScript function sanitizes option names to be valid environment variable names by replacing non-alphanumeric characters with underscores and ensuring the name does not start with a digit or underscore. It converts the name to uppercase. ```javascript (str: string) => str .replace(/[^\w_]/g, '_') .replace(/^[\d_]+/g, '_') .toUpperCase(); ``` -------------------------------- ### Specify Docker Build Cache From Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Use `build.cacheFrom` to provide images that should be used as caches during the Docker image build process. ```json { "build": { "cacheFrom": [ "my-cached-image:latest" ] } } ``` -------------------------------- ### Devcontainer Feature Version Shorthand Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md Demonstrates the shorthand notation for specifying a feature version directly as a string value. ```json "features": { "ghcr.io/owner/repo/go": "1.18" } ``` ```json "features": { "ghcr.io/owner/repo/go": { "version": "1.18" } } ``` -------------------------------- ### Define Hard Dependencies with `dependsOn` Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainer-features.md Use the `dependsOn` property to declare required Features that must be installed before the current Feature. Dependencies can be specified with options or as empty objects if defaults are sufficient. All dependencies, including recursively defined ones, must be satisfied. ```json { "name": "My Feature", "id": "myFeature", "version": "1.0.0", "dependsOn": { "foo:1": { "flag": true }, "bar:1.2.3": {}, "baz@sha256:a4cdc44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" {}, } } ``` -------------------------------- ### Build and Inspect Docker Image Metadata Source: https://context7.com/devcontainers/spec/llms.txt Builds a Docker image with embedded metadata and then inspects the `devcontainer.metadata` label to verify its content. The output shows the JSON array embedded in the label. ```bash # Building and inspecting the label docker build -t my-devcontainer-image . docker inspect my-devcontainer-image \ --format '{{ index .Config.Labels "devcontainer.metadata" }}' # Output: [{"remoteUser":"vscode","postCreateCommand":"echo container ready",...}] ``` -------------------------------- ### Pass Docker Build Arguments Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Use `build.args` to pass name-value pairs as Docker image build arguments. Environment variables can be referenced. ```json { "build": { "args": { "MYARG": "MYVALUE", "MYARGFROMENVVAR": "${localEnv:VARIABLE_NAME}" } } } ``` -------------------------------- ### Contribute Lifecycle Scripts to FeatureA Source: https://github.com/devcontainers/spec/blob/main/docs/specs/features-contribute-lifecycle-scripts.md Illustrates contributing onCreateCommand and postCreateCommand scripts to a Feature. These scripts execute in the project workspace folder, similar to user-defined lifecycle hooks. ```jsonc { "id": "featureA", "version": "1.0.0", "onCreateCommand": "myOnCreate.sh && myOnCreate2.sh", "postCreateCommand": "myPostCreate.sh", "postAttachCommand": { "command01": "myPostAttach.sh arg01", "command02": "myPostAttach.sh arg02", }, } ``` -------------------------------- ### Publish a Dev Container Feature using `oras` Source: https://context7.com/devcontainers/spec/llms.txt Packages a dev container feature into a tarball and pushes it to an OCI registry using `oras`. It demonstrates pushing version tags and a collection index. ```bash # --- Publish a Feature --- REGISTRY=ghcr.io NAMESPACE=myorg/myfeatures FEATURE=myfeature VERSION=1.2.3 # Package the Feature directory into a tarball tar -czf devcontainer-feature-${FEATURE}.tgz -C src/${FEATURE} . # Push all required version tags (major, minor, patch, latest) for TAG in 1 1.2 1.2.3 latest; do oras push ${REGISTRY}/${NAMESPACE}/${FEATURE}:${TAG} \ --manifest-config /dev/null:application/vnd.devcontainers \ ./devcontainer-feature-${FEATURE}.tgz:application/vnd.devcontainers.layer.v1+tar done # Push the collection index (always tagged latest, no feature name) oras push ${REGISTRY}/${NAMESPACE}:latest \ --manifest-config /dev/null:application/vnd.devcontainers \ ./devcontainer-collection.json:application/vnd.devcontainers.collection.layer.v1+json ``` -------------------------------- ### Set Docker Build Context Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Configure the `build.context` to specify the directory where the Docker build should be run from, relative to `devcontainer.json`. ```json { "build": { "dockerfile": "Dockerfile", "context": ".." } } ``` -------------------------------- ### Using localEnv Variable Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Reference environment variables from the host machine using the `${localEnv:VARIABLE_NAME}` format. A default value can be provided. ```json "remoteEnv": { "LOCAL_USER_PATH": "${localEnv:HOME}${localEnv:USERPROFILE}" } ``` -------------------------------- ### Declare GPU Requirements in devcontainer.json Source: https://context7.com/devcontainers/spec/llms.txt Specify GPU needs alongside other hardware resources. Use a boolean for simple requirements or an object for minimum specifications. ```jsonc { "image": "mcr.microsoft.com/devcontainers/base:bullseye", "hostRequirements": { "cpus": 8, "memory": "32gb", "storage": "128gb", // Boolean: GPU required "gpu": true, // String: GPU used if available, but not required // "gpu": "optional", // Object: GPU required with minimum specs "gpu": { "cores": 4, "memory": "8gb" } } } ``` -------------------------------- ### Configuring Port Attributes Source: https://github.com/devcontainers/spec/blob/main/docs/specs/devcontainerjson-reference.md Define default options for specific ports or port ranges. This allows customization of how ports are handled, such as adding labels. ```json "portsAttributes": { "3000": {"label": "Application port"} } ``` -------------------------------- ### Dev Container Configuration for a Template (`devcontainer.json`) Source: https://context7.com/devcontainers/spec/llms.txt Specifies the dev container configuration for a template, using placeholders like `${templateOption:...}` for dynamic option replacement. This file is combined with the template manifest. ```jsonc // src/java/.devcontainer/devcontainer.json (uses ${templateOption:...} placeholders) { "name": "Java", "image": "mcr.microsoft.com/devcontainers/java:0-${templateOption:imageVariant}", "features": { "ghcr.io/devcontainers/features/node:1": { "version": "${templateOption:nodeVersion}" }, "ghcr.io/devcontainers/features/java:1": { "installMaven": "${templateOption:installMaven}" } } } ```