Docker Compose Environment Variables: Best Practices Guide
Master environment variables in Docker Compose. Learn .env files, variable substitution, secrets management, and best practices for self-hosted deployments.
Posted by
Related reading
Private Cloud vs Public Cloud: When to Self-Host and When Not To
Understand when self-hosting makes sense and when public cloud is better. A practical guide to choosing between private cloud homelab and AWS/GCP/Azure services.
Homelab Documentation: Wiki.js vs BookStack for Self-Hosted Wikis
Document your homelab setup with self-hosted wikis. Compare Wiki.js and BookStack for creating searchable documentation of your infrastructure and procedures.
Docker Security Scanning: Trivy and Dockle for Safe Containers
Scan your Docker images for vulnerabilities before deploying. Learn to use Trivy and Dockle to secure your self-hosted homelab container infrastructure.

Why Environment Variables Matter
Environment variables let you configure containers without hardcoding values. This is essential for security, portability, and maintaining different environments (dev/staging/production).
The .env File
# .env file in same directory as docker-compose.yml
POSTGRES_PASSWORD=super_secret_password
DOMAIN=homelab.local
TIMEZONE=America/New_York
PUID=1000
PGID=1000
# docker-compose.yml
services:
db:
image: postgres:15
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- TZ=${TIMEZONE}Variable Substitution Methods
# Method 1: Direct substitution
environment:
- DB_HOST=${DB_HOST}
# Method 2: With default value
environment:
- DB_HOST=${DB_HOST:-localhost}
# Method 3: Required (fails if not set)
environment:
- DB_HOST=${DB_HOST:?Database host is required}
# Method 4: env_file directive
env_file:
- .env
- .env.localBest Practices
- Never commit .env files to version control
- Use .env.example as a template
- Set restrictive permissions: chmod 600 .env
- Use different .env files per environment
- Validate required variables at startup
Debugging Variables
# Show resolved compose file docker compose config # Check specific variable docker compose config | grep POSTGRES # Verify environment inside container docker exec container_name env | grep DB_
