This is an automated email from the ASF dual-hosted git repository.

Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 6843dcad5ac4 CAMEL-24087: camel-test-infra - Add UI support to camel 
infra run (#24739)
6843dcad5ac4 is described below

commit 6843dcad5ac47084290926e2749eaa649ba1cd55
Author: Federico Mariani <[email protected]>
AuthorDate: Thu Jul 16 15:04:55 2026 +0200

    CAMEL-24087: camel-test-infra - Add UI support to camel infra run (#24739)
    
    * CAMEL-24087: camel-test-infra - Add UI support to camel infra run
    
    * CAMEL-24087: Address review feedback - fix blockers and design issues
---
 .../apache/camel/catalog/test-infra/metadata.json  | 218 ++++++++++++++-------
 .../apache/camel/spi/annotations/InfraService.java |   9 +
 .../jbang-commands/camel-jbang-infra-run.adoc      |   1 +
 .../META-INF/camel-jbang-commands-metadata.json    |   2 +-
 .../core/commands/infra/InfraBaseCommand.java      |  30 ++-
 .../dsl/jbang/core/commands/infra/InfraRun.java    |  13 +-
 .../camel/dsl/jbang/core/model/InfraBaseDTO.java   |  14 +-
 .../dsl/jbang/core/commands/infra/InfraTest.java   |   4 +-
 .../src/generated/resources/META-INF/metadata.json | 218 ++++++++++++++-------
 .../arangodb/services/ArangoDBInfraService.java    |   4 +
 .../ArangoDBLocalContainerInfraService.java        |   3 +-
 .../artemis/services/ArtemisAllInfraService.java   |   8 +-
 .../artemis/services/ArtemisInfraService.java      |   4 +
 .../common/services/ContainerEnvironmentUtil.java  |  18 ++
 .../infra/consul/services/ConsulInfraService.java  |   4 +
 .../services/ConsulLocalContainerInfraService.java |   3 +-
 .../couchbase/services/CouchbaseInfraService.java  |   4 +
 .../CouchbaseLocalContainerInfraService.java       |   3 +-
 .../couchdb/services/CouchDbInfraService.java      |   4 +
 .../CouchDbLocalContainerInfraService.java         |   3 +-
 .../vault/services/HashicorpVaultInfraService.java |   4 +
 .../HashicorpVaultLocalContainerInfraService.java  |   3 +-
 .../infra/ibmmq/services/IbmMQInfraService.java    |   4 +
 .../services/IbmMQLocalContainerInfraService.java  |   8 +-
 .../services/InfinispanInfraService.java           |   4 +
 .../InfinispanLocalContainerInfraService.java      |   3 +-
 .../infra/jaeger/services/JaegerInfraService.java  |   4 +
 .../services/JaegerLocalContainerInfraService.java |   3 +-
 .../services/ContainerLocalKafkaInfraService.java  |  59 +++++-
 .../infra/kafka/services/KafkaInfraService.java    |   3 +
 .../test/infra/kafka/services/container.properties |   1 +
 .../keycloak/services/KeycloakInfraService.java    |   4 +
 .../KeycloakLocalContainerInfraService.java        |   3 +-
 .../infra/minio/services/MinioInfraService.java    |   4 +
 .../services/MinioLocalContainerInfraService.java  |   3 +-
 .../mongodb/services/MongoDBInfraService.java      |   4 +
 .../MongoDBLocalContainerInfraService.java         |  40 +++-
 .../infra/mongodb/services/container.properties    |   1 +
 .../infra/neo4j/services/Neo4jInfraService.java    |   4 +
 .../services/Neo4jLocalContainerInfraService.java  |   8 +-
 .../services/OpenSearchInfraService.java           |   4 +
 .../OpenSearchLocalContainerInfraService.java      |  49 +++++
 .../infra/opensearch/services/container.properties |   1 +
 .../postgres/services/PostgresInfraService.java    |   4 +
 .../PostgresLocalContainerInfraService.java        |  65 +++++-
 .../PostgresVectorLocalContainerInfraService.java  |   2 +-
 .../infra/postgres/services/container.properties   |   1 +
 .../infra/qdrant/services/QdrantInfraService.java  |   4 +
 .../services/QdrantLocalContainerInfraService.java |   3 +-
 .../rabbitmq/services/RabbitMQInfraService.java    |   4 +
 .../RabbitMQLocalContainerInfraService.java        |   3 +-
 .../infra/redis/services/RedisInfraService.java    |   4 +
 .../services/RedisLocalContainerInfraService.java  |  39 +++-
 .../test/infra/redis/services/container.properties |   1 +
 .../test/infra/solr/services/SolrInfraService.java |   4 +
 .../services/SolrLocalContainerInfraService.java   |   3 +-
 .../CamelTestInfraGenerateMetadataMojo.java        |  11 ++
 .../apache/camel/spi/annotations/InfraService.java |   9 +
 58 files changed, 775 insertions(+), 170 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
index 11e895795c96..a751e0b1d99e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
@@ -7,7 +7,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-milvus",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v2.6.20"
+  "serviceVersion" : "v2.6.20",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -17,7 +18,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -27,7 +29,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -37,7 +40,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.iggy.services.IggyInfraService",
   "description" : "Iggy is a persistent message streaming platform",
@@ -47,7 +51,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-iggy",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.8.0"
+  "serviceVersion" : "0.8.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -57,7 +62,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.zookeeper.services.ZooKeeperInfraService",
   "description" : "Zookeeper is a server for highly reliable distributed 
coordination of cloud applications",
@@ -67,7 +73,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-zookeeper",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.9.5"
+  "serviceVersion" : "3.9.5",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -77,7 +84,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.redis.services.RedisInfraService",
   "description" : "Redis is an open source in-memory data store",
@@ -87,7 +95,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-redis",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "7.4.9-alpine"
+  "serviceVersion" : "7.4.9-alpine",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.elasticsearch.services.ElasticSearchInfraService",
   "description" : "Elasticsearch is a distributed search and analytics engine",
@@ -97,7 +106,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-elasticsearch",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "9.1.0"
+  "serviceVersion" : "9.1.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -107,7 +117,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.51.0-kafka-4.2.0"
+  "serviceVersion" : "0.51.0-kafka-4.2.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -117,7 +128,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "8.3.0"
+  "serviceVersion" : "8.3.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.nats.services.NatsInfraService",
   "description" : "NATS is a high-performance messaging system for cloud 
native applications",
@@ -127,7 +139,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-nats",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.14.2"
+  "serviceVersion" : "2.14.2",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -137,7 +150,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.postgres.services.PostgresInfraService",
   "description" : "PostgreSQL is an open source object-relational database",
@@ -147,7 +161,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-postgres",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "17.10-alpine"
+  "serviceVersion" : "17.10-alpine",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -157,7 +172,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v26.1.12"
+  "serviceVersion" : "v26.1.12",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.hashicorp.vault.services.HashicorpVaultInfraService",
   "description" : "HashiCorp Vault is a tool for securely accessing secrets",
@@ -167,7 +183,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hashicorp-vault",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.0.3"
+  "serviceVersion" : "2.0.3",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -177,7 +194,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.artemis.services.ArtemisInfraService",
   "description" : "Apache Artemis is an open source message broker",
@@ -187,7 +205,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-artemis",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "latest"
+  "serviceVersion" : "latest",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.solr.services.SolrInfraService",
   "description" : "Apache Solr is an open source search platform",
@@ -197,7 +216,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-solr",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "9.10.1-slim"
+  "serviceVersion" : "9.10.1-slim",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.couchbase.services.CouchbaseInfraService",
   "description" : "Couchbase is a distributed NoSQL cloud database",
@@ -207,7 +227,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-couchbase",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "8.0.0"
+  "serviceVersion" : "8.0.0",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -217,7 +238,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.couchdb.services.CouchDbInfraService",
   "description" : "Apache CouchDB is an open source NoSQL document database",
@@ -227,7 +249,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-couchdb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.5.1"
+  "serviceVersion" : "3.5.1",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.keycloak.services.KeycloakInfraService",
   "description" : "Keycloak is an open source identity and access management 
solution",
@@ -237,7 +260,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-keycloak",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "26.6.4"
+  "serviceVersion" : "26.6.4",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService",
   "description" : "HiveMQ is an MQTT-based messaging platform for IoT",
@@ -247,7 +271,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hivemq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2025.5"
+  "serviceVersion" : "2025.5",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ibmmq.services.IbmMQInfraService",
   "description" : "IBM MQ is enterprise messaging middleware for reliable 
communication",
@@ -257,7 +282,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ibmmq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "9.4.5.0-r2"
+  "serviceVersion" : "9.4.5.0-r2",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -267,7 +293,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.smb.services.SmbLocalContainerInfraService",
   "description" : "Samba provides file sharing services using the SMB 
protocol",
@@ -277,7 +304,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-smb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.14.0"
+  "serviceVersion" : "0.14.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.openldap.services.OpenldapInfraService",
   "description" : "OpenLDAP is an implementation of the Lightweight Directory 
Access Protocol",
@@ -287,7 +315,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-openldap",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.0"
+  "serviceVersion" : "1.5.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.xmpp.services.XmppInfraService",
   "description" : "XMPP is an open communication protocol for messaging",
@@ -297,7 +326,19 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-xmpp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.3"
+  "serviceVersion" : "0.3",
+  "uiSupported" : false
+}, {
+  "service" : 
"org.apache.camel.test.infra.opensearch.services.OpenSearchInfraService",
+  "description" : "OpenSearch is a distributed search and analytics engine",
+  "implementation" : 
"org.apache.camel.test.infra.opensearch.services.OpenSearchLocalContainerInfraService",
+  "alias" : [ "opensearch" ],
+  "aliasImplementation" : [ ],
+  "groupId" : "org.apache.camel",
+  "artifactId" : "camel-test-infra-opensearch",
+  "version" : "4.22.0-SNAPSHOT",
+  "serviceVersion" : "3.7.0",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.pulsar.services.PulsarInfraService",
   "description" : "Apache Pulsar is a distributed messaging and streaming 
platform",
@@ -307,7 +348,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-pulsar",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "4.2.1"
+  "serviceVersion" : "4.2.1",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.artemis.services.ArtemisInfraService",
   "description" : "Apache Artemis is an open source message broker",
@@ -317,7 +359,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-artemis",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "latest"
+  "serviceVersion" : "latest",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -327,7 +370,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -337,7 +381,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.google.pubsub.services.GooglePubSubInfraService",
   "description" : "Google Cloud Pub/Sub is a messaging service for 
event-driven systems",
@@ -347,7 +392,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-google-pubsub",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "emulators"
+  "serviceVersion" : "emulators",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.chatscript.services.ChatScriptInfraService",
   "description" : "ChatScript is an open source chatbot engine",
@@ -357,7 +403,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-chatscript",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "latest"
+  "serviceVersion" : "latest",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.arangodb.services.ArangoDBInfraService",
   "description" : "ArangoDB is a multi-model database for high-performance 
applications.",
@@ -367,7 +414,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-arangodb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.12.5.2"
+  "serviceVersion" : "3.12.5.2",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.ignite.services.IgniteInfraService",
   "description" : "Apache Ignite is a distributed database for 
high-performance computing",
@@ -377,7 +425,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ignite",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.18.0"
+  "serviceVersion" : "2.18.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.rabbitmq.services.RabbitMQInfraService",
   "description" : "RabbitMQ is an open source message and streaming broker",
@@ -387,7 +436,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-rabbitmq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "4.2.5-management"
+  "serviceVersion" : "4.2.5-management",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.mosquitto.services.MosquittoInfraService",
   "description" : "Mosquitto is a message broker that implements MQTT 
protocol",
@@ -397,7 +447,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-mosquitto",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.0.22"
+  "serviceVersion" : "2.0.22",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.neo4j.services.Neo4jInfraService",
   "description" : "Neo4j is a graph database management system",
@@ -407,7 +458,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-neo4j",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2026.05-community-ubi10"
+  "serviceVersion" : "2026.05-community-ubi10",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.rocketmq.services.RocketMQInfraService",
   "description" : "Apache RocketMQ is a distributed messaging and streaming 
platform",
@@ -417,7 +469,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-rocketmq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.3.3"
+  "serviceVersion" : "5.3.3",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -427,7 +480,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -437,7 +491,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -447,7 +502,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.cassandra.services.CassandraInfraService",
   "description" : "Apache Cassandra is a distributed NoSQL database",
@@ -457,7 +513,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-cassandra",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.0.8"
+  "serviceVersion" : "5.0.8",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -467,7 +524,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.hazelcast.services.HazelcastInfraService",
   "description" : "Hazelcast is a distributed in-memory computing platform",
@@ -477,7 +535,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hazelcast",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.4.0"
+  "serviceVersion" : "5.4.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService",
   "description" : "HiveMQ is an MQTT-based messaging platform for IoT",
@@ -487,7 +546,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hivemq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "camel"
+  "serviceVersion" : "camel",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.postgres.services.PostgresInfraService",
   "description" : "PostgreSQL with pgvector extension for vector similarity 
search",
@@ -497,7 +557,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-postgres",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "pg18"
+  "serviceVersion" : "pg18",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.microprofile.lra.services.MicroprofileLRAInfraService",
   "description" : "Transaction Manager for microservices that is based on the 
SAGA pattern for distributed transaction.",
@@ -507,7 +568,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-microprofile-lra",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.13.1.Final-2.16.6.Final"
+  "serviceVersion" : "5.13.1.Final-2.16.6.Final",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.minio.services.MinioInfraService",
   "description" : "MinIO is a high-performance S3 compatible object storage",
@@ -517,7 +579,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-minio",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1"
+  "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -527,7 +590,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "4.3.1"
+  "serviceVersion" : "4.3.1",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.azure.common.services.AzureInfraService",
   "description" : "Local Azure services with Azurite",
@@ -537,7 +601,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-azure-storage-queue",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.35.0"
+  "serviceVersion" : "3.35.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
   "description" : "Embedded SFTP Server",
@@ -547,7 +612,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ftp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.19.0"
+  "serviceVersion" : "2.19.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.jaeger.services.JaegerInfraService",
   "description" : "Jaeger is a distributed tracing backend with OTLP collector 
and UI",
@@ -557,7 +623,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-jaeger",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.19.0"
+  "serviceVersion" : "2.19.0",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.infinispan.services.InfinispanInfraService",
   "description" : "Infinispan is a distributed in-memory key/value data store",
@@ -567,7 +634,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-infinispan",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "16.2"
+  "serviceVersion" : "16.2",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.weaviate.services.WeaviateInfraService",
   "description" : "Weaviate is an open source vector database",
@@ -577,7 +645,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-weaviate",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.37.4"
+  "serviceVersion" : "1.37.4",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.consul.services.ConsulInfraService",
   "description" : "Consul is a service networking solution",
@@ -587,7 +656,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-consul",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.0.1"
+  "serviceVersion" : "2.0.1",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.qdrant.services.QdrantInfraService",
   "description" : "Qdrant is a vector similarity search engine and database",
@@ -597,7 +667,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-qdrant",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v1.18.2-unprivileged"
+  "serviceVersion" : "v1.18.2-unprivileged",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
   "description" : "Embedded FTPS Server",
@@ -607,7 +678,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ftp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.2.1"
+  "serviceVersion" : "1.2.1",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ollama.services.OllamaInfraService",
   "description" : "Ollama is a tool for running large language models locally",
@@ -617,7 +689,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ollama",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.31.2"
+  "serviceVersion" : "0.31.2",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.azure.common.services.AzureInfraService",
   "description" : "Local Azure services with Azurite",
@@ -627,7 +700,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-azure-storage-blob",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.35.0"
+  "serviceVersion" : "3.35.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.docling.services.DoclingInfraService",
   "description" : "Docling is a document processing and conversion toolkit",
@@ -637,7 +711,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-docling",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v1.26.0"
+  "serviceVersion" : "v1.26.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -647,7 +722,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.fhir.services.FhirInfraService",
   "description" : "HAPI FHIR RESTful test server",
@@ -657,7 +733,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-fhir",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v8.10.0-2"
+  "serviceVersion" : "v8.10.0-2",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.pinecone.services.PineconeInfraService",
   "description" : "Pinecone is a vector database for machine learning 
applications",
@@ -667,7 +744,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-pinecone",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v1.0.0.rc0"
+  "serviceVersion" : "v1.0.0.rc0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
   "description" : "Embedded FTP Server",
@@ -677,7 +755,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ftp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.2.1"
+  "serviceVersion" : "1.2.1",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.mongodb.services.MongoDBInfraService",
   "description" : "MongoDB is a document-oriented NoSQL database",
@@ -687,5 +766,6 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-mongodb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "7.0.31-jammy"
+  "serviceVersion" : "7.0.31-jammy",
+  "uiSupported" : true
 } ]
