Introduction
Docker Compose has two separate concepts that are easy to mix up: variable interpolation in the Compose YAML, and environment variables injected into a container at runtime. env_file is for the second case. It does not automatically perform YAML-level substitution the way the .env file and shell environment do. Many Compose configuration bugs come from assuming those mechanisms are interchangeable.
Symptoms
- The container receives literal
${VAR}strings instead of resolved values docker compose configstill shows unresolved variables- Values in
env_fileexist inside the container but are not substituted into image tags, ports, or other Compose fields - The same stack behaves differently between Compose versions or machines
Common Causes
- The wrong file type is used for the wrong purpose (
env_filevs.env) - The
.envfile has bad formatting, such as spaces around= - Variables are referenced before they exist in the interpolation context
- Users expect runtime container env injection to affect Compose YAML parsing
Step-by-Step Fix
- 1.**Use
.envor shell variables for Compose-file interpolation** - 2.Values like image tags, published ports, and top-level environment substitutions must be available during Compose config parsing.
docker compose config- 1.**Use
env_fileonly for environment passed into the container** - 2.This is useful for application configuration, not for Compose YAML interpolation.
services:
app:
env_file:
- .env
environment:
DATABASE_URL: ${DATABASE_URL}- 1.**Check
.envfile formatting** - 2.Compose parsing is sensitive to malformed env files and simple syntax mistakes.
DATABASE_URL=postgres://user:pass@db:5432/mydb
API_KEY=abc123- 1.Inspect the fully rendered configuration before blaming the app
- 2.
docker compose configshows what Compose actually resolved, which is often enough to separate interpolation problems from application-level bugs.
Prevention
- Keep
.envfor Compose interpolation andenv_filefor container runtime configuration - Validate
docker compose configbefore deploying - Avoid ambiguous variable precedence across shell,
.env, and override files - Document required variables and where each one is expected to be resolved