I am writing my docker-compose.yml file and to avoid writing redundant lines especially for using different profiles for dev, uat, prod etc, I was using yaml anchors. Here is a sample for one of the adapters I used for uat and for dev.
Adapter:&Adapter
image:"my-image"
profiles:
- uat
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
- SPRING_PROFILES_ACTIVE=uat
volumes:
- /local/path/to/logs:/logs
depends_on:
- some_image
Adapter-dev:
<<: *Adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
.env file contains:
JAVA_OPTS=-Xmx3g -Xms3g
The key part is that the JAVA_OPTS is a must have in order to run properly. The JAVA_OPTS is stored in a .env file, and I append to the JAVA_OPTS variable to specify my main class. I just found out that doing it in the way above, it overwrites the environment entirely and only passes the SPRING_PROFILES_ACTIVE to my docker container’s environment variables. What I expected would be that only SPRING_PROFILES_ACTIVE would be overwritten, but the JAVA_OPTS would be preserved. How can I only overwrite the SPRING_PROFILES_ACTIVE in my docker-compose.yml without overwriting the JAVA_OPTS?
2
Answers
This might be a case where I’d use Compose’s support for multiple Compose files, which are able to combine per-service settings. Compose profiles are better for selecting which service to run, but not necessarily for controlling how to run it.
You’d have a base
docker-compose.yml
file that listed all of the settings that were required in every environmentThen you’d have a file per environment that added settings for only that environment
When you go to run
docker-compose
commands, you can then specify both files usingdocker-compose -f
options. Note that you need to specify both files on everydocker-compose
invocation; setting a$COMPOSE_FILE
environment variable may be a little easier.There are two versions of the Compose tooling, an older one that runs as a standalone tool and a newer one packaged as a
docker
CLI extension. This setup will work with both of them.In Compose you can set up one service to extend another. This does essentially what you’re showing with YAML anchors, but it also lets you provide additional settings.
depends_on:
is documented to not be reused inextends:
services, so I’ve copied it into each per-environment service here.There are two versions of the Compose tool. If you are using the older version of the tool (
docker-compose --version
says it’s version 1) then be aware that the Compose file format version 3 doesn’t includeextends:
; you need to declare aversion: 2.x
at the start of the file and you will be unable to use some Swarm-related features in version 3 of the file format.