14.1.2.5 Production External Config
A focused guide to Production External Config, connecting core concepts with practical Docker and container operations.
Production external config keeps an application's environment-specific settings — database connection strings, feature flags, API endpoints — outside the container image itself, supplied instead at runtime, ensuring the same image can be deployed across different environments without needing a separate build for each.
Why Configuration Shouldn't Be Baked Into the Image
An image with configuration values hardcoded directly into it would need a separate build for every environment, undermining the immutable image promotion principle of building once and deploying that same artifact everywhere.
ENV DATABASE_URL=postgres://prod-db:5432/myapp
services:
app:
image: registry.example.com/myapp:1.0
environment:
- DATABASE_URL=${DATABASE_URL}
The second approach supplies configuration at runtime, allowing the exact same image to run correctly across development, staging, and production simply by varying what's supplied externally.
Supplying Configuration Through Environment Variables
Environment variables are a common, straightforward mechanism for supplying this kind of external configuration.
docker run -e DATABASE_URL=postgres://prod-db:5432/myapp myapp:1.0
Using a Secrets Management System for Sensitive Configuration
Sensitive configuration values — credentials, API keys — should come from a dedicated secrets management system rather than plain environment variables, where appropriate.
services:
app:
secrets:
- db_password
secrets:
db_password:
external: true
Validating Required Configuration Is Actually Present at Startup
An application should fail fast and clearly if a required piece of external configuration is missing, rather than failing later with a confusing, unrelated error.
if (!process.env.DATABASE_URL) {
throw new Error('DATABASE_URL environment variable is required');
}
Why Production External Config Matters
Keeping environment-specific configuration outside the image itself is essential for genuinely supporting the build-once, promote-everywhere principle, allowing one validated image to correctly run across every environment without divergence.