Environment Variables in Containers: Configuration Best Practices
Environment variables are the standard way to configure containerized apps. Here's how to use them properly and securely.
The Twelve-Factor App
The Twelve-Factor App methodology (12factor.net) established that configuration should be stored in environment variables, not in code. This principle drives modern container configuration.
Why Environment Variables?
Common Environment Variables
Database Connection
DATABASE_URL=postgres://user:password@db:5432/myapp
Application Settings
NODE_ENV=production
PORT=3000
LOG_LEVEL=info
Third-Party Services
STRIPE_SECRET_KEY=sk_live_...
SMTP_HOST=smtp.mailgun.org
S3_BUCKET=my-uploads
Feature Flags
ENABLE_SIGNUPS=true
MAINTENANCE_MODE=false
Methods for Passing Env Vars
Command Line
docker run -e DATABASE_URL=postgres://... myapp
Good for: Quick testing, one-off variables.
.env File
Create a .env file:
DATABASE_URL=postgres://user:pass@db:5432/myapp
JWT_SECRET=supersecretkey
SMTP_PASSWORD=mailpassword
Reference in docker-compose:
env_file:
Good for: Development, simple deployments.
Docker Compose Environment
environment:
NODE_ENV: production
PORT: "3000"
Good for: Non-sensitive configuration that's the same across environments.
Security
Never Commit .env Files
Add .env to .gitignore immediately. Committed secrets are the #1 source of credential leaks.
Never Put Secrets in Dockerfiles
ENV SECRET=mysecret bakes the secret into the image. Anyone who pulls the image can see it.
Restrict File Permissions
chmod 600 .env — only the owner can read.
Use Secret Managers for Production
For sensitive production deployments, use Docker secrets, Vault, or your platform's secret management.
Debugging
View env vars in a running container:
docker exec mycontainer env
Check if a variable is set:
docker exec mycontainer printenv DATABASE_URL
On TinyPod
TinyPod stores environment variables encrypted in the dashboard. They're injected at container start time and never appear in logs or image definitions.