Each subdirectory under examples/ is fully self‑contained: copy or cd into it and run the shown commands without referencing assets elsewhere in the repo.
Several of the newer examples are intentionally designed as canaries — they exercise spec-mandated behavior that deacon doesn't fully implement yet. If you run them today and they fail, it's by design.
The single source of truth for which examples are currently blocked on upstream deacon bugs is the tracking issue:
➡️ #74 — Tracking: example scripts blocked on upstream deacon bugs
That issue lists each blocked example, the specific deacon bug it surfaces, and ticks them off as the underlying issues land. Each affected example's own README.md also links to the specific issue(s) it surfaces, as a breadcrumb back to #74.
Workaround for running examples today: most up-based examples currently need --mount-workspace-git-root false (see #67) when run from inside the deacon repo, to avoid silently picking up the repo's own .devcontainer/. Once #67 lands, the workaround is no longer needed.
-
Build: Dockerfile builds, platform targeting, build args, secrets & SSH, Compose service targeting, image reference builds, multi-tag + labels, push/export workflows, feature installation across modes, validation & error scenarios (
build/) -
CLI: CLI-specific features and flags including port forwarding and custom container names (
cli/) -
Container Lifecycle: lifecycle command execution, ordering, variables, skip flags, progress events, and redaction (
container-lifecycle/) -
Exec: command execution semantics covering working directory, user, TTY, and environment (
exec/) -
Observability: JSON logs, standardized spans, and structured fields (
observability/) -
Registry: authentication methods for push/pull operations (
registry/) -
Configuration (
configuration/)configuration/basic/— Minimum viable configconfiguration/with-variables/—${localEnv:VAR}and workspace tokensconfiguration/extends-chain/— Chainedextendsacross base/mid/leafconfiguration/extends-chain-cycle/— Cycle detection in extends (two-file + self-extending)configuration/nested-variables/— Variable substitution into nested objectsconfiguration/secrets-declarative/— Top-levelsecretsproperty with description + documentationUrl
-
Docker Compose (
compose/)compose/multiservice-basic/— App + Redis,shutdownAction: stopComposecompose/multiple-compose-files/—dockerComposeFileas an array merging base + overridecompose/port-events/—--ports-eventsstreaming
-
Doctor (
doctor/)doctor/host-requirements/— Realistic CPU/memory/storage check (passes)doctor/host-requirements-failure/— Unmeetable requirements (text + JSON output)doctor/gpu-host-requirements/—hostRequirements.gpuin all three spec shapes (true,"optional", object)
-
Down (
down/)down/basic/—shutdownAction: stopContainer,--remove,--volumes,--force,--all, idempotency
-
Feature System (
features/)features/dependencies-and-ordering/—dependsOn/installsAfterresolutionfeatures/parallel-install-demo/— Parallel install levelsfeatures/cache-reuse-hint/— Digest-based cachingfeatures/lockfile-demo/—devcontainer-lock.jsonshapefeatures/override-install-order/—overrideFeatureInstallOrderforces non-default orderfeatures/feature-contributed-lifecycle/— Feature-declaredpostCreate/postStartmerge with the user'sfeatures/feature-env-injection/— Spec-mandated_REMOTE_USER/_REMOTE_USER_HOME/_CONTAINER_USER/_CONTAINER_USER_HOMEduring installfeatures/option-sanitization/— Option-name → env-var name sanitization rulesfeatures/oci-digest-pin/— Feature ref pinned by@sha256:for reproducibility (network)
-
Read-Configuration (
read-configuration/)read-configuration/basic/— Minimal config discovery and outputread-configuration/with-variables/— Variable substitution for local env and workspace folderread-configuration/extends-chain/— Chainedextendsacross base/mid/leaf configsread-configuration/override-config/— Apply an override with--override-configread-configuration/features-minimal/— Local Feature with--include-features-configurationread-configuration/features-additional/— Inject a Feature via--additional-featuresread-configuration/compose/— Config referencing a Docker Compose fileread-configuration/legacy-normalization/— LegacycontainerEnvnormalized toremoteEnvread-configuration/id-labels-and-devcontainerId/—${devcontainerId}via--id-labelread-configuration/named-config-search/—.devcontainer/<name>/devcontainer.jsondiscovery alongside the default
-
Run-User-Commands (
run-user-commands/)run-user-commands/basic/— Re-execute lifecycle hooks against an existing container; covers--prebuild,--skip-non-blocking-commands,--container-id
-
Set-Up (
set-up/)set-up/basic/— Attach to a vanilladocker runcontainer and layer adevcontainer.jsonvia--config
-
Template Management (
template-management/)template-management/minimal-template/— Minimal template metadata + applytemplate-management/template-with-options/— Boolean, string, enum optionstemplate-management/templates-apply/— Driver script for the apply workflowtemplate-management/optional-paths/— Spec-mandatoryoptionalPathsfield for opt-in files
-
Up (
up/)up/basic-image/— Image-based startup/dockerfile-build/— Build from Dockerfileup/compose-basic/,up/compose-profiles/— Compose with optional profilesup/with-features/— Features installed during upup/lifecycle-hooks/— All five hooksup/initialize-command/— Host-sideinitializeCommand+ workspace-trust gate (--trust-workspace,--trust-workspace-persist,DEACON_NO_PROMPT)up/skip-lifecycle/— Lifecycle skip flagsup/prebuild-mode/—--prebuildup/dotfiles-integration/— Dotfiles flagsup/additional-mounts/,up/workspace-mount/— Extra mounts and customworkspaceMountup/remote-env-secrets/—--remote-env,--secrets-fileup/id-labels-reconnect/,up/remove-existing/— Reconnect / replace patternsup/gpu-modes/—--gpu-availabilityup/configuration-output/—--include-configuration/--include-merged-configurationup/user-env-probe-modes/—userEnvProbefour-value matrix on the up sideup/wait-for/—waitForenum +--skip-non-blocking-commandscutoffup/container-user-vs-remote-user/—containerUser(PID 1) vsremoteUser(lifecycle + exec)up/security-options/—init,capAdd,securityOpt,privilegedup/override-command/—overrideCommand: falseruns the image's own CMDup/update-remote-user-uid/— UID/GID sync to host user (Linux)up/ports-config/—forwardPortsstring form,portsAttributessub-fields,otherPortsAttributes,appPortup/image-metadata-merge/— Imagedevcontainer.metadataLABEL merged with user config
Build a basic Dockerfile with build args:
cd examples/build/basic-dockerfile
deacon build --workspace-folder . --build-arg FOO=BAR --output-format jsonBuild with platform targeting and no cache:
cd examples/build/platform-and-cache
deacon build --workspace-folder . --platform linux/amd64 --no-cacheBuild with secrets (requires BuildKit):
cd examples/build/secrets-and-ssh
echo "test-secret" > /tmp/secret.txt
deacon build --workspace-folder . --secret id=foo,src=/tmp/secret.txtBuild from a Compose service with custom tags:
cd examples/build/compose-service-target
deacon build --workspace-folder . --image-name myapp:latestBuild from an image reference with labels:
cd examples/build/image-reference
deacon build --workspace-folder . --image-name myimage:latest --label "version=1.0"Build with multiple tags and push to registry (requires BuildKit):
cd examples/build/basic-dockerfile
deacon build --workspace-folder . \
--image-name myrepo/app:latest \
--image-name myrepo/app:v1.0 \
--pushBuild and export to OCI archive (requires BuildKit):
cd examples/build/basic-dockerfile
deacon build --workspace-folder . --output type=oci,dest=app.tarValidate a configuration example:
cd examples/configuration/basic
deacon config validate . --jsonStart a basic development container:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . --include-configuration | jq '.containerId'Start with prebuild mode (CI/CD workflows):
cd examples/container-lifecycle/basic
deacon up --workspace-folder . --prebuild --include-configuration
# Outputs JSON with container ready for cachingStart with dotfiles installation:
cd examples/container-lifecycle/advanced
deacon up --workspace-folder . \
--dotfiles-repository https://github.com/user/dotfiles \
--dotfiles-install-command "./install.sh"Start with additional mounts and remote environment:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . \
--mount "type=bind,source=/tmp/cache,target=/cache" \
--remote-env "NODE_ENV=development" \
--remote-env "DEBUG=true"Start with secrets file:
cd examples/container-lifecycle/advanced
echo "API_KEY=secret123" > /tmp/secrets.env
deacon up --workspace-folder . --secrets-file /tmp/secrets.env
# Secrets are redacted from logs automaticallyStart with BuildKit cache:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . \
--buildkit auto \
--cache-from type=registry,ref=myrepo/cache \
--cache-to type=registry,ref=myrepo/cacheStart with ID labels for reconnection:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . \
--id-label project=myapp \
--id-label environment=dev
# Later reconnect with same labels
deacon up --id-label project=myapp --id-label environment=dev --expect-existing-containerStart with skip flags for faster iteration:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . --skip-post-create --skip-post-attach
# Skips lifecycle hooks for faster startupStart with included merged configuration:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . \
--include-configuration \
--include-merged-configuration | jq '.mergedConfiguration'Start with custom Docker paths and data folders:
cd examples/container-lifecycle/basic
deacon up --workspace-folder . \
--docker-path /usr/local/bin/docker \
--container-data-folder /workspace/.devcontainer \
--user-data-folder ~/.local/share/deaconStart a container with custom name:
cd examples/cli/custom-container-name
deacon up --container-name my-dev-container --skip-post-createExplore template assets:
cd examples/template-management/template-with-options
ls -1
cat devcontainer-template.json | jq '.id, .options'Apply a template with custom options:
cd examples/template-management/templates-apply
mkdir -p /tmp/my-project
deacon templates apply ../template-with-options \
--output /tmp/my-project \
--option customName=my-app \
--option debugMode=trueRun doctor command for system diagnostics:
cd examples/doctor/host-requirements
deacon doctor --workspace-folder .
# Or for JSON output
deacon doctor --workspace-folder . --json | jq '.disk_space'Test container lifecycle commands (with full up execution):
cd examples/container-lifecycle/basic
# First, inspect the configuration
deacon read-configuration --config devcontainer.json | jq '.onCreateCommand, .postCreateCommand, .postStartCommand, .postAttachCommand'
# Then execute with up command to see lifecycle in action
deacon up --workspace-folder . --include-configurationExplore lifecycle execution order:
cd examples/container-lifecycle/execution-order
deacon read-configuration --config devcontainer.json | jq -r '
"1. onCreate: " + (.onCreateCommand | tostring),
"2. postCreate: " + (.postCreateCommand | tostring),
"3. postStart: " + (.postStartCommand | tostring),
"4. postAttach: " + (.postAttachCommand | tostring)
'Test configuration extends chain:
cd examples/configuration/extends-chain/leaf
deacon read-configuration --config devcontainer.json --include-merged-configuration | jq '.__meta.layers'Test nested variable substitution:
cd examples/configuration/nested-variables
deacon config substitute --config devcontainer.json --dry-run | jq '.configuration.containerEnv'Test skip flags behavior:
cd examples/container-lifecycle/non-blocking-and-skip
deacon read-configuration --config devcontainer.json | jq '{
onCreate: .onCreateCommand,
postCreate: .postCreateCommand,
postStart: .postStartCommand,
postAttach: .postAttachCommand
}'Analyze progress events structure:
cd examples/container-lifecycle/progress-events
deacon read-configuration --config devcontainer.json | jq '.postCreateCommand'
# Shows named commands that will generate stable command IDsVerify redaction configuration:
cd examples/container-lifecycle/redaction
deacon read-configuration --config devcontainer.json | jq '.containerEnv'
# Shows environment variables (including sensitive ones that will be redacted)Start a multi-service compose environment:
cd examples/compose/multiservice-basic
deacon up
deacon exec sh -lc 'echo ok'Capture port events from a compose service:
cd examples/compose/port-events
deacon up --ports-events 2>&1 | grep "PORT_EVENT:"Test exec command semantics:
cd examples/exec/semantics
deacon up
deacon exec sh -lc 'pwd' # Should output /wsp
deacon exec --env FOO=BAR sh -lc 'echo $FOO' # Should output BAR
deacon downExamine lockfile structure and path derivation:
cd examples/features/lockfile-demo
cat devcontainer-lock.json | jq '.features | keys'
cat devcontainer-lock.json | jq '.features["ghcr.io/devcontainers/features/node:1"]'Verify JSON logs with standardized spans:
cd examples/observability/json-logs
export DEACON_LOG_FORMAT=json
deacon config substitute --workspace-folder . --output-format json 2>&1 \
| jq 'select(.span.name == "config.resolve")'Build examples demonstrate Dockerfile-based container builds with build arguments, platform targeting, cache control, and BuildKit features (secrets, SSH) as specified in the containers.dev spec Container Build section. Additional examples showcase Compose service targeting (compose-service-target/), image reference builds (image-reference/), multi-tag support with --image-name, registry push with --push, and OCI archive export with --output. See the containers.dev spec for complete build parity documentation.
Specific build capability example directories (under examples/build/):
basic-dockerfile/– Minimal Dockerfile buildplatform-and-cache/– Platform selection & cache controlsecrets-and-ssh/– BuildKit secrets & SSH forwardingcompose-service-target/– Targeted Docker Compose service imageimage-reference/– Extending a referenced base imagemulti-tags-and-labels/– Multiple--image-nametags & custom--labelinjectionoutput-archive/– Exporting image as OCI archive via--outputpush/– Publishing tags to a registry with--push(BuildKit required)push-output-conflict/– Demonstrates mutual exclusion of--pushand--outputdockerfile-with-features/– Feature install during Dockerfile buildimage-reference-with-features/– Feature install atop base imagecompose-with-features/– Feature install with Compose service buildcompose-unsupported-flags/– Demonstrates pre-build rejection of unsupported flagscompose-missing-service/– Error when referenced service does not existbuildkit-gated-feature/– Example of feature requiring BuildKit-only capabilityinvalid-config-name/– Validation failure for incorrect config filenameduplicate-tags/– Duplicate tag validation error scenariounwritable-output/– Failing fast on unwritable--outputdestination
Container lifecycle examples demonstrate the complete DevContainer lifecycle command execution workflow as specified in the containers.dev spec Lifecycle Execution Workflow. The up command now has full parity with the specification including: JSON output contract, all CLI flags (workspace/config/lifecycle/mount/env/cache/buildkit/dotfiles/security), validation rules, updateContentCommand execution, prebuild mode, ID labels, secrets handling with redaction, image metadata merging, feature-driven builds, compose parity (mount conversion, profiles, remote-env), UID/security options, and data folder management. See the containers.dev spec for complete implementation status (~95% specification compliance).
Doctor examples demonstrate environment diagnostics including host requirements validation (CPU, memory, storage) and real disk space checking using platform-specific APIs as specified in the containers.dev spec Host Requirements section.
Exec examples demonstrate command execution semantics including working directory, user context, TTY allocation, and environment variable handling as specified in the containers.dev spec Exec Command section.
Feature system examples demonstrate dependency resolution, parallel execution levels, digest-based caching, and lockfile support for reproducible builds as specified in the containers.dev spec Feature Installation Workflow, Distribution & Caching sections, and lockfile specifications.
Observability examples demonstrate JSON logging, standardized tracing spans, and structured fields as specified in the containers.dev spec Monitoring and Observability section.
Registry authentication examples demonstrate multiple authentication methods (environment variables, Docker config, command-line options) for push/pull operations with proper error handling and retry logic as specified in the containers.dev spec OCI Registry Integration section.