Desk Clarity

A field guide to everyday digital problems.

Developer tools / Practical guide

Compose Expands the Wrong Variable: Separate Configuration and Container Expansion

A service env_file supplies container variables; it does not automatically supply every ${NAME} in the Compose model.

By ON Lab2 min readSources checked November 10, 2026 (KST)

A service env_file supplies container variables; it does not automatically supply every ${NAME} in the Compose model. First decide whether the value must be resolved by Compose on the host or by a shell inside the container.

Inspect the boundary before changing the service

The commands below use placeholder names. They illustrate a diagnostic workflow and were not run against a live container in this review. Match the Docker context and project before inspecting your own service.

# compose.yaml: illustrative configuration, not a deployment command
services:
  probe:
    image: alpine:3.21
    environment:
      APP_LABEL: container-value
    command: ["sh", "-c", "printf '%s\n' "$$APP_LABEL""]
# Inspect the resolved configuration locally:
docker compose -f compose.yaml config

What to compare

There are two expansion boundaries. A single dollar expression belongs to Compose interpolation. The doubled dollar preserves a dollar for the next layer. The explicit sh -c in this example supplies that next layer; a program launched directly does not gain shell expansion just because its argument contains a dollar sign. Quoting YAML alone does not establish which process expands a variable.

Choose the next action

For a value chosen at configuration time, provide it through the invoking shell or the appropriate Compose interpolation input and inspect docker compose config. For a value already present in the container environment, preserve the dollar through Compose and deliberately invoke a shell only when the command requires one. Inspect the rendered command and environment separately. Use a harmless label first; resolved configurations may include secret values, so keep their output private.

Limits and verification

This is Compose syntax, not Dockerfile ARG expansion or application dotenv loading. Environment precedence depends on how values are supplied. Do not add more dollar signs until the rendered configuration shows which layer consumed the original expression. No image was downloaded and this container was not started during this review.

Related: Bash Prefix Assignment Changes the Child Environment, Not Earlier Argument Expansion.

Official Docker documentation checked November 10, 2026 (KST). Docker Compose 2.35.1 configuration parsing was available, but the Docker daemon was not running. These pages do not claim a live container connectivity, storage, health or recovery test.

Sources & further reading