Repository: spring-projects/spring-boot (2026-04-18T10:31:49Z)

Issue:
Add support for docker.elastic.co/elasticsearch/elasticsearch
We only support elasticsearch from Docker Hub (`library/elasticsearch`), but we should also support `docker.elastic.co/elasticsearch/elasticsearch`.


Discussion:
Hi, I'd like to work on this.

My understanding is that the gap is in image-name matching rather than the typed ElasticsearchContainer support, likely in the Docker Compose connection details factory. I’m planning to add support for docker.elastic.co/elasticsearch/elasticsearch and cover it with an integration test.
Thanks for the offer, @carlosSepher, but we already have a PR for this issue: #50119.
Superseded by https://github.com/spring-projects/spring-boot/pull/50119.



Patch:
diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc
index 6a031505e173..f18d9d9f9dec 100644
--- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc
+++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/features/dev-services.adoc
@@ -93,7 +93,7 @@ The following service connections are currently supported:
 | Containers named "cassandra"
 
 | javadoc:org.springframework.boot.elasticsearch.autoconfigure.ElasticsearchConnectionDetails[]
-| Containers named "elasticsearch"
+| Containers named "elasticsearch" or "elasticsearch/elasticsearch"
 
 | javadoc:org.springframework.boot.hazelcast.autoconfigure.HazelcastConnectionDetails[]
 | Containers named "hazelcast/hazelcast".
diff --git a/module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java b/module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java
index 428719d2d5ba..19bd3be5fc32 100644
--- a/module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java
+++ b/module/spring-boot-elasticsearch/src/main/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactory.java
@@ -42,7 +42,7 @@ class ElasticsearchDockerComposeConnectionDetailsFactory
 	private static final int ELASTICSEARCH_PORT = 9200;
 
 	protected ElasticsearchDockerComposeConnectionDetailsFactory() {
-		super("elasticsearch");
+		super(new String[] { "elasticsearch", "elasticsearch/elasticsearch" });
 	}
 
 	@Override


Test patch:
diff --git a/core/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/ConnectionNamePredicateTests.java b/core/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/ConnectionNamePredicateTests.java
index a506e48f7958..7450bb47f828 100644
--- a/core/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/ConnectionNamePredicateTests.java
+++ b/core/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/ConnectionNamePredicateTests.java
@@ -39,16 +39,17 @@ class ConnectionNamePredicateTests {
 
 	@Test
 	void official() {
-		assertThat(predicateOf("elasticsearch")).accepts(sourceOf("elasticsearch"));
-		assertThat(predicateOf("elasticsearch")).accepts(sourceOf("library/elasticsearch"));
-		assertThat(predicateOf("elasticsearch")).accepts(sourceOf("docker.io/library/elasticsearch"));
-		assertThat(predicateOf("elasticsearch")).accepts(sourceOf("docker.io/elasticsearch"));
-		assertThat(predicateOf("elasticsearch")).accepts(sourceOf("docker.io/elasticsearch:latest"));
-		assertThat(predicateOf("elasticsearch")).rejects(sourceOf("redis"));
-		assertThat(predicateOf("elasticsearch")).rejects(sourceOf("library/redis"));
-		assertThat(predicateOf("elasticsearch")).rejects(sourceOf("docker.io/library/redis"));
-		assertThat(predicateOf("elasticsearch")).rejects(sourceOf("docker.io/redis"));
-		assertThat(predicateOf("elasticsearch")).rejects(sourceOf("docker.io/redis"));
+		assertThat(predicateOf("elasticsearch", "elasticsearch/elasticsearch")).accepts(sourceOf("elasticsearch"))
+			.accepts(sourceOf("library/elasticsearch"))
+			.accepts(sourceOf("docker.io/library/elasticsearch"))
+			.accepts(sourceOf("docker.io/elasticsearch"))
+			.accepts(sourceOf("docker.io/elasticsearch:latest"))
+			.accepts(sourceOf("docker.elastic.co/elasticsearch/elasticsearch:latest"))
+			.accepts(sourceOf("docker.elastic.co/elasticsearch/elasticsearch"))
+			.rejects(sourceOf("redis"))
+			.rejects(sourceOf("library/redis"))
+			.rejects(sourceOf("docker.io/library/redis"))
+			.rejects(sourceOf("docker.io/redis"));
 		assertThat(predicateOf("zipkin")).rejects(sourceOf("openzipkin/zipkin"));
 	}
 
diff --git a/module/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java b/module/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java
index 7fca9023e96c..e80614050240 100644
--- a/module/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java
+++ b/module/spring-boot-elasticsearch/src/dockerTest/java/org/springframework/boot/elasticsearch/docker/compose/ElasticsearchDockerComposeConnectionDetailsFactoryIntegrationTests.java
@@ -49,6 +49,15 @@ void runWithSslCreatesConnectionDetails(ElasticsearchConnectionDetails connectio
 		assertThat(sslBundle).isNotNull();
 	}
 
+	@DockerComposeTest(composeFile = "elasticsearch-ssl-compose.yaml",
+			image = TestImage.ELASTICSEARCH_ELASTIC_REGISTRY_9,
+			additionalResources = { "ca.crt", "server.crt", "server.key", "client.crt", "client.key" })
+	void runWithSslCreatesConnectionDetailsForElasticRegistryImage(ElasticsearchConnectionDetails connectionDetails) {
+		assertConnectionDetails(connectionDetails, Protocol.HTTPS);
+		SslBundle sslBundle = connectionDetails.getSslBundle();
+		assertThat(sslBundle).isNotNull();
+	}
+
 	private void assertConnectionDetails(ElasticsearchConnectionDetails connectionDetails, Protocol expectedProtocol) {
 		assertThat(connectionDetails.getUsername()).isEqualTo("elastic");
 		assertThat(connectionDetails.getPassword()).isEqualTo("secret");
diff --git a/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java b/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java
index 6d7d83ed93ff..6fc763b3e744 100644
--- a/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java
+++ b/test-support/spring-boot-docker-test-support/src/main/java/org/springframework/boot/testsupport/container/TestImage.java
@@ -126,6 +126,11 @@ public enum TestImage {
 	 */
 	ELASTICSEARCH_9("elasticsearch", "9.0.2"),
 
+	/**
+	 * A container image from Elastic Registry suitable for testing Elasticsearch 9.
+	 */
+	ELASTICSEARCH_ELASTIC_REGISTRY_9("docker.elastic.co/elasticsearch/elasticsearch", "9.0.2"),
+
 	/**
 	 * A container image suitable for testing Grafana OTel LGTM.
 	 */