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?
The specific solution used was to utilise a common-services.yml file. This allowed me to only run the services with the specified profile without running the default services. What I did was to extract the default service to an additional yml file like so:
#common-services.yml:
services:
adapter:
image: "my-image"
profiles: []
environment:
- JAVA_OPTS="${JAVA_OPTS} -Dloader.main=com.my.class"
volumes:
- /local/path/to/logs:/logs
and the docker compose yaml will look like:
#docker-compose.yml
version: '3.9'
services:
adapter-uat:
extends:
file: common-services.yml
service: adapter
profiles:
- uat
environment:
- SPRING_PROFILES_ACTIVE=uat
depends_on:
- some_image
adapter-dev:
extends:
file: common-services.yml
service: adapter
profiles:
- dev
environment:
- SPRING_PROFILES_ACTIVE=dev
depends_on:
- some_image