Devcontainer overlays
Use --devcontainer-overlay to layer a second devcontainer.json over the config selected for a workspace:
devsy workspace up <workspace> --devcontainer-overlay ./devcontainer/overlay.jsonThe overlay participates in build planning before substitution and image creation. Supported build selectors are image, dockerFile, context, build, dockerComposeFile, service, and runServices. initializeCommand, features, and overrideFeatureInstallOrder also participate before the build. The primary config remains the effective origin; paths to assets declared in the overlay and local features are resolved relative to the file that declares them.
Replacement and clearing
Fields absent from an overlay leave the primary value in place when both configs select the same build type. Selecting a different build type (image, Dockerfile, or Compose) clears incompatible fields from the previous type before applying the new selector. For example, an overlay that selects Compose can replace a primary image config without retaining its image selector.
Within build, overlay args merge by key, so matching overlay keys replace primary keys and other primary arguments remain. target, cacheFrom, and options replace their primary values when supplied. The legacy top-level dockerFile and context fields normalize to build.dockerfile and build.context; setting both forms to different paths is an error. Structural selectors that must be present cannot be null or empty: Devsy reports an error instead of guessing. Explicit null is also an error for initializeCommand. Use an empty initializeCommand ("", [], or {}) to disable the primary command, and use "runServices": [] to clear the primary list.
dockerComposeFile accepts a path string or a list of paths. A supplied string or list replaces the primary Compose file selection as a whole; service replaces the selected service, and runServices replaces the sidecar list. Paths in these fields are substituted before resolution. Relative paths are resolved from the file that declares them, including files inherited through extends, then represented relative to the primary config origin; absolute paths remain absolute. Paths inside Compose YAML, such as build contexts and bind mounts, continue to follow Docker Compose's own project-directory rules. The feature lockfile remains beside the primary devcontainer config. Structural overlays cannot attach to or replace a containerID config.
A missing or malformed overlay is an error. Devsy resolves it before replacing an existing workspace, so a failed change leaves the current workspace available. Use --recreate to apply a structural change to an existing workspace:
devsy workspace up <workspace> --recreate --devcontainer-overlay ./devcontainer/overlay.jsonAfter a successful creation, workspace cleanup uses the recorded workspace invocation. It can still delete the workspace if the overlay file is later removed or malformed.
The overlay's initializeCommand replaces the primary command when present. It runs on the host with the workspace root as its working directory, before the image build. A string runs through the shell; an argument array runs directly as one command; a named-object form runs its commands in parallel. Files it creates can be used by the build when they are inside the selected build context.
Feature and runtime behavior
Overlay features and overrideFeatureInstallOrder participate in image planning before feature installation. The precedence is primary config, then overlay, then CLI --features. Local feature paths in the overlay are relative to the overlay file.
Runtime metadata continues to layer onto the resolved config using Devsy's existing overlay behavior. For example, overlay remoteEnv values combine with primary values, with overlay values taking precedence for matching keys. This support list describes the fields consumed during build planning; it does not enable arbitrary structural config replacement.