Docker Compose .env Changes Need Container Recreation

Editing .env on a running container does nothing — Compose reads it once at start. And $ in a secret gets interpolated away, silently truncating tokens.

Two Docker Compose traps cost me real time, and both hide behind “I edited the config, why didn’t it work?”

Trap 1: .env is read once, at container start

Docker Compose’s env_file (and environment: interpolation) is resolved once, when the container is created. Editing .env on a running container does nothing — the process keeps the old values in its environment.

The fix is recreation, not restart: docker compose up -d --force-recreate. A plain docker compose restart re-runs the same container with the same stale environment.

Trap 2: $ in a secret gets interpolated away

Compose treats $ in a value as a variable reference. If a secret contains a literal dollar sign — say, a WordPress application token with $L in it — Compose replaces $L with an empty string. The container ends up with a shorter, invalid token and emits a warning like The "L" variable is not set that’s easy to miss in the compose output.

In my case a WordPress token silently lost its $L and every publish 401’d for a week. The escape is $$: Compose collapses $$ back to a literal $ when it passes the value through.

The lesson

Two rules cover most of it: after editing .env, always --force-recreate; and before you store a secret in a Compose env file, check it for $ and escape it as $$. When a token mysteriously fails auth, compare its length inside the container against the file on disk — a shortfall is the interpolation eating characters, not a wrong key.

Related

Filed under: Home Lab, Docker, Home Lab, Self-Hosting