In this lesson, you will learn how to decouple your application’s settings from its code by injecting configuration dynamically through environment variables.
When building containerized applications, hardcoding database URLs, API keys, or feature flags directly into your source code is a major security and architectural anti-pattern. If you change a configuration value, you would have to rebuild the entire container image, which is slow and breaks the principle of immutability. Instead, we treat the code as a constant and the configuration as a dynamic input.
Inline Environment Variables
The simplest way to inject configuration is by defining them directly in your docker-compose.yml file using the environment key.
services:
web-app:
image: my-app:latest
environment:
- DATABASE_URL=postgres://db.example.com:5432/prod
- DEBUG_MODE=false
Using env_file for Scalability
As your project grows, managing dozens of variables inline becomes messy. Docker allows you to offload these configurations into a separate text file. Create a file named .env:
DATABASE_URL=postgres://db.example.com:5432/prod
DEBUG_MODE=false
Then, reference this file in your docker-compose.yml:
services:
web-app:
image: my-app:latest
env_file:
- .env
Why this matters
By using env_file or inline definitions, your application remains portable. The same container image can be deployed to a "Development," "Staging," or "Production" environment simply by pointing it to different environment variables. This approach keeps your image generic, ensures that sensitive configuration isn't baked into the image layers, and allows you to update your settings without needing to trigger a new build process.
Key Takeaway: Never hardcode configuration in your image; use environment or env_file to inject settings at runtime, keeping your application logic separate from its deployment environment.