Docker ecosystem is truly amazing. This said, very few users take advantages of all its built-in and often hidden facilities. Idea there is to both increase awareness of such features while providing real world usage.
Dry config using extension
Configuration materials such as compose files or Kubernetes manifests are inherently verbose. Networking setup is something that we encounter in every compose file. Ideally, we want to allocate a dedicated network four our services to operate on, as well as providing bridge for the OS
-based executables to interact with. It translates into following bits, that have to be cloned for every single service part of the deployment. It is painful to write, painful to read and painful to maintain.
|
|
One way of DRYing this part is to leverage extension mechanism:
- Declare common settings through an
extension
, herex-app
- Mark it with an
anchor
, heredefault-glue
- Inject settings into through
alias
, here<<: *default-glue
|
|
Below the diff view to better assess changes. Of course, the more you have services the better shines the pattern.
|
|
Compose multiple docker compose files
Assume you have an instrumented stack you would like to be able to deploy in 2 flavors:
- Deploy the stack only, with
OTEL
flag switched off (default value) - Deploy the stack, with
OTEL
flag switched on, along with theOTEL
ecosystem
There are multiple ways of doing that, such as profiles or compose merge.
Profile-based solution works great but tends to noise the original compose file, making difficult to easily assess what is deployed and what isn’t.
On the other hand, merge-based solution allows for better separation of concern, in a way Open/Closed Principle is applied to code.
Default compose.yaml
focuses on deploying the bare-metal stack the way we are used to
|
|
Deploying stack through docker CLI
|
|
As we have previously instrumented our code base, enabling user to switch on or off this facility through command line flag, --otel
, we can draft another compose file to gather this configuration. We start by complementing our stack declared in the core compose file using matching service alias. Here, we activate the flag and provide expected OTEL
environment variables. Then, we allocate new OTEL
services.
|
|
Deploying stack through docker CLI by chaining compose files.
|
|
Of course, we can use this pattern for other uses cases such as:
- Provide compose overrides for dev, staging and production environment
- Provide compose overrides per customer
Remember the smarter your original stack is articulated and instrumented upstream, the easier it will be to compose and accommodate new use cases downstream without having to modify the base materials.