\ No newline at end of file
diff --git 
a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java
 
b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java
index fb6051e05581..e4ef026135a7 100644
--- 
a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java
+++ 
b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java
@@ -81,4 +81,13 @@ public @interface InfraService {
      * @return
      */
     String serviceVersion() default "";
+
+    /**
+     * Whether this service supports a web UI (built-in or via companion 
container).
+     *
+     * When true, the service interface should provide a {@code uiUrl()} 
method that returns the UI URL when available.
+     *
+     * @return true if the service has UI support
+     */
+    boolean uiSupported() default false;
 }
diff --git 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-infra-run.adoc 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-infra-run.adoc
index bc7b7bcf2c93..a0d1592f2764 100644
--- 
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-infra-run.adoc
+++ 
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-infra-run.adoc
@@ -22,6 +22,7 @@ camel infra run [options]
 | `--background` | Run in the background | false | boolean
 | `--json` | Output in JSON Format |  | boolean
 | `--log` | Log container output to console |  | boolean
+| `--no-ui` | Do not start companion UI containers | false | boolean
 | `--port` | Override the default port for the service |  | Integer
 | `-h,--help` | Display the help and sub-commands |  | boolean
 |===
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
 
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
index d207910f993c..b19e55604a5c 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
@@ -18,7 +18,7 @@
     { "name": "get", "fullName": "get", "description": "Get status of Camel 
integrations", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.CamelStatus", "options": [ { 
"names": "--watch", "description": "Execute periodically and showing output 
fullscreen", "javaType": "boolean", "type": "boolean" }, { "names": 
"-h,--help", "description": "Display the help and sub-commands", "javaType": 
"boolean", "type": "boolean" } ], "subcommands": [ { "name": "activity", 
"fullName": " [...]
     { "name": "harden", "fullName": "harden", "description": "Suggest security 
hardening for Camel routes using AI\/LLM", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.Harden", "options": [ { "names": 
"--api-key", "description": "API key for authentication. Also reads 
OPENAI_API_KEY or LLM_API_KEY env vars", "javaType": "java.lang.String", 
"type": "string" }, { "names": "--api-type", "description": "API type: 'ollama' 
or 'openai' (OpenAI-compatible)", "defaultValue": "ollama", [...]
     { "name": "hawtio", "fullName": "hawtio", "description": "Launch Hawtio 
web console", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.Hawtio", "options": [ { 
"names": "--host", "description": "Hostname to bind the Hawtio web console to", 
"defaultValue": "127.0.0.1", "javaType": "java.lang.String", "type": "string" 
}, { "names": "--openUrl", "description": "To automatic open Hawtio web console 
in the web browser", "defaultValue": "true", "javaType": "boolean", "type": 
[...]
-    { "name": "infra", "fullName": "infra", "description": "List and Run 
external services for testing and prototyping", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.infra.InfraCommand", "options": [ { 
"names": "--json", "description": "Output in JSON Format", "javaType": 
"boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display 
the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], 
"subcommands": [ { "name": "get", "fullName": "infra  [...]
+    { "name": "infra", "fullName": "infra", "description": "List and Run 
external services for testing and prototyping", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.infra.InfraCommand", "options": [ { 
"names": "--json", "description": "Output in JSON Format", "javaType": 
"boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display 
the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], 
"subcommands": [ { "name": "get", "fullName": "infra  [...]
     { "name": "init", "fullName": "init", "description": "Creates a new Camel 
integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Init", 
"options": [ { "names": "--clean-dir,--clean-directory", "description": 
"Whether to clean directory first (deletes all files in directory)", 
"javaType": "boolean", "type": "boolean" }, { "names": "--dir,--directory", 
"description": "Directory relative path where the new Camel integration will be 
saved", "defaultValue": ".", "javaType" [...]
     { "name": "jolokia", "fullName": "jolokia", "description": "Attach Jolokia 
JVM Agent to a running Camel integration", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.process.Jolokia", "options": [ { 
"names": "--port", "description": "To use a specific port number when attaching 
Jolokia JVM Agent (default a free port is found in range 8778-9999)", 
"javaType": "int", "type": "integer" }, { "names": "--stop", "description": 
"Stops the Jolokia JVM Agent in the running Camel inte [...]
     { "name": "log", "fullName": "log", "description": "Tail logs from running 
Camel integrations", "sourceClass": 
"org.apache.camel.dsl.jbang.core.commands.action.CamelLogAction", "options": [ 
{ "names": "--find", "description": "Find and highlight matching text (ignore 
case).", "javaType": "java.lang.String", "type": "string" }, { "names": 
"--follow", "description": "Keep following and outputting new log lines (press 
enter to exit).", "defaultValue": "true", "javaType": "boolean", "typ [...]
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
index e59bfd51653a..8c6b0e7e9a54 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
@@ -167,6 +167,9 @@ public abstract class InfraBaseCommand extends CamelCommand 
{
                 if (service.aliasImplementation() != null) {
                     
services.get(alias).getAliasImplementation().addAll(service.aliasImplementation());
                 }
+                if (service.uiSupported()) {
+                    services.get(alias).setUiSupported(true);
+                }
             }
         }
 
@@ -182,7 +185,8 @@ public abstract class InfraBaseCommand extends CamelCommand 
{
                             .sorted()
                             .collect(Collectors.joining(", ")),
                     entry.getValue().getDescription(),
-                    getServiceData(entry.getKey(), pid)));
+                    getServiceData(entry.getKey(), pid),
+                    entry.getValue().isUiSupported()));
         }
 
         rows.sort(Comparator.comparing(InfraList.Row::alias));
@@ -195,7 +199,7 @@ public abstract class InfraBaseCommand extends CamelCommand 
{
                     Jsoner.serialize(
                             rows.stream().map(row -> new InfraBaseDTO(
                                     row.alias, row.aliasImplementation, 
row.description,
-                                    parseServiceData(row.serviceData())))
+                                    parseServiceData(row.serviceData()), 
row.uiSupported()))
                                     .map(InfraBaseDTO::toMap)
                                     .collect(Collectors.toList())));
         } else {
@@ -204,19 +208,22 @@ public abstract class InfraBaseCommand extends 
CamelCommand {
             // IMPLEMENTATION is capped and SERVICE_DATA keeps a compact fixed 
width; both truncate with an ellipsis
             // instead of overflowing the terminal (the full, structured 
service data is available via --json).
             int serviceDataWidth = 30;
+            int uiWidth = 4;
             int aliasWidth = width + 2;
             int pidWidth = showPidColumn()
                     ? CamelTableColumns.measure("PID", Integer.MAX_VALUE, 
rows, r -> r.pid) : 0;
             int implWidth = CamelTableColumns.measure("IMPLEMENTATION", 35, 
rows, Row::aliasImplementation);
-            int overhead = 
TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 5 : 4);
+            int overhead = 
TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 6 : 5);
             int descWidth = CamelTableColumns.lastColumnWidth(
-                    tw, overhead, pidWidth, aliasWidth, implWidth, 
serviceDataWidth);
+                    tw, overhead, pidWidth, aliasWidth, implWidth, uiWidth, 
serviceDataWidth);
             printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, 
Arrays.asList(
                     new 
Column().header("PID").visible(showPidColumn()).headerAlign(HorizontalAlign.CENTER).with(r
 -> r.pid),
                     new 
Column().header("ALIAS").minWidth(aliasWidth).dataAlign(HorizontalAlign.LEFT)
                             .with(Row::alias),
                     new Column().header("IMPLEMENTATION").maxWidth(implWidth, 
OverflowBehaviour.ELLIPSIS_RIGHT)
                             
.dataAlign(HorizontalAlign.LEFT).with(Row::aliasImplementation),
+                    new 
Column().header("UI").maxWidth(uiWidth).dataAlign(HorizontalAlign.CENTER)
+                            .with(r -> r.uiSupported() ? "x" : ""),
                     CamelTableColumns.lastText("DESCRIPTION", 
descWidth).with(Row::description),
                     new 
Column().header("SERVICE_DATA").maxWidth(serviceDataWidth, 
OverflowBehaviour.ELLIPSIS_RIGHT)
                             
.dataAlign(HorizontalAlign.LEFT).with(Row::serviceData))));
@@ -286,15 +293,18 @@ public abstract class InfraBaseCommand extends 
CamelCommand {
             String groupId,
             String artifactId,
             String version,
-            String serviceVersion) {
+            String serviceVersion,
+            boolean uiSupported) {
     }
 
-    record Row(String pid, String alias, String aliasImplementation, String 
description, String serviceData) {
+    record Row(String pid, String alias, String aliasImplementation, String 
description, String serviceData,
+            boolean uiSupported) {
     }
 
     private static class InfraServiceAlias {
         private final String description;
         private final Set<String> aliasImplementation = new HashSet<>();
+        private boolean uiSupported;
 
         public InfraServiceAlias(String description) {
             this.description = description;
@@ -307,5 +317,13 @@ public abstract class InfraBaseCommand extends 
CamelCommand {
         public Set<String> getAliasImplementation() {
             return aliasImplementation;
         }
+
+        public boolean isUiSupported() {
+            return uiSupported;
+        }
+
+        public void setUiSupported(boolean uiSupported) {
+            this.uiSupported = uiSupported;
+        }
     }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
index cfca1893cb33..244707de8287 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java
@@ -65,6 +65,10 @@ public class InfraRun extends InfraBaseCommand {
                         description = "Override the default port for the 
service")
     Integer port;
 
+    @CommandLine.Option(names = { "--no-ui" }, defaultValue = "false",
+                        description = "Do not start companion UI containers")
+    boolean noUi;
+
     public InfraRun(CamelJBangMain main) {
         super(main);
     }
@@ -137,6 +141,9 @@ public class InfraRun extends InfraBaseCommand {
             if (logToStdout) {
                 cmds.add("--log");
             }
+            if (noUi) {
+                cmds.add("--no-ui");
+            }
         }
 
         cmds.remove("--background=true");
@@ -169,7 +176,9 @@ public class InfraRun extends InfraBaseCommand {
         if (port != null) {
             System.setProperty("camel.infra.port", String.valueOf(port));
         }
-
+        if (noUi) {
+            System.setProperty("camel.infra.ui", "false");
+        }
         Object actualService = cl.loadClass(serviceImpl).newInstance();
 
         // Make sure the actualService can be run with initialize method
@@ -316,6 +325,7 @@ public class InfraRun extends InfraBaseCommand {
             }
             System.clearProperty("camel.infra.port");
             System.clearProperty("camel.infra.fixedPort");
+            System.clearProperty("camel.infra.ui");
         }
     }
 
@@ -364,4 +374,5 @@ public class InfraRun extends InfraBaseCommand {
     public void setLogToStdout(boolean logToStdout) {
         this.logToStdout = logToStdout;
     }
+
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java
index 8f69b30c8f2d..e92a0bac7f80 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java
@@ -26,15 +26,18 @@ public class InfraBaseDTO {
     private String aliasImplementation;
     private String description;
     private Object serviceData;
+    private boolean uiSupported;
 
     public InfraBaseDTO() {
     }
 
-    public InfraBaseDTO(String alias, String aliasImplementation, String 
description, Object serviceData) {
+    public InfraBaseDTO(String alias, String aliasImplementation, String 
description, Object serviceData,
+                        boolean uiSupported) {
         this.alias = alias;
         this.aliasImplementation = aliasImplementation;
         this.description = description;
         this.serviceData = serviceData;
+        this.uiSupported = uiSupported;
     }
 
     public String getAlias() {
@@ -69,6 +72,14 @@ public class InfraBaseDTO {
         this.serviceData = serviceData;
     }
 
+    public boolean isUiSupported() {
+        return uiSupported;
+    }
+
+    public void setUiSupported(boolean uiSupported) {
+        this.uiSupported = uiSupported;
+    }
+
     public Map<String, Object> toMap() {
         JsonObject jo = new JsonObject();
         jo.put("alias", alias);
@@ -81,6 +92,7 @@ public class InfraBaseDTO {
         if (serviceData != null) {
             jo.put("serviceData", serviceData);
         }
+        jo.put("uiSupported", uiSupported);
         return jo;
     }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
index e8983b74be70..794fa260c8b4 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
@@ -77,7 +77,7 @@ public class InfraTest extends CamelCommandBaseTestSupport {
         String rawServiceData = "{\"host\":\"localhost\",\"port\":61616}";
         Object serviceData = InfraBaseCommand.parseServiceData(rawServiceData);
 
-        InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", 
serviceData);
+        InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", 
serviceData, true);
         String json = Jsoner.serialize(List.of(dto.toMap()));
 
         // serviceData is embedded as a nested JSON object (so --json is 
machine-parseable), not a string-escaped blob
@@ -93,7 +93,7 @@ public class InfraTest extends CamelCommandBaseTestSupport {
         // unparseable content is dropped rather than emitted as an escaped 
string
         Assertions.assertThat(serviceData).isNull();
 
-        InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", 
serviceData);
+        InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", 
serviceData, true);
         String json = Jsoner.serialize(List.of(dto.toMap()));
 
         Assertions.assertThat(json).contains("\"alias\":\"artemis\"");
diff --git 
a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
 
b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
index 11e895795c96..a751e0b1d99e 100644
--- 
a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
+++ 
b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
@@ -7,7 +7,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-milvus",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v2.6.20"
+  "serviceVersion" : "v2.6.20",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -17,7 +18,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -27,7 +29,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -37,7 +40,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.iggy.services.IggyInfraService",
   "description" : "Iggy is a persistent message streaming platform",
@@ -47,7 +51,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-iggy",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.8.0"
+  "serviceVersion" : "0.8.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -57,7 +62,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.zookeeper.services.ZooKeeperInfraService",
   "description" : "Zookeeper is a server for highly reliable distributed 
coordination of cloud applications",
@@ -67,7 +73,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-zookeeper",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.9.5"
+  "serviceVersion" : "3.9.5",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -77,7 +84,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.redis.services.RedisInfraService",
   "description" : "Redis is an open source in-memory data store",
@@ -87,7 +95,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-redis",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "7.4.9-alpine"
+  "serviceVersion" : "7.4.9-alpine",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.elasticsearch.services.ElasticSearchInfraService",
   "description" : "Elasticsearch is a distributed search and analytics engine",
@@ -97,7 +106,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-elasticsearch",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "9.1.0"
+  "serviceVersion" : "9.1.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -107,7 +117,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.51.0-kafka-4.2.0"
+  "serviceVersion" : "0.51.0-kafka-4.2.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -117,7 +128,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "8.3.0"
+  "serviceVersion" : "8.3.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.nats.services.NatsInfraService",
   "description" : "NATS is a high-performance messaging system for cloud 
native applications",
@@ -127,7 +139,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-nats",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.14.2"
+  "serviceVersion" : "2.14.2",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -137,7 +150,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.postgres.services.PostgresInfraService",
   "description" : "PostgreSQL is an open source object-relational database",
@@ -147,7 +161,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-postgres",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "17.10-alpine"
+  "serviceVersion" : "17.10-alpine",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -157,7 +172,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v26.1.12"
+  "serviceVersion" : "v26.1.12",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.hashicorp.vault.services.HashicorpVaultInfraService",
   "description" : "HashiCorp Vault is a tool for securely accessing secrets",
@@ -167,7 +183,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hashicorp-vault",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.0.3"
+  "serviceVersion" : "2.0.3",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -177,7 +194,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.artemis.services.ArtemisInfraService",
   "description" : "Apache Artemis is an open source message broker",
@@ -187,7 +205,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-artemis",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "latest"
+  "serviceVersion" : "latest",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.solr.services.SolrInfraService",
   "description" : "Apache Solr is an open source search platform",
@@ -197,7 +216,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-solr",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "9.10.1-slim"
+  "serviceVersion" : "9.10.1-slim",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.couchbase.services.CouchbaseInfraService",
   "description" : "Couchbase is a distributed NoSQL cloud database",
@@ -207,7 +227,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-couchbase",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "8.0.0"
+  "serviceVersion" : "8.0.0",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -217,7 +238,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.couchdb.services.CouchDbInfraService",
   "description" : "Apache CouchDB is an open source NoSQL document database",
@@ -227,7 +249,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-couchdb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.5.1"
+  "serviceVersion" : "3.5.1",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.keycloak.services.KeycloakInfraService",
   "description" : "Keycloak is an open source identity and access management 
solution",
@@ -237,7 +260,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-keycloak",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "26.6.4"
+  "serviceVersion" : "26.6.4",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService",
   "description" : "HiveMQ is an MQTT-based messaging platform for IoT",
@@ -247,7 +271,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hivemq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2025.5"
+  "serviceVersion" : "2025.5",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ibmmq.services.IbmMQInfraService",
   "description" : "IBM MQ is enterprise messaging middleware for reliable 
communication",
@@ -257,7 +282,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ibmmq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "9.4.5.0-r2"
+  "serviceVersion" : "9.4.5.0-r2",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -267,7 +293,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.smb.services.SmbLocalContainerInfraService",
   "description" : "Samba provides file sharing services using the SMB 
protocol",
@@ -277,7 +304,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-smb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.14.0"
+  "serviceVersion" : "0.14.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.openldap.services.OpenldapInfraService",
   "description" : "OpenLDAP is an implementation of the Lightweight Directory 
Access Protocol",
@@ -287,7 +315,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-openldap",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.0"
+  "serviceVersion" : "1.5.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.xmpp.services.XmppInfraService",
   "description" : "XMPP is an open communication protocol for messaging",
@@ -297,7 +326,19 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-xmpp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.3"
+  "serviceVersion" : "0.3",
+  "uiSupported" : false
+}, {
+  "service" : 
"org.apache.camel.test.infra.opensearch.services.OpenSearchInfraService",
+  "description" : "OpenSearch is a distributed search and analytics engine",
+  "implementation" : 
"org.apache.camel.test.infra.opensearch.services.OpenSearchLocalContainerInfraService",
+  "alias" : [ "opensearch" ],
+  "aliasImplementation" : [ ],
+  "groupId" : "org.apache.camel",
+  "artifactId" : "camel-test-infra-opensearch",
+  "version" : "4.22.0-SNAPSHOT",
+  "serviceVersion" : "3.7.0",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.pulsar.services.PulsarInfraService",
   "description" : "Apache Pulsar is a distributed messaging and streaming 
platform",
@@ -307,7 +348,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-pulsar",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "4.2.1"
+  "serviceVersion" : "4.2.1",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.artemis.services.ArtemisInfraService",
   "description" : "Apache Artemis is an open source message broker",
@@ -317,7 +359,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-artemis",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "latest"
+  "serviceVersion" : "latest",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -327,7 +370,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -337,7 +381,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.google.pubsub.services.GooglePubSubInfraService",
   "description" : "Google Cloud Pub/Sub is a messaging service for 
event-driven systems",
@@ -347,7 +392,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-google-pubsub",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "emulators"
+  "serviceVersion" : "emulators",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.chatscript.services.ChatScriptInfraService",
   "description" : "ChatScript is an open source chatbot engine",
@@ -357,7 +403,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-chatscript",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "latest"
+  "serviceVersion" : "latest",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.arangodb.services.ArangoDBInfraService",
   "description" : "ArangoDB is a multi-model database for high-performance 
applications.",
@@ -367,7 +414,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-arangodb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.12.5.2"
+  "serviceVersion" : "3.12.5.2",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.ignite.services.IgniteInfraService",
   "description" : "Apache Ignite is a distributed database for 
high-performance computing",
@@ -377,7 +425,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ignite",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.18.0"
+  "serviceVersion" : "2.18.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.rabbitmq.services.RabbitMQInfraService",
   "description" : "RabbitMQ is an open source message and streaming broker",
@@ -387,7 +436,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-rabbitmq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "4.2.5-management"
+  "serviceVersion" : "4.2.5-management",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.mosquitto.services.MosquittoInfraService",
   "description" : "Mosquitto is a message broker that implements MQTT 
protocol",
@@ -397,7 +447,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-mosquitto",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.0.22"
+  "serviceVersion" : "2.0.22",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.neo4j.services.Neo4jInfraService",
   "description" : "Neo4j is a graph database management system",
@@ -407,7 +458,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-neo4j",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2026.05-community-ubi10"
+  "serviceVersion" : "2026.05-community-ubi10",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.rocketmq.services.RocketMQInfraService",
   "description" : "Apache RocketMQ is a distributed messaging and streaming 
platform",
@@ -417,7 +469,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-rocketmq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.3.3"
+  "serviceVersion" : "5.3.3",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -427,7 +480,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -437,7 +491,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -447,7 +502,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.cassandra.services.CassandraInfraService",
   "description" : "Apache Cassandra is a distributed NoSQL database",
@@ -457,7 +513,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-cassandra",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.0.8"
+  "serviceVersion" : "5.0.8",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -467,7 +524,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.hazelcast.services.HazelcastInfraService",
   "description" : "Hazelcast is a distributed in-memory computing platform",
@@ -477,7 +535,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hazelcast",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.4.0"
+  "serviceVersion" : "5.4.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService",
   "description" : "HiveMQ is an MQTT-based messaging platform for IoT",
@@ -487,7 +546,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-hivemq",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "camel"
+  "serviceVersion" : "camel",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.postgres.services.PostgresInfraService",
   "description" : "PostgreSQL with pgvector extension for vector similarity 
search",
@@ -497,7 +557,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-postgres",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "pg18"
+  "serviceVersion" : "pg18",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.microprofile.lra.services.MicroprofileLRAInfraService",
   "description" : "Transaction Manager for microservices that is based on the 
SAGA pattern for distributed transaction.",
@@ -507,7 +568,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-microprofile-lra",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "5.13.1.Final-2.16.6.Final"
+  "serviceVersion" : "5.13.1.Final-2.16.6.Final",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.minio.services.MinioInfraService",
   "description" : "MinIO is a high-performance S3 compatible object storage",
@@ -517,7 +579,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-minio",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1"
+  "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService",
   "description" : "Apache Kafka, Distributed event streaming platform",
@@ -527,7 +590,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-kafka",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "4.3.1"
+  "serviceVersion" : "4.3.1",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.azure.common.services.AzureInfraService",
   "description" : "Local Azure services with Azurite",
@@ -537,7 +601,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-azure-storage-queue",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.35.0"
+  "serviceVersion" : "3.35.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
   "description" : "Embedded SFTP Server",
@@ -547,7 +612,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ftp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.19.0"
+  "serviceVersion" : "2.19.0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.jaeger.services.JaegerInfraService",
   "description" : "Jaeger is a distributed tracing backend with OTLP collector 
and UI",
@@ -557,7 +623,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-jaeger",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.19.0"
+  "serviceVersion" : "2.19.0",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.infinispan.services.InfinispanInfraService",
   "description" : "Infinispan is a distributed in-memory key/value data store",
@@ -567,7 +634,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-infinispan",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "16.2"
+  "serviceVersion" : "16.2",
+  "uiSupported" : true
 }, {
   "service" : 
"org.apache.camel.test.infra.weaviate.services.WeaviateInfraService",
   "description" : "Weaviate is an open source vector database",
@@ -577,7 +645,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-weaviate",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.37.4"
+  "serviceVersion" : "1.37.4",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.consul.services.ConsulInfraService",
   "description" : "Consul is a service networking solution",
@@ -587,7 +656,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-consul",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "2.0.1"
+  "serviceVersion" : "2.0.1",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.qdrant.services.QdrantInfraService",
   "description" : "Qdrant is a vector similarity search engine and database",
@@ -597,7 +667,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-qdrant",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v1.18.2-unprivileged"
+  "serviceVersion" : "v1.18.2-unprivileged",
+  "uiSupported" : true
 }, {
   "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
   "description" : "Embedded FTPS Server",
@@ -607,7 +678,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ftp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.2.1"
+  "serviceVersion" : "1.2.1",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ollama.services.OllamaInfraService",
   "description" : "Ollama is a tool for running large language models locally",
@@ -617,7 +689,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ollama",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "0.31.2"
+  "serviceVersion" : "0.31.2",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.azure.common.services.AzureInfraService",
   "description" : "Local Azure services with Azurite",
@@ -627,7 +700,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-azure-storage-blob",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "3.35.0"
+  "serviceVersion" : "3.35.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.docling.services.DoclingInfraService",
   "description" : "Docling is a document processing and conversion toolkit",
@@ -637,7 +711,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-docling",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v1.26.0"
+  "serviceVersion" : "v1.26.0",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.aws.common.services.AWSInfraService",
   "description" : "Local AWS Services with LocalStack",
@@ -647,7 +722,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-aws-v2",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.5.28"
+  "serviceVersion" : "1.5.28",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.fhir.services.FhirInfraService",
   "description" : "HAPI FHIR RESTful test server",
@@ -657,7 +733,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-fhir",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v8.10.0-2"
+  "serviceVersion" : "v8.10.0-2",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.pinecone.services.PineconeInfraService",
   "description" : "Pinecone is a vector database for machine learning 
applications",
@@ -667,7 +744,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-pinecone",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "v1.0.0.rc0"
+  "serviceVersion" : "v1.0.0.rc0",
+  "uiSupported" : false
 }, {
   "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
   "description" : "Embedded FTP Server",
@@ -677,7 +755,8 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-ftp",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "1.2.1"
+  "serviceVersion" : "1.2.1",
+  "uiSupported" : false
 }, {
   "service" : 
"org.apache.camel.test.infra.mongodb.services.MongoDBInfraService",
   "description" : "MongoDB is a document-oriented NoSQL database",
@@ -687,5 +766,6 @@
   "groupId" : "org.apache.camel",
   "artifactId" : "camel-test-infra-mongodb",
   "version" : "4.22.0-SNAPSHOT",
-  "serviceVersion" : "7.0.31-jammy"
+  "serviceVersion" : "7.0.31-jammy",
+  "uiSupported" : true
 } ]
\ No newline at end of file
diff --git 
a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
 
b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
index 357f4439c463..9d5440b4e209 100644
--- 
a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
+++ 
b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
@@ -58,4 +58,8 @@ public interface ArangoDBInfraService extends 
InfrastructureService {
     default String password() {
         return "";
     }
+
+    default String uiUrl() {
+        return String.format("http://%s:%d";, host(), port());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java
index 555231e0259e..759f0304a267 100644
--- 
a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java
@@ -26,7 +26,8 @@ import org.slf4j.LoggerFactory;
 
 @InfraService(service = ArangoDBInfraService.class,
               description = "ArangoDB is a multi-model database for 
high-performance applications.",
-              serviceAlias = "arangodb")
+              serviceAlias = "arangodb",
+              uiSupported = true)
 public class ArangoDBLocalContainerInfraService implements 
ArangoDBInfraService, ContainerService<ArangoDbContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(ArangoDBLocalContainerInfraService.class);
 
diff --git 
a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java
 
b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java
index 3426db9d8eab..3e8028c07dcb 100644
--- 
a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java
+++ 
b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java
@@ -25,7 +25,8 @@ import org.slf4j.LoggerFactory;
 
 @InfraService(service = ArtemisInfraService.class,
               description = "Apache Artemis is an open source message broker",
-              serviceAlias = "artemis")
+              serviceAlias = "artemis",
+              uiSupported = true)
 public class ArtemisAllInfraService implements ArtemisInfraService, 
ContainerService<ArtemisContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(ArtemisAllInfraService.class);
 
@@ -102,4 +103,9 @@ public class ArtemisAllInfraService implements 
ArtemisInfraService, ContainerSer
     public String remoteURI() {
         return serviceAddress();
     }
+
+    @Override
+    public String uiUrl() {
+        return container.adminURL();
+    }
 }
diff --git 
a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
 
b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
index 105fcefff66d..09d97457de15 100644
--- 
a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
+++ 
b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
@@ -59,6 +59,10 @@ public interface ArtemisInfraService extends 
InfrastructureService {
         System.setProperty(ArtemisProperties.ARTEMIS_PASSWORD, password());
     }
 
+    default String uiUrl() {
+        return null;
+    }
+
     void restart();
 
     long countMessages(String queue) throws Exception;
diff --git 
a/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java
 
b/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java
index 72cbfc840e78..4f23e9235a73 100644
--- 
a/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java
+++ 
b/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java
@@ -35,6 +35,8 @@ public final class ContainerEnvironmentUtil {
     public static final String STARTUP_ATTEMPTS_PROPERTY = ".startup.attempts";
     public static final String INFRA_PORT_PROPERTY = "camel.infra.port";
     public static final String INFRA_FIXED_PORT_PROPERTY = 
"camel.infra.fixedPort";
+    public static final String INFRA_UI_PROPERTY = "camel.infra.ui";
+
     private static final Logger LOG = 
LoggerFactory.getLogger(ContainerEnvironmentUtil.class);
     private static final AtomicInteger INSTANCE_COUNTER = new AtomicInteger(0);
 
@@ -108,6 +110,22 @@ public final class ContainerEnvironmentUtil {
         return fixedPort;
     }
 
+    /**
+     * Determines if companion UI containers should be started alongside 
infrastructure services. Driven by the
+     * {@link #INFRA_UI_PROPERTY} system property: {@code "true"} to start UI 
containers, {@code "false"} to suppress
+     * them. When the property is not set, defaults to {@code true} in 
fixed-port mode (Camel CLI) and {@code false}
+     * otherwise (tests).
+     *
+     * @return true if companion UI containers should be started
+     */
+    public static boolean isWithUi() {
+        String uiProp = System.getProperty(INFRA_UI_PROPERTY);
+        if (uiProp != null) {
+            return Boolean.parseBoolean(uiProp);
+        }
+        return 
Boolean.parseBoolean(System.getProperty(INFRA_FIXED_PORT_PROPERTY, "false"));
+    }
+
     public static String containerName(Class cls) {
         InfraService annotation = findAnnotation(cls);
         String name = null;
diff --git 
a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java
 
b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java
index 08b0bc40cc6a..c130c7fe0f72 100644
--- 
a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java
+++ 
b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java
@@ -28,4 +28,8 @@ public interface ConsulInfraService extends 
InfrastructureService {
     String host();
 
     int port();
+
+    default String uiUrl() {
+        return getConsulUrl() + "/ui";
+    }
 }
diff --git 
a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java
index 25b8a248e2bc..a44a53b99e40 100644
--- 
a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java
@@ -28,7 +28,8 @@ import org.testcontainers.containers.wait.strategy.Wait;
 
 @InfraService(service = ConsulInfraService.class,
               description = "Consul is a service networking solution",
-              serviceAlias = { "consul" })
+              serviceAlias = { "consul" },
+              uiSupported = true)
 public class ConsulLocalContainerInfraService implements ConsulInfraService, 
ContainerService<GenericContainer<?>> {
     public static final String CONTAINER_NAME = "consul";
 
diff --git 
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
 
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
index b09cd51b5ba0..41fc41f1eed4 100644
--- 
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
+++ 
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
@@ -63,4 +63,8 @@ public interface CouchbaseInfraService extends 
InfrastructureService {
     default String connectionBase() {
         return String.format("couchbase:%s://%s:%d", protocol(), hostname(), 
port());
     }
+
+    default String uiUrl() {
+        return String.format("http://%s:%d";, hostname(), port());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
index 1f22bd4a9e7a..f5f74412d700 100644
--- 
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
@@ -37,7 +37,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = CouchbaseInfraService.class,
               description = "Couchbase is a distributed NoSQL cloud database",
-              serviceAlias = { "couchbase" })
+              serviceAlias = { "couchbase" },
+              uiSupported = true)
 public class CouchbaseLocalContainerInfraService implements 
CouchbaseInfraService, ContainerService<CouchbaseContainer> {
 
     private class CustomCouchbaseContainer extends CouchbaseContainer {
diff --git 
a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
 
b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
index f9de00a66b59..95f238c71ce1 100644
--- 
a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
+++ 
b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
@@ -43,4 +43,8 @@ public interface CouchDbInfraService extends 
InfrastructureService {
     default String connectionBase() {
         return String.format("couchdb:http:%s:%d", host(), port());
     }
+
+    default String uiUrl() {
+        return String.format("http://%s:%d/_utils";, host(), port());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java
index 1a036ffac97a..e74bd823d329 100644
--- 
a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java
@@ -29,7 +29,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = CouchDbInfraService.class,
               description = "Apache CouchDB is an open source NoSQL document 
database",
-              serviceAlias = { "couchdb" })
+              serviceAlias = { "couchdb" },
+              uiSupported = true)
 public class CouchDbLocalContainerInfraService implements CouchDbInfraService, 
ContainerService<GenericContainer<?>> {
     public static final String CONTAINER_NAME = "couchdb";
 
diff --git 
a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
 
b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
index bb83f4db7f3b..cb12baf62cbb 100644
--- 
a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
+++ 
b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
@@ -32,4 +32,8 @@ public interface HashicorpVaultInfraService extends 
InfrastructureService {
     default String scheme() {
         return "http";
     }
+
+    default String uiUrl() {
+        return String.format("%s://%s:%d/ui", scheme(), host(), port());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java
index 55b05d1a86aa..316fe5fda02e 100644
--- 
a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java
@@ -35,7 +35,8 @@ import org.testcontainers.utility.DockerImageName;
 @InfraService(service = HashicorpVaultInfraService.class,
               description = "HashiCorp Vault is a tool for securely accessing 
secrets",
               serviceAlias = "hashicorp",
-              serviceImplementationAlias = "vault")
+              serviceImplementationAlias = "vault",
+              uiSupported = true)
 public class HashicorpVaultLocalContainerInfraService
         implements HashicorpVaultInfraService, 
ContainerService<GenericContainer<?>> {
     public static final String CONTAINER_NAME = "hashicorp-vault";
diff --git 
a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
 
b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
index 0d668c697ee6..60bd1cee7f31 100644
--- 
a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
+++ 
b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
@@ -48,4 +48,8 @@ public interface IbmMQInfraService extends 
InfrastructureService {
     default String brokerUrl() {
         return String.format("amqp://%s:%d", host(), port());
     }
+
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java
index 00d32805b8a9..41b577c539a1 100644
--- 
a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java
@@ -39,7 +39,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = IbmMQInfraService.class,
               description = "IBM MQ is enterprise messaging middleware for 
reliable communication",
-              serviceAlias = "ibmmq")
+              serviceAlias = "ibmmq",
+              uiSupported = true)
 public class IbmMQLocalContainerInfraService implements IbmMQInfraService, 
ContainerService<GenericContainer<?>> {
 
     public static final String CONTAINER_NAME = "ibmmq";
@@ -148,4 +149,9 @@ public class IbmMQLocalContainerInfraService implements 
IbmMQInfraService, Conta
     public int listenerPort() {
         return container.getMappedPort(MQ_LISTENER_PORT);
     }
+
+    @Override
+    public String uiUrl() {
+        return String.format("https://%s:%d/ibmmq/console";, 
container.getHost(), container.getMappedPort(WEB_CONSOLE_PORT));
+    }
 }
diff --git 
a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
 
b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
index 87124267fe75..1a55f60e62ee 100644
--- 
a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
+++ 
b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
@@ -37,4 +37,8 @@ public interface InfinispanInfraService extends 
InfrastructureService {
     default String hosts() {
         return String.format("%s:%d", host(), port());
     }
+
+    default String uiUrl() {
+        return String.format("http://%s:%d/console";, host(), port());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java
index 1c415377de07..15962f2ea89c 100644
--- 
a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java
@@ -34,7 +34,8 @@ import org.testcontainers.containers.wait.strategy.Wait;
 
 @InfraService(service = InfinispanInfraService.class,
               description = "Infinispan is a distributed in-memory key/value 
data store",
-              serviceAlias = { "infinispan" })
+              serviceAlias = { "infinispan" },
+              uiSupported = true)
 public class InfinispanLocalContainerInfraService implements 
InfinispanInfraService, ContainerService<GenericContainer<?>> {
     public static final String CONTAINER_NAME = "infinispan";
     private static final String DEFAULT_USERNAME = "admin";
diff --git 
a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java
 
b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java
index d89088ea5b16..03f5d468d65a 100644
--- 
a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java
+++ 
b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java
@@ -45,4 +45,8 @@ public interface JaegerInfraService extends 
InfrastructureService {
     default String queryUiUrl() {
         return String.format("http://%s:%d";, host(), queryUiPort());
     }
+
+    default String uiUrl() {
+        return queryUiUrl();
+    }
 }
diff --git 
a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java
index 94fa4c279dc7..9067785463f1 100644
--- 
a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java
@@ -28,7 +28,8 @@ import org.slf4j.LoggerFactory;
  */
 @InfraService(service = JaegerInfraService.class,
               description = "Jaeger is a distributed tracing backend with OTLP 
collector and UI",
-              serviceAlias = { "jaeger" })
+              serviceAlias = { "jaeger" },
+              uiSupported = true)
 public class JaegerLocalContainerInfraService implements JaegerInfraService, 
ContainerService<JaegerContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(JaegerLocalContainerInfraService.class);
 
diff --git 
a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java
 
b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java
index 80fc7143d1f8..bc1c190b0787 100644
--- 
a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java
+++ 
b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java
@@ -24,19 +24,27 @@ import 
org.apache.camel.test.infra.common.services.ContainerService;
 import org.apache.camel.test.infra.kafka.common.KafkaProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.Network;
 import org.testcontainers.kafka.KafkaContainer;
 import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = KafkaInfraService.class,
               description = "Apache Kafka, Distributed event streaming 
platform",
-              serviceAlias = "kafka")
+              serviceAlias = "kafka", uiSupported = true)
 public class ContainerLocalKafkaInfraService implements KafkaInfraService, 
ContainerService<KafkaContainer> {
     public static final String KAFKA_IMAGE_NAME = 
LocalPropertyResolver.getProperty(
             ContainerLocalKafkaInfraService.class,
             KafkaProperties.KAFKA_CONTAINER);
 
+    private static final String KAFKA_UI_CONTAINER_IMAGE = 
"kafka-ui.container.image";
+    private static final int KAFKA_UI_PORT = 9080;
+    private static final String KAFKA_NETWORK_ALIAS = "kafka-broker";
+
     private static final Logger LOG = 
LoggerFactory.getLogger(ContainerLocalKafkaInfraService.class);
     protected KafkaContainer kafka;
+    private GenericContainer<?> uiContainer;
+    private Network uiNetwork;
 
     public ContainerLocalKafkaInfraService() {
         kafka = initContainer();
@@ -55,6 +63,8 @@ public class ContainerLocalKafkaInfraService implements 
KafkaInfraService, Conta
     }
 
     protected KafkaContainer initContainer() {
+        boolean fixedPort = 
ContainerEnvironmentUtil.isFixedPort(this.getClass());
+
         class TestInfraKafkaContainer extends KafkaContainer {
             public TestInfraKafkaContainer(boolean fixedPort) {
                 
super(DockerImageName.parse(System.getProperty(KafkaProperties.KAFKA_CONTAINER, 
KAFKA_IMAGE_NAME))
@@ -64,7 +74,16 @@ public class ContainerLocalKafkaInfraService implements 
KafkaInfraService, Conta
             }
         }
 
-        return new 
TestInfraKafkaContainer(ContainerEnvironmentUtil.isFixedPort(this.getClass()));
+        KafkaContainer container = new TestInfraKafkaContainer(fixedPort);
+
+        if (ContainerEnvironmentUtil.isWithUi()) {
+            uiNetwork = Network.newNetwork();
+            container.withNetwork(uiNetwork)
+                    .withNetworkAliases(KAFKA_NETWORK_ALIAS)
+                    .withListener(KAFKA_NETWORK_ALIAS + ":19092");
+        }
+
+        return container;
     }
 
     public String getBootstrapServers() {
@@ -87,14 +106,50 @@ public class ContainerLocalKafkaInfraService implements 
KafkaInfraService, Conta
         registerProperties();
 
         LOG.info("Kafka bootstrap server running at address {}", 
kafka.getBootstrapServers());
+
+        if (ContainerEnvironmentUtil.isWithUi()) {
+            try {
+                startUiContainer();
+            } catch (Exception e) {
+                LOG.warn("Failed to start Kafka UI container: {}", 
e.getMessage(), e);
+            }
+        }
+    }
+
+    private void startUiContainer() {
+        String uiImage = LocalPropertyResolver.getProperty(
+                ContainerLocalKafkaInfraService.class, 
KAFKA_UI_CONTAINER_IMAGE);
+
+        uiContainer = new GenericContainer<>(uiImage)
+                .withNetwork(uiNetwork)
+                .withEnv("DYNAMIC_CONFIG_ENABLED", "true")
+                .withEnv("KAFKA_CLUSTERS_0_NAME", "camel-infra")
+                .withEnv("KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS", 
KAFKA_NETWORK_ALIAS + ":19092")
+                .withEnv("SERVER_PORT", String.valueOf(KAFKA_UI_PORT));
+        ContainerEnvironmentUtil.configurePort(uiContainer, true, 
KAFKA_UI_PORT);
+        uiContainer.start();
+
+        LOG.info("Kafka UI running at http://{}:{}";, uiContainer.getHost(), 
uiContainer.getMappedPort(KAFKA_UI_PORT));
     }
 
     @Override
     public void shutdown() {
+        if (uiContainer != null) {
+            LOG.info("Shutting down Kafka UI container");
+            uiContainer.stop();
+        }
         LOG.info("Shutting down Kafka container");
         kafka.stop();
     }
 
+    @Override
+    public String uiUrl() {
+        if (uiContainer != null && uiContainer.isRunning()) {
+            return String.format("http://%s:%d";, uiContainer.getHost(), 
uiContainer.getMappedPort(KAFKA_UI_PORT));
+        }
+        return null;
+    }
+
     @Override
     public KafkaContainer getContainer() {
         return kafka;
diff --git 
a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java
 
b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java
index 108982f57775..934cb23245e8 100644
--- 
a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java
+++ 
b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java
@@ -33,4 +33,7 @@ public interface KafkaInfraService extends 
InfrastructureService {
 
     String brokers();
 
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties
 
b/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties
index e83a87bb9981..0abfcfe8e75b 100644
--- 
a/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties
+++ 
b/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties
@@ -25,3 +25,4 @@ kafka.container.image.version.freeze.major=true
 redpanda.container.image.version.exclude=fips,amd64,arm64
 strimzi.container.image.version.freeze.major=true
 confluent.container.image.version.freeze.major=true
+kafka-ui.container.image=mirror.gcr.io/provectuslabs/kafka-ui:v0.7.2
diff --git 
a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
 
b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
index 3108955e5fd6..8d2e9240e105 100644
--- 
a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
+++ 
b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
@@ -58,4 +58,8 @@ public interface KeycloakInfraService extends 
InfrastructureService {
     default String password() {
         return getKeycloakPassword();
     }
+
+    default String uiUrl() {
+        return serverUrl() + "/admin";
+    }
 }
diff --git 
a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java
index 16a3ced4b56b..60abddf65c0a 100644
--- 
a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java
@@ -33,7 +33,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = KeycloakInfraService.class,
               description = "Keycloak is an open source identity and access 
management solution",
-              serviceAlias = { "keycloak" })
+              serviceAlias = { "keycloak" },
+              uiSupported = true)
 public class KeycloakLocalContainerInfraService implements 
KeycloakInfraService, ContainerService<GenericContainer<?>> {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(KeycloakLocalContainerInfraService.class);
diff --git 
a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
 
b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
index 2594ae1c475d..7ecdb6d32e3d 100644
--- 
a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
+++ 
b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
@@ -40,4 +40,8 @@ public interface MinioInfraService extends 
InfrastructureService {
     default String endpoint() {
         return String.format("http://%s:%d";, host(), port());
     }
+
+    default String uiUrl() {
+        return String.format("http://%s:%d";, host(), consolePort());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java
index 12a85538ff62..420006bc634f 100644
--- 
a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java
@@ -30,7 +30,8 @@ import 
org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
 
 @InfraService(service = MinioInfraService.class,
               description = "MinIO is a high-performance S3 compatible object 
storage",
-              serviceAlias = { "minio" })
+              serviceAlias = { "minio" },
+              uiSupported = true)
 public class MinioLocalContainerInfraService implements MinioInfraService, 
ContainerService<GenericContainer<?>> {
     public static final String CONTAINER_NAME = "minio";
     private static final String ACCESS_KEY = 
System.getProperty(MinioProperties.ACCESS_KEY, "testAccessKey");
diff --git 
a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
 
b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
index 392eaa2784aa..acf146e486de 100644
--- 
a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
+++ 
b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
@@ -40,4 +40,8 @@ public interface MongoDBInfraService extends 
InfrastructureService {
     default String hosts() {
         return getConnectionAddress();
     }
+
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java
index caa92fe76048..60ac12a916bf 100644
--- 
a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java
@@ -24,16 +24,22 @@ import 
org.apache.camel.test.infra.common.services.ContainerService;
 import org.apache.camel.test.infra.mongodb.common.MongoDBProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testcontainers.Testcontainers;
+import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.mongodb.MongoDBContainer;
 import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = MongoDBInfraService.class,
               description = "MongoDB is a document-oriented NoSQL database",
-              serviceAlias = { "mongodb" })
+              serviceAlias = { "mongodb" }, uiSupported = true)
 public class MongoDBLocalContainerInfraService implements MongoDBInfraService, 
ContainerService<MongoDBContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(MongoDBLocalContainerInfraService.class);
     private static final int DEFAULT_MONGODB_PORT = 27017;
+    private static final String MONGO_EXPRESS_CONTAINER_IMAGE = 
"mongo-express.container.image";
+    private static final int MONGO_EXPRESS_PORT = 8081;
+
     private final MongoDBContainer container;
+    private GenericContainer<?> uiContainer;
 
     public MongoDBLocalContainerInfraService() {
         
this(LocalPropertyResolver.getProperty(MongoDBLocalContainerInfraService.class, 
MongoDBProperties.MONGODB_CONTAINER));
@@ -87,14 +93,46 @@ public class MongoDBLocalContainerInfraService implements 
MongoDBInfraService, C
         container.start();
         registerProperties();
         LOG.info("MongoDB service running at {}", 
container.getReplicaSetUrl());
+
+        if (ContainerEnvironmentUtil.isWithUi()) {
+            try {
+                String uiImage = LocalPropertyResolver.getProperty(
+                        MongoDBLocalContainerInfraService.class, 
MONGO_EXPRESS_CONTAINER_IMAGE);
+                int mongoPort = 
ContainerEnvironmentUtil.getConfiguredPort(DEFAULT_MONGODB_PORT);
+                Testcontainers.exposeHostPorts(mongoPort);
+                uiContainer = new GenericContainer<>(uiImage)
+                        .withEnv("ME_CONFIG_MONGODB_URL",
+                                "mongodb://host.testcontainers.internal:" + 
mongoPort + "/?directConnection=true")
+                        .withEnv("ME_CONFIG_BASICAUTH", "false")
+                        .withAccessToHost(true);
+                ContainerEnvironmentUtil.configurePort(uiContainer, true, 
MONGO_EXPRESS_PORT);
+                uiContainer.start();
+                LOG.info("Mongo Express running at http://{}:{}";, 
uiContainer.getHost(),
+                        uiContainer.getMappedPort(MONGO_EXPRESS_PORT));
+            } catch (Exception e) {
+                LOG.warn("Failed to start Mongo Express UI container: {}", 
e.getMessage(), e);
+            }
+        }
     }
 
     @Override
     public void shutdown() {
+        if (uiContainer != null) {
+            LOG.info("Stopping the Mongo Express container");
+            uiContainer.stop();
+        }
         LOG.info("Stopping the MongoDB container");
         container.stop();
     }
 
+    @Override
+    public String uiUrl() {
+        if (uiContainer != null && uiContainer.isRunning()) {
+            return String.format("http://%s:%d";, uiContainer.getHost(), 
uiContainer.getMappedPort(MONGO_EXPRESS_PORT));
+        }
+        return null;
+    }
+
     @Override
     public MongoDBContainer getContainer() {
         return container;
diff --git 
a/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties
 
b/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties
index 1b8c67213bc6..773aea4f6ac9 100644
--- 
a/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties
+++ 
b/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties
@@ -19,3 +19,4 @@ 
mongodb.container.ppc64le=icr.io/ppc64le-oss/mongodb-ppc64le:4.4.24
 mongodb.container.version.include=jammy
 mongodb.container.ppc64le.version.exclude=bv
 mongodb.container.ppc64le.version.freeze.major=true
+mongo-express.container.image=mirror.gcr.io/library/mongo-express:1.0.2
diff --git 
a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java
 
b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java
index ece157e2ae0a..a0ed56cbba02 100644
--- 
a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java
+++ 
b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java
@@ -25,4 +25,8 @@ public interface Neo4jInfraService extends 
InfrastructureService {
     String getNeo4jDatabaseUser();
 
     String getNeo4jDatabasePassword();
+
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java
index fee77cd82061..f1901dd49766 100644
--- 
a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java
@@ -30,7 +30,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = Neo4jInfraService.class,
               description = "Neo4j is a graph database management system",
-              serviceAlias = { "neo4j" })
+              serviceAlias = { "neo4j" },
+              uiSupported = true)
 public class Neo4jLocalContainerInfraService implements Neo4jInfraService, 
ContainerService<Neo4jContainer> {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(Neo4jLocalContainerInfraService.class);
@@ -110,4 +111,9 @@ public class Neo4jLocalContainerInfraService implements 
Neo4jInfraService, Conta
     public String getNeo4jDatabasePassword() {
         return container.getAdminPassword();
     }
+
+    @Override
+    public String uiUrl() {
+        return String.format("http://%s:%d";, container.getHost(), 
container.getMappedPort(7474));
+    }
 }
diff --git 
a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java
 
b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java
index 1a06dfc8b359..b43715f081e8 100644
--- 
a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java
+++ 
b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java
@@ -32,4 +32,8 @@ public interface OpenSearchInfraService extends 
InfrastructureService {
     String getUsername();
 
     String getPassword();
+
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java
index 577ad23abbd3..3d1bfac1e93b 100644
--- 
a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java
@@ -19,6 +19,7 @@ package org.apache.camel.test.infra.opensearch.services;
 
 import java.time.Duration;
 
+import org.apache.camel.spi.annotations.InfraService;
 import org.apache.camel.test.infra.common.LocalPropertyResolver;
 import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil;
 import org.apache.camel.test.infra.common.services.ContainerService;
@@ -26,17 +27,27 @@ import 
org.apache.camel.test.infra.opensearch.common.OpenSearchProperties;
 import org.opensearch.testcontainers.OpensearchContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testcontainers.Testcontainers;
+import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.containers.output.Slf4jLogConsumer;
 import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
 import org.testcontainers.utility.DockerImageName;
 
+@InfraService(service = OpenSearchInfraService.class,
+              description = "OpenSearch is a distributed search and analytics 
engine",
+              serviceAlias = { "opensearch" }, uiSupported = true)
 public class OpenSearchLocalContainerInfraService implements 
OpenSearchInfraService, ContainerService<OpensearchContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(OpenSearchLocalContainerInfraService.class);
     private static final int OPEN_SEARCH_PORT = 9200;
     private static final String USER_NAME = "admin";
     // NOTE: default value used for testing purposes only.
     private static final String PASSWORD = "admin"; // NOSONAR
+
+    private static final String OPENSEARCH_DASHBOARDS_CONTAINER_IMAGE = 
"opensearch-dashboards.container.image";
+    private static final int OPENSEARCH_DASHBOARDS_PORT = 5601;
+
     private final OpensearchContainer container;
+    private GenericContainer<?> uiContainer;
 
     public OpenSearchLocalContainerInfraService() {
         
this(LocalPropertyResolver.getProperty(OpenSearchLocalContainerInfraService.class,
@@ -112,10 +123,39 @@ public class OpenSearchLocalContainerInfraService 
implements OpenSearchInfraServ
 
         registerProperties();
         LOG.info("OpenSearch instance running at {}", getHttpHostAddress());
+
+        if (ContainerEnvironmentUtil.isWithUi()) {
+            try {
+                startUiContainer();
+            } catch (Exception e) {
+                LOG.warn("Failed to start OpenSearch Dashboards UI container: 
{}", e.getMessage(), e);
+            }
+        }
+    }
+
+    private void startUiContainer() {
+        String uiImage = LocalPropertyResolver.getProperty(
+                OpenSearchLocalContainerInfraService.class, 
OPENSEARCH_DASHBOARDS_CONTAINER_IMAGE);
+        int opensearchPort = 
ContainerEnvironmentUtil.getConfiguredPort(OPEN_SEARCH_PORT);
+        Testcontainers.exposeHostPorts(opensearchPort);
+
+        uiContainer = new GenericContainer<>(uiImage)
+                .withEnv("OPENSEARCH_HOSTS", 
"[\"http://host.testcontainers.internal:"; + opensearchPort + "\"]")
+                .withEnv("DISABLE_SECURITY_DASHBOARDS_PLUGIN", "true")
+                .withAccessToHost(true);
+        ContainerEnvironmentUtil.configurePort(uiContainer, true, 
OPENSEARCH_DASHBOARDS_PORT);
+        uiContainer.start();
+
+        LOG.info("OpenSearch Dashboards running at http://{}:{}";,
+                uiContainer.getHost(), 
uiContainer.getMappedPort(OPENSEARCH_DASHBOARDS_PORT));
     }
 
     @Override
     public void shutdown() {
+        if (uiContainer != null) {
+            LOG.info("Shutting down OpenSearch Dashboards container");
+            uiContainer.stop();
+        }
         LOG.info("Stopping the OpenSearch container");
         container.stop();
     }
@@ -134,4 +174,13 @@ public class OpenSearchLocalContainerInfraService 
implements OpenSearchInfraServ
     public String getPassword() {
         return PASSWORD;
     }
+
+    @Override
+    public String uiUrl() {
+        if (uiContainer != null && uiContainer.isRunning()) {
+            return String.format("http://%s:%d";, uiContainer.getHost(),
+                    uiContainer.getMappedPort(OPENSEARCH_DASHBOARDS_PORT));
+        }
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties
 
b/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties
index fa19956c85a6..9c5f81f29a88 100644
--- 
a/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties
+++ 
b/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties
@@ -16,3 +16,4 @@
 ## ---------------------------------------------------------------------------
 opensearch.container=mirror.gcr.io/opensearchproject/opensearch:3.7.0
 opensearch.container.ppc64le=icr.io/ppc64le-oss/opensearch-ppc64le:3.3.0
+opensearch-dashboards.container.image=mirror.gcr.io/opensearchproject/opensearch-dashboards:3.7.0
diff --git 
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
 
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
index 4d6b5a313874..aef2ac36aa1d 100644
--- 
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
+++ 
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
@@ -64,4 +64,8 @@ public interface PostgresInfraService extends 
InfrastructureService {
         properties.put("camel.beans.postgresDS.password", password());
         return properties;
     }
+
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java
index cc09fcad11cd..b5733d95a498 100644
--- 
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java
@@ -25,20 +25,31 @@ import 
org.apache.camel.test.infra.common.services.ContainerService;
 import org.apache.camel.test.infra.postgres.common.PostgresProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testcontainers.Testcontainers;
+import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.images.builder.Transferable;
 import org.testcontainers.postgresql.PostgreSQLContainer;
 import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = PostgresInfraService.class,
               description = "PostgreSQL is an open source object-relational 
database",
-              serviceAlias = { "postgres" })
+              serviceAlias = { "postgres" }, uiSupported = true)
 public class PostgresLocalContainerInfraService implements 
PostgresInfraService, ContainerService<PostgreSQLContainer> {
 
     public static final String DEFAULT_POSTGRES_CONTAINER
             = 
LocalPropertyResolver.getProperty(PostgresLocalContainerInfraService.class,
                     PostgresProperties.POSTGRES_CONTAINER);
+
+    private static final String PGADMIN_CONTAINER_IMAGE = 
"pgadmin.container.image";
+    private static final int PGADMIN_PORT = 5050;
+    private static final String PGADMIN_EMAIL = "[email protected]";
+    // NOTE: default value used for local development only
+    private static final String PGADMIN_PASSWORD = "admin"; // NOSONAR
+
     private static final Logger LOG = 
LoggerFactory.getLogger(PostgresLocalContainerInfraService.class);
     private final PostgreSQLContainer container;
+    private GenericContainer<?> uiContainer;
 
     public PostgresLocalContainerInfraService() {
         this(DEFAULT_POSTGRES_CONTAINER);
@@ -96,10 +107,54 @@ public class PostgresLocalContainerInfraService implements 
PostgresInfraService,
 
         registerProperties();
         LOG.info("Postgres instance running at {}", getServiceAddress());
+
+        if (ContainerEnvironmentUtil.isWithUi()) {
+            try {
+                startUiContainer();
+            } catch (Exception e) {
+                LOG.warn("Failed to start pgAdmin UI container: {}", 
e.getMessage(), e);
+            }
+        }
+    }
+
+    private void startUiContainer() {
+        String uiImage = LocalPropertyResolver.getProperty(
+                PostgresLocalContainerInfraService.class, 
PGADMIN_CONTAINER_IMAGE);
+        int pgPort = ContainerEnvironmentUtil.getConfiguredPort(5432);
+        Testcontainers.exposeHostPorts(pgPort);
+
+        String serversJson = String.format(
+                
"{\"Servers\":{\"1\":{\"Name\":\"camel-infra\",\"Group\":\"Servers\","
+                                           + 
"\"Host\":\"host.testcontainers.internal\",\"Port\":%d,"
+                                           + 
"\"MaintenanceDB\":\"postgres\",\"Username\":\"%s\","
+                                           + 
"\"PassFile\":\"/tmp/pgpassfile\",\"SSLMode\":\"prefer\"}}}",
+                pgPort, container.getUsername());
+        String pgpassFile = String.format(
+                "host.testcontainers.internal:%d:postgres:%s:%s",
+                pgPort, container.getUsername(), container.getPassword());
+
+        uiContainer = new GenericContainer<>(uiImage)
+                .withEnv("PGADMIN_DEFAULT_EMAIL", PGADMIN_EMAIL)
+                .withEnv("PGADMIN_DEFAULT_PASSWORD", PGADMIN_PASSWORD)
+                .withEnv("PGADMIN_LISTEN_PORT", String.valueOf(PGADMIN_PORT))
+                .withEnv("PGADMIN_CONFIG_SERVER_MODE", "False")
+                .withEnv("PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED", "False")
+                .withCopyToContainer(Transferable.of(serversJson), 
"/pgadmin4/servers.json")
+                .withCopyToContainer(Transferable.of(pgpassFile, 0600), 
"/tmp/pgpassfile")
+                .withAccessToHost(true);
+        ContainerEnvironmentUtil.configurePort(uiContainer, true, 
PGADMIN_PORT);
+        uiContainer.start();
+
+        LOG.info("pgAdmin running at http://{}:{} (email: {}, password: {})",
+                uiContainer.getHost(), 
uiContainer.getMappedPort(PGADMIN_PORT), PGADMIN_EMAIL, PGADMIN_PASSWORD);
     }
 
     @Override
     public void shutdown() {
+        if (uiContainer != null) {
+            LOG.info("Shutting down pgAdmin container");
+            uiContainer.stop();
+        }
         LOG.info("Stopping the Postgres container");
         container.stop();
     }
@@ -133,4 +188,12 @@ public class PostgresLocalContainerInfraService implements 
PostgresInfraService,
     public String password() {
         return container.getPassword();
     }
+
+    @Override
+    public String uiUrl() {
+        if (uiContainer != null && uiContainer.isRunning()) {
+            return String.format("http://%s:%d";, uiContainer.getHost(), 
uiContainer.getMappedPort(PGADMIN_PORT));
+        }
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java
index 3ac2a518edc4..169604470f3e 100644
--- 
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java
@@ -22,7 +22,7 @@ import 
org.apache.camel.test.infra.postgres.common.PostgresProperties;
 
 @InfraService(service = PostgresInfraService.class,
               description = "PostgreSQL with pgvector extension for vector 
similarity search",
-              serviceAlias = { "postgres-vector", "pgvector" })
+              serviceAlias = { "postgres-vector", "pgvector" }, uiSupported = 
true)
 public class PostgresVectorLocalContainerInfraService extends 
PostgresLocalContainerInfraService {
 
     public static final String DEFAULT_POSTGRES_VECTOR_CONTAINER
diff --git 
a/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties
 
b/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties
index 23cf52bd9544..4445846efb37 100644
--- 
a/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties
+++ 
b/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties
@@ -18,3 +18,4 @@ postgres.container=mirror.gcr.io/postgres:17.10-alpine
 postgres.container.version.include=alpine
 postgres.container.version.freeze.major=true
 postgres.vector.container=mirror.gcr.io/pgvector/pgvector:pg18
+pgadmin.container.image=mirror.gcr.io/dpage/pgadmin4:9
diff --git 
a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
 
b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
index 7ffc6998d81a..2d54a24db794 100644
--- 
a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
+++ 
b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
@@ -51,6 +51,10 @@ public interface QdrantInfraService extends 
InfrastructureService {
         return "";
     }
 
+    default String uiUrl() {
+        return String.format("http://%s:%d/dashboard";, getHttpHost(), 
getHttpPort());
+    }
+
     default HttpResponse<byte[]> put(String path, Map<Object, Object> body) 
throws Exception {
         final String reqPath = !path.startsWith("/") ? "/" + path : path;
         final String reqUrl = String.format("http://%s:%d%s";, getHttpHost(), 
getHttpPort(), reqPath);
diff --git 
a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java
index 08605b8f43d1..2bfa142e730c 100644
--- 
a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java
@@ -29,7 +29,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = QdrantInfraService.class,
               description = "Qdrant is a vector similarity search engine and 
database",
-              serviceAlias = { "qdrant" })
+              serviceAlias = { "qdrant" },
+              uiSupported = true)
 public class QdrantLocalContainerInfraService implements QdrantInfraService, 
ContainerService<QdrantContainer> {
     public static final int HTTP_PORT = 6333;
     public static final int GRPC_PORT = 6334;
diff --git 
a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
 
b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
index 8c3682211964..24e828942f23 100644
--- 
a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
+++ 
b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
@@ -89,4 +89,8 @@ public interface RabbitMQInfraService extends 
InfrastructureService {
     default String brokerUrl() {
         return String.format("amqp://%s:%d", hostname(), port());
     }
+
+    default String uiUrl() {
+        return managementUri();
+    }
 }
diff --git 
a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java
index 2aa1e46271ff..704110fe1235 100644
--- 
a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java
@@ -29,7 +29,8 @@ import org.testcontainers.utility.DockerImageName;
 
 @InfraService(service = RabbitMQInfraService.class,
               description = "RabbitMQ is an open source message and streaming 
broker",
-              serviceAlias = { "rabbitmq" })
+              serviceAlias = { "rabbitmq" },
+              uiSupported = true)
 public class RabbitMQLocalContainerInfraService implements 
RabbitMQInfraService, ContainerService<RabbitMQContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(RabbitMQLocalContainerInfraService.class);
 
diff --git 
a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
 
b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
index 0d7635248d90..9ad9dd05dada 100644
--- 
a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
+++ 
b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
@@ -35,4 +35,8 @@ public interface RedisInfraService extends 
InfrastructureService {
     default String endpointUri() {
         return String.format("spring-redis:%s:%d", host(), port());
     }
+
+    default String uiUrl() {
+        return null;
+    }
 }
diff --git 
a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java
index 56ab2aaf4190..5daa00327321 100644
--- 
a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java
@@ -17,19 +17,25 @@
 package org.apache.camel.test.infra.redis.services;
 
 import org.apache.camel.spi.annotations.InfraService;
+import org.apache.camel.test.infra.common.LocalPropertyResolver;
 import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil;
 import org.apache.camel.test.infra.common.services.ContainerService;
 import org.apache.camel.test.infra.redis.common.RedisProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.testcontainers.Testcontainers;
+import org.testcontainers.containers.GenericContainer;
 
 @InfraService(service = RedisInfraService.class,
               description = "Redis is an open source in-memory data store",
-              serviceAlias = { "redis" })
+              serviceAlias = { "redis" }, uiSupported = true)
 public class RedisLocalContainerInfraService implements RedisInfraService, 
ContainerService<RedisContainer> {
     private static final Logger LOG = 
LoggerFactory.getLogger(RedisLocalContainerInfraService.class);
+    private static final String REDIS_COMMANDER_CONTAINER_IMAGE = 
"redis-commander.container.image";
+    private static final int REDIS_COMMANDER_PORT = 8082;
 
     private final RedisContainer container;
+    private GenericContainer<?> uiContainer;
 
     public RedisLocalContainerInfraService() {
         container = initContainer();
@@ -71,14 +77,45 @@ public class RedisLocalContainerInfraService implements 
RedisInfraService, Conta
 
         registerProperties();
         LOG.info("Redis instance running at {}", getServiceAddress());
+
+        if (ContainerEnvironmentUtil.isWithUi()) {
+            try {
+                String uiImage = LocalPropertyResolver.getProperty(
+                        RedisLocalContainerInfraService.class, 
REDIS_COMMANDER_CONTAINER_IMAGE);
+                int redisPort = 
ContainerEnvironmentUtil.getConfiguredPort(RedisProperties.DEFAULT_PORT);
+                Testcontainers.exposeHostPorts(redisPort);
+                uiContainer = new GenericContainer<>(uiImage)
+                        .withEnv("REDIS_HOSTS", 
"local:host.testcontainers.internal:" + redisPort)
+                        .withEnv("PORT", String.valueOf(REDIS_COMMANDER_PORT))
+                        .withAccessToHost(true);
+                ContainerEnvironmentUtil.configurePort(uiContainer, true, 
REDIS_COMMANDER_PORT);
+                uiContainer.start();
+                LOG.info("Redis Commander running at http://{}:{}";, 
uiContainer.getHost(),
+                        uiContainer.getMappedPort(REDIS_COMMANDER_PORT));
+            } catch (Exception e) {
+                LOG.warn("Failed to start Redis Commander UI container: {}", 
e.getMessage(), e);
+            }
+        }
     }
 
     @Override
     public void shutdown() {
+        if (uiContainer != null) {
+            LOG.info("Stopping the Redis Commander container");
+            uiContainer.stop();
+        }
         LOG.info("Stopping the Redis container");
         container.stop();
     }
 
+    @Override
+    public String uiUrl() {
+        if (uiContainer != null && uiContainer.isRunning()) {
+            return String.format("http://%s:%d";, uiContainer.getHost(), 
uiContainer.getMappedPort(REDIS_COMMANDER_PORT));
+        }
+        return null;
+    }
+
     @Override
     public RedisContainer getContainer() {
         return container;
diff --git 
a/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties
 
b/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties
index f2bf442ee54e..fe31a258527d 100644
--- 
a/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties
+++ 
b/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties
@@ -18,3 +18,4 @@ redis.container=mirror.gcr.io/redis:7.4.9-alpine
 redis.container.version.include=alpine
 redis.container.version.exclude=rc,beta
 redis.container.version.freeze.major=true
+redis-commander.container.image=ghcr.io/joeferner/redis-commander:0.9.1
diff --git 
a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
 
b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
index 5f5d8c79b42c..1fac820bbba8 100644
--- 
a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
+++ 
b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
@@ -39,4 +39,8 @@ public interface SolrInfraService extends 
InfrastructureService {
     default int port() {
         return getPort();
     }
+
+    default String uiUrl() {
+        return String.format("http://%s:%d/solr";, host(), port());
+    }
 }
diff --git 
a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java
index 1abd2e3141ae..70105cc8cee8 100644
--- 
a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java
@@ -25,7 +25,8 @@ import org.slf4j.LoggerFactory;
 
 @InfraService(service = SolrInfraService.class,
               description = "Apache Solr is an open source search platform",
-              serviceAlias = { "solr" })
+              serviceAlias = { "solr" },
+              uiSupported = true)
 public class SolrLocalContainerInfraService implements SolrInfraService, 
ContainerService<SolrContainer> {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(SolrLocalContainerInfraService.class);
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java
index 5332a0dcd18b..27181414c377 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java
@@ -119,6 +119,8 @@ public class CamelTestInfraGenerateMetadataMojo extends 
AbstractGeneratorMojo {
                     infrastructureServiceModel.setDescription(av.asString());
                 } else if (av.name().equals("serviceVersion")) {
                     annotationServiceVersion = av.asString();
+                } else if (av.name().equals("uiSupported")) {
+                    infrastructureServiceModel.setUiSupported(av.asBoolean());
                 }
             }
 
@@ -378,6 +380,7 @@ public class CamelTestInfraGenerateMetadataMojo extends 
AbstractGeneratorMojo {
         private String artifactId;
         private String version;
         private String serviceVersion;
+        private boolean uiSupported;
 
         public String getService() {
             return service;
@@ -450,5 +453,13 @@ public class CamelTestInfraGenerateMetadataMojo extends 
AbstractGeneratorMojo {
         public void setServiceVersion(String serviceVersion) {
             this.serviceVersion = serviceVersion;
         }
+
+        public boolean isUiSupported() {
+            return uiSupported;
+        }
+
+        public void setUiSupported(boolean uiSupported) {
+            this.uiSupported = uiSupported;
+        }
     }
 }
diff --git 
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java
 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java
index fb6051e05581..e4ef026135a7 100644
--- 
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java
+++ 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java
@@ -81,4 +81,13 @@ public @interface InfraService {
      * @return
      */
     String serviceVersion() default "";
+
+    /**
+     * Whether this service supports a web UI (built-in or via companion 
container).
+     *
+     * When true, the service interface should provide a {@code uiUrl()} 
method that returns the UI URL when available.
+     *
+     * @return true if the service has UI support
+     */
+    boolean uiSupported() default false;
 }


Reply via email to