Docker
Docker Compose
environment variables
devops
containerization

Docker Compose Change env variables

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Changing environment variables in Docker Compose is easy, but it often fails in subtle ways because multiple sources can override one another. Most confusion comes from mixing variable substitution and container runtime environment settings. A reliable workflow starts by understanding precedence, then validating the final resolved configuration before deployment.

Understand Variable Sources in Compose

Compose projects usually involve four sources of values:

  • Shell environment used to run the Compose command.
  • .env file loaded by Compose for substitution.
  • env_file entries attached to a service.
  • Inline environment entries in a service definition.

These sources are not equivalent. .env mainly feeds Compose file substitution, while environment and env_file define what the container process receives.

Example configuration:

yaml
1services:
2  api:
3    image: my-api:latest
4    env_file:
5      - ./config/base.env
6    environment:
7      APP_ENV: development
8      LOG_LEVEL: info

Here, APP_ENV from inline environment overrides the same key if it is also present in base.env.

Safe Workflow for Environment Changes

A production-safe sequence is:

  1. Preview resolved Compose config.
  2. Apply targeted override.
  3. Recreate affected services.
  4. Verify values inside running container.
bash
1# Show resolved configuration
2docker compose config
3
4# Temporary command-scoped override
5APP_ENV=staging LOG_LEVEL=debug docker compose up -d api
6
7# Recreate a service after env changes
8docker compose up -d --force-recreate api
9
10# Verify effective values
11docker compose exec api sh -lc 'echo "$APP_ENV $LOG_LEVEL"'

This sequence prevents stale values and makes changes auditable.

Use Environment Files Strategically

A practical file strategy:

  • Keep shared non-secret defaults in base.env.
  • Keep environment-specific values in separate files such as staging.env.
  • Keep secrets out of Git and inject them through CI or secret managers.

Example with explicit file selection in command line:

bash
docker compose --env-file ./config/staging.env config

For teams, document which file is authoritative for each environment so developers do not combine files inconsistently.

Substitution vs Runtime Variables

Do not confuse these two patterns:

  • Compose substitution: image: my-api:${TAG}
  • Runtime environment: environment: APP_ENV=staging

If TAG is missing during substitution, Compose may fail before containers start. Runtime variables, by contrast, affect process behavior after startup.

Example substitution:

yaml
services:
  api:
    image: registry.example.com/my-api:${TAG:-latest}

The default expression prevents startup failures when TAG is not set.

CI and Deployment Practices

In CI pipelines, avoid hidden local assumptions. Inject environment values explicitly in the job configuration and archive docker compose config output as a trace artifact. That artifact is useful during incident analysis because it shows the exact resolved settings that were deployed.

If you deploy with multiple Compose files, pin the exact file order in scripts:

bash
docker compose -f compose.yaml -f compose.prod.yaml config

File order matters because later files override earlier definitions.

Troubleshooting Checklist

When a variable change appears ignored:

  • Confirm the service was recreated.
  • Run docker compose config and inspect the resolved key.
  • Check whether the key was overridden by inline environment.
  • Confirm the right Compose files and env files were used.
  • Inspect container environment directly with docker compose exec.

This checklist resolves most issues without deep debugging.

Common Pitfalls

  • Assuming .env values always win against inline environment.
  • Editing env files but not recreating already running containers.
  • Mixing substitution variables and runtime variables without documentation.
  • Committing secrets in .env files to version control.
  • Using ad hoc CLI overrides in production without recording them.

Summary

  • Learn the difference between substitution and runtime environment values.
  • Use docker compose config before applying changes.
  • Recreate services when environment values change.
  • Keep shared defaults and secrets in separate sources.
  • Make CI and deployment overrides explicit and traceable.

Course illustration
Course illustration

All Rights Reserved.