How do you pass environment variables and secrets into services in Docker Compose?
Use environment: for inline values, env_file: to load a file, and ${VAR} substitution from the shell or a .env file. Keep real secrets out of Git and prefer Compose secrets or an external secret store.
Explain it simply
Think of three ways to give a new employee his login details: say them aloud (inline), hand over a sealed envelope (env_file), or fill in blanks on a form when he joins (substitution).
environment: lists key-value pairs directly in the YAML. env_file: .env.api loads many at once into the container. Separately, Compose reads a file named .env next to the compose file to substitute ${DB_PASSWORD} inside the YAML itself; that is not the same as passing it to the container. Shell variables override .env values. Always add the env files to .gitignore.
For sensitive data, Compose secrets: mounts a file under /run/secrets/, which the app reads, rather than exposing the value in docker inspect.
Example
services:
api:
image: myapi
env_file: .env.api
environment:
DB_HOST: db
DB_PASSWORD: ${DB_PASSWORD} # substituted from .env or shell
secrets:
- jwt_key
secrets:
jwt_key:
file: ./jwt_key.txtWhat to say in the interview
"I use environment for simple values, env_file for groups, and ${VAR} substitution from a .env file. Secrets stay out of Git, and for sensitive values I use Compose secrets mounted as files."
Common mistakes
- Committing .env with real passwords.
- Thinking the compose-level .env is automatically passed into containers.