https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties.docker-compose calls out that we should be able to disable the docker compose support with spring.docker.compose.enabled=false however it has no affect for some reason.

Steps to Recreate: 1. set spring.docker.compose.enabled: false in application.yaml 2. set spring.docker.compose.enabled=true in application-local.properties 3. run application in some other profile like 'stage'

I've created a simple app to emulate the issue.

https://github.com/ranma2913/spring-boot_docker-compose-support_example

Dependency List:

  • org.springframework.boot:spring-boot-autoconfigure:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-configuration-processor:jar:3.2.2:compile (optional)
  • org.springframework.boot:spring-boot-devtools:jar:3.2.2:runtime (optional)
  • org.springframework.boot:spring-boot-docker-compose:jar:3.2.2:runtime (optional)
  • org.springframework.boot:spring-boot-starter-aop:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter-data-jpa:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter-jdbc:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter-json:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter-logging:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter-test:jar:3.2.2:test
  • org.springframework.boot:spring-boot-starter-tomcat:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter-web:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-starter:jar:3.2.2:compile
  • org.springframework.boot:spring-boot-test-autoconfigure:jar:3.2.2:test
  • org.springframework.boot:spring-boot-test:jar:3.2.2:test
  • org.springframework.boot:spring-boot:jar:3.2.2:compile
  • org.springframework.cloud:spring-cloud-commons:jar:4.1.0:compile
  • org.springframework.cloud:spring-cloud-context:jar:4.1.0:compile
  • org.springframework.cloud:spring-cloud-starter-bootstrap:jar:4.1.0:compile
  • org.springframework.cloud:spring-cloud-starter:jar:4.1.0:compile
  • org.springframework.data:spring-data-commons:jar:3.2.2:compile
  • org.springframework.data:spring-data-jpa:jar:3.2.2:compile
  • org.springframework.security:spring-security-crypto:jar:6.2.1:compile
  • org.springframework.security:spring-security-rsa:jar:1.1.1:compile
  • org.springframework:spring-aop:jar:6.1.3:compile
  • org.springframework:spring-aspects:jar:6.1.3:compile
  • org.springframework:spring-beans:jar:6.1.3:compile
  • org.springframework:spring-context:jar:6.1.3:compile
  • org.springframework:spring-core:jar:6.1.3:compile
  • org.springframework:spring-expression:jar:6.1.3:compile
  • org.springframework:spring-jcl:jar:6.1.3:compile
  • org.springframework:spring-jdbc:jar:6.1.3:compile
  • org.springframework:spring-orm:jar:6.1.3:compile
  • org.springframework:spring-test:jar:6.1.3:test
  • org.springframework:spring-tx:jar:6.1.3:compile
  • org.springframework:spring-web:jar:6.1.3:compile
  • org.springframework:spring-webmvc:jar:6.1.3:compile
  • org.xmlunit:xmlunit-core:jar:2.9.1:test
  • org.yaml:snakeyaml:jar:2.2:compile
  • ch.qos.logback:logback-classic:jar:1.4.14:compile
  • ch.qos.logback:logback-core:jar:1.4.14:compile
  • com.fasterxml.jackson.core:jackson-annotations:jar:2.15.3:compile
  • com.fasterxml.jackson.core:jackson-core:jar:2.15.3:compile
  • com.fasterxml.jackson.core:jackson-databind:jar:2.15.3:compile
  • com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.15.3:compile
  • com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.15.3:compile
  • com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.15.3:compile
  • com.fasterxml:classmate:jar:1.6.0:runtime
  • com.jayway.jsonpath:json-path:jar:2.8.0:test
  • com.mysql:mysql-connector-j:jar:8.3.0:runtime
  • com.sun.istack:istack-commons-runtime:jar:4.1.2:runtime
  • com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
  • com.zaxxer:HikariCP:jar:5.0.1:compile
  • io.micrometer:micrometer-commons:jar:1.12.2:compile
  • io.micrometer:micrometer-observation:jar:1.12.2:compile
  • io.smallrye:jandex:jar:3.1.2:runtime
  • jakarta.activation:jakarta.activation-api:jar:2.1.2:runtime
  • jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile
  • jakarta.inject:jakarta.inject-api:jar:2.0.1:runtime
  • jakarta.persistence:jakarta.persistence-api:jar:3.1.0:compile
  • jakarta.transaction:jakarta.transaction-api:jar:2.0.1:compile
  • jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.1:runtime
  • net.bytebuddy:byte-buddy-agent:jar:1.14.11:test
  • net.bytebuddy:byte-buddy:jar:1.14.11:runtime
  • net.minidev:accessors-smart:jar:2.5.0:test
  • net.minidev:json-smart:jar:2.5.0:test
  • org.antlr:antlr4-runtime:jar:4.13.0:compile
  • org.apache.logging.log4j:log4j-api:jar:2.21.1:compile
  • org.apache.logging.log4j:log4j-to-slf4j:jar:2.21.1:compile
  • org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.18:compile
  • org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.18:compile
  • org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.18:compile
  • org.apiguardian:apiguardian-api:jar:1.1.2:test
  • org.aspectj:aspectjweaver:jar:1.9.21:compile
  • org.assertj:assertj-core:jar:3.24.2:test
  • org.awaitility:awaitility:jar:4.2.0:test
  • org.bouncycastle:bcprov-jdk18on:jar:1.74:compile
  • org.eclipse.angus:angus-activation:jar:2.0.1:runtime
  • org.glassfish.jaxb:jaxb-core:jar:4.0.4:runtime
  • org.glassfish.jaxb:jaxb-runtime:jar:4.0.4:runtime
  • org.glassfish.jaxb:txw2:jar:4.0.4:runtime
  • org.hamcrest:hamcrest:jar:2.2:test
  • org.hibernate.common:hibernate-commons-annotations:jar:6.0.6.Final:runtime
  • org.hibernate.orm:hibernate-core:jar:6.4.1.Final:compile
  • org.jboss.logging:jboss-logging:jar:3.5.3.Final:runtime
  • org.junit.jupiter:junit-jupiter-api:jar:5.10.1:test
  • org.junit.jupiter:junit-jupiter-engine:jar:5.10.1:test
  • org.junit.jupiter:junit-jupiter-params:jar:5.10.1:test
  • org.junit.jupiter:junit-jupiter:jar:5.10.1:test
  • org.junit.platform:junit-platform-commons:jar:1.10.1:test
  • org.junit.platform:junit-platform-engine:jar:1.10.1:test
  • org.mockito:mockito-core:jar:5.7.0:test
  • org.mockito:mockito-junit-jupiter:jar:5.7.0:test
  • org.objenesis:objenesis:jar:3.3:test
  • org.opentest4j:opentest4j:jar:1.3.0:test
  • org.ow2.asm:asm:jar:9.3:test
  • org.projectlombok:lombok:jar:1.18.30:compile (optional)
  • org.skyscreamer:jsonassert:jar:1.5.1:test
  • org.slf4j:jul-to-slf4j:jar:2.0.11:compile
  • org.slf4j:slf4j-api:jar:2.0.11:compile

Comment From: ranma2913

Ok, so I was trying to reproduce the issue in my example app, and at first I wasn't able to. Turns out this is related to not respecting java properties used to start the spring-boot app from my IDE. You can see in the below screenshot I'm starting the application with -Dspring.profiles.active=stage but the active-profile isn't set. SpringBoot DockerComposeLifecycleManager.start() Called in Spring Cloud Bootstrap and in Application Context phase SpringBoot DockerComposeLifecycleManager.start() Called in Spring Cloud Bootstrap and in Application Context phase

Comment From: wilkinsona

Docker Compose profiles and Spring profiles are two separate concepts. The former is controlled by spring.docker.compose.profiles.active while the latter is controlled by spring.profiles.active. You appear to have set the latter but your screenshots are showing the classes to which the former is bound.

Comment From: ranma2913

Further Debugging shows that in my 'business' application the issue is that DockerComposeLifecycleManager.start() is called twice.

Once during the bootstrap phase (before my application property is configured) & once during the regular startup phase.

Comment From: ranma2913

Docker Compose profiles and Spring profiles are two separate concepts. The former is controlled by spring.docker.compose.profiles.active while the latter is controlled by spring.profiles.active. You appear to have set the latter but your screenshots are showing the classes to which the former is bound.

Yeah this wasn't related. The issue seems to be because of spring-cloud-config in the bootstrap phase. This application event ends up causing the docker-compose to execute a second time.

Comment From: ranma2913

@wilkinsona I don't think this should be closed yet. Until it's understood if there's a bug with the Spring-Cloud integration.

I'll keep looking.

Comment From: ranma2913

Docker Compose profiles and Spring profiles are two separate concepts. The former is controlled by spring.docker.compose.profiles.active while the latter is controlled by spring.profiles.active. You appear to have set the latter but your screenshots are showing the classes to which the former is bound.

The issue is me trying to set the spring.profiles.active is where the spring.docker.compose.enabled=false is defined so if the profile isn't activating and loading properties it won't disable the docker-compose like I am expecting.

Comment From: wilkinsona

Edit: @ranma2913, every comment triggers a notification for those watching this issue tracker. Please collect your thoughts in a single comment rather than posting several in quick succession.

The issue seems to be because of spring-cloud-config in the bootstrap phase

In that case, this could be the same problem as https://github.com/spring-projects/spring-boot/issues/35878. I cannot tell for sure as I don't know what version of Spring Cloud you're using. If the problem remains when using the latest version of Spring Cloud and doesn't occur without Spring Cloud, please open a Spring Cloud issue so that they can investigate.

Comment From: ranma2913

Sorry for the chats.

Anyway, I've confirmed the issue is with spring-cloud-starter-bootstrap. When the Spring-Cloud Bootstrap Application Context starts, DockerComposeLifecycleManager.start() is called, however since I only saw the documentation mentioning setting spring.docker.compose.enabled=false in the application.properties file, It appeared as though the properties weren't taking affect, when in-fact they hadn't been loaded into the application context yet.

I can see how this is actually the expected behavior since a user may wish to provide something like a Hashicorp Vault pod for local development, that pod being needed as part of the bootstrap phase.

I'm just wondering if we could add a warning or note to the docs mentioning something like: "If you use Spring-Cloud Bootstrap, Docker Compose Properties can be added to your bootstrap.yaml to configure the bootstrap phase."

Comment From: wilkinsona

Behavior changes due to the Bootstrap context aren't limited to Spring Boot's Docker Compose integration. For example, it'll affect anything that uses an ApplicationListener registered in spring.factories. As such, I don't think it's practical for Boot's documentation to mention this everywhere that it may be relevant. It would be better if it was documented once in Spring Cloud's documentation.