Dev Containers split environment variables into two scopes: containerEnv reaches the whole container, while remoteEnv reaches VS Code and the processes it starts. That distinction explains why a value can appear in an integrated terminal but be absent from a service started by the container itself. With Docker Compose, put container-wide values in the service configuration; only remoteEnv belongs in devcontainer.json for that setup.
Choose the scope before the syntax
containerEnv: image or Dockerfile containers and every process inside them.remoteEnv: VS Code terminals, tasks, debuggers, and extensions.environmentorenv_file: container-wide values for a Docker Compose service.
A minimal image-based example
{
"name": "env-scope-demo",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"containerEnv": {
"APP_MODE": "development",
"HOST_LABEL": "${localEnv:USER}"
},
"remoteEnv": {
"EDITOR_MODE": "${containerEnv:APP_MODE}-vscode"
}
}printf '%s
' "$APP_MODE" "$EDITOR_MODE"development
development-vscode${localEnv:NAME} is resolved by the host running VS Code. Missing host values resolve empty, so validate the result instead of assuming a shell profile was inherited. After changes, run Dev Containers: Rebuild Container; opening another terminal is insufficient.
Docker Compose needs two layers
FEATURE_MODE=safeservices:
app:
image: node:24
command: sleep infinity
volumes:
- ..:/workspace
environment:
APP_MODE: development
env_file:
- devcontainer.env{
"dockerComposeFile": "compose.yaml",
"service": "app",
"workspaceFolder": "/workspace",
"remoteEnv": { "EDITOR_APP_MODE": "${containerEnv:APP_MODE}" }
}Compose's .env primarily feeds YAML interpolation; it does not inject values unless the service uses environment or env_file. See the Docker Compose env guide for that separate precedence chain.
Limitations
remoteEnvdoes not configure daemons outside VS Code's process tree.- Host interpolation can expose credentials to the container. Pass only deliberately named values.
- For many values, use an ignored env file rather than a large JSON object.
Check files with the env validator. For the broader lifecycle, see the Dev Containers guide.
Version scope and primary references
These rules reflect the Dev Container specification and VS Code documentation reviewed September 14, 2026. Other editors may implement only part of the specification.