Hardcoding passwords, API keys, and configuration directly into docker-compose.yml is a common mistake — especially if the file ends up in version control. This guide covers using .env files and environment variables the right way.
The Problem
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: hardcoded-password-123
This exposes secrets to anyone with access to the file, including in Git history.
Step 1 — Create a .env File
In the same directory as your docker-compose.yml:
nano .env
DB_ROOT_PASSWORD=change_me_strong_password
DB_NAME=myapp
DB_USER=appuser
DB_PASSWORD=change_me_another_strong_password
Step 2 — Reference Variables in docker-compose.yml
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
Docker Compose automatically loads a .env file from the same directory — no extra flag required.
Step 3 — Exclude .env from Version Control
echo ".env" >> .gitignore
Commit a .env.example file instead, listing variable names without real values, so collaborators know what's required.
Providing Default Values
environment:
APP_PORT: ${APP_PORT:-3000}
If APP_PORT isn't set in .env, this defaults to 3000.
Using Variables in Other Parts of the Compose File
services:
web:
image: myapp
ports:
- "${APP_PORT}:3000"
Verifying Which Values Will Actually Be Used
docker compose config
This prints the fully resolved configuration — useful for confirming variables were substituted correctly before deploying.
Passing Environment Variables from the Shell Instead
DB_PASSWORD=temporary_value docker compose up -d
Loading a Different Env File
docker compose --env-file production.env up -d
Common Errors
Variable not being substituted (shows literally as ${VAR}) — confirm .env is in the same directory you're running docker compose from, and there's no typo in the variable name.
Values with special characters break parsing — wrap values containing spaces or special characters in quotes inside .env.
Best Practices
- Never commit real
.envfiles to version control - Use strong, unique values for every password/secret, never shared defaults
- Provide a
.env.exampletemplate for team members or future deployments - Verify resolved config with
docker compose configbefore deploying to production
FAQ
Can I use different .env files for staging and production?
Yes — use the --env-file flag to point to environment-specific files, e.g. staging.env and production.env.
Related Articles
- How to Install Docker Compose on Ubuntu & Debian
- Docker Compose Troubleshooting: Common Errors & Fixes
- Docker Security Best Practices
