Arconia Dev Services
Arconia Dev Services streamline your development workflow by automatically provisioning external services your application depends on during development and testing. No manual setup is required.
Need a database, message broker, or other infrastructure components for your application? Add the corresponding Dev Service dependency to your project. When you run your application or tests, the required services start automatically as OCI containers and are seamlessly wired into your application. Zero additional code or configuration needed.
Built on Testcontainers and Spring Boot’s Testcontainers support, Arconia Dev Services provide a great developer experience by eliminating the friction of manually setting up and managing services in your development environment.
|
Dev Services are designed exclusively for development and testing workflows. Declared as development/test-only dependencies, they are excluded from production builds and have zero impact on your production deployments. |
How It Works
When Arconia Dev Services are detected while the application is running in dev or test mode, the framework:
-
Starts the container: Launches an OCI container for the required service using Testcontainers.
-
Configures the connection: Sets up connection properties (URLs, credentials, ports).
-
Wires the service: Integrates the service into your application context using Spring Boot’s Service Connection mechanism.
-
Manages the lifecycle: Handles container startup, shutdown, and cleanup.
This happens transparently without requiring any code or configuration. Dev Services take precedence over manually configured properties, ensuring your application always connects to the containerized service during development and testing.
Quick Start
Get started with Arconia Dev Services in three simple steps:
-
Add the dependency for your required service (e.g., PostgreSQL):
-
Gradle
-
Maven
dependencies { testAndDevelopmentOnly 'io.arconia:arconia-dev-services-postgresql' }<dependency> <groupId>io.arconia</groupId> <artifactId>arconia-dev-services-postgresql</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> -
-
Run your application as usual:
-
Gradle
-
Maven
-
CLI
./gradlew bootRun./mvnw spring-boot:runarconia dev -
-
That’s it! The PostgreSQL container starts automatically, and your application connects to it. No configuration files, no code changes needed.
|
Want to verify which Dev Services are running? When running the application in dev mode with Spring Boot Actuator in your classpath, check the |
Using Dev Services
Dev Services are available as separate modules for each supported service. You can find the complete list in the Supported Services section below.
Dev Services providing the same capability (e.g. JDBC databases) are mutually exclusive: if more than one is active at the same time, the application fails at startup with a clear error message pointing at the conflict.
Service Connections
Your application is automatically configured to connect to Dev Services, which take precedence over manually configured properties. For example, when using the arconia-dev-services-postgresql module, the Dev Service transparently overrides properties like spring.datasource.url, spring.datasource.username, and spring.datasource.password.
The auto-configuration mechanism uses Spring Boot’s Service Connections internally to establish connections between your application and containerized services, eliminating the need for manual property configuration or test-specific setup code.
If your application defines its own ConnectionDetails bean of the type a Dev Service provides (for example, a JdbcConnectionDetails bean), the application connects to the service of your choice: the Dev Service is not started, and a message says so at startup.
SSL with Dev Services
Some Dev Services can serve SSL, so that the SSL support of your application is developed and tested against them, the way SSL with Service Connections allows with plain Spring Boot and Testcontainers. This covers two situations:
-
The application connects to the real service over SSL, in production, and you want dev and test to exercise the same path. For example, an application whose Redis is only reachable over SSL in production connects to the Redis Dev Service over SSL as well, so that its SSL client setup is covered by its tests.
-
The service only accepts SSL connections, as Elasticsearch does in its default configuration, so the application has no other way to reach it.
The support builds on Spring Boot’s and goes one step further: Spring Boot configures the application side, and Arconia configures the container as well. The connection uses SSL in one direction: the Dev Service presents a certificate, and the application verifies it. The application presents no certificate of its own, and the Dev Service doesn’t ask for one.
SSL is configured through the ssl properties of the Dev Service, which describe its SSL bundle with the keys of a Spring Boot SSL bundle, in PEM form (ssl.pem) or as a Java keystore (ssl.jks). The bundle has the meaning of the bundle a Spring Boot server is configured with: its key store holds the certificate and private key the Dev Service presents. There is nothing to configure on the application side: the application trusts the certificate chain the Dev Service presents, with the protocol and options of the bundle, through the Spring Boot service connection of the Dev Service.
arconia:
dev:
services:
redis:
ssl:
enabled: true
pem:
keystore:
certificate: "classpath:certs/redis.crt"
private-key: "classpath:certs/redis.key"
Certificates and keys are read as for any Spring Boot SSL bundle: from a classpath: or file: location, as inline PEM content, or as base64: content. Whatever form they are configured in, each Dev Service gets them in the form its service expects. The ssl.pem and ssl.jks properties take the keystore, key, options, and protocol keys of a spring.ssl.bundle definition, with the same names and meaning. A trust store is not part of them, since the Dev Service never asks the application for a certificate. When ssl.enabled is false, the other ssl properties have no effect.
Certificate Requirements
The clients verify the host name of the Dev Service against its certificate, so the certificate must be valid for the host the application connects to: localhost and 127.0.0.1 with a local container runtime, the host of the container runtime otherwise, and the name of the Dev Service and its network-aliases when the application reaches it over the shared network. A certificate for local development can be generated with OpenSSL, for example:
openssl req -x509 -newkey rsa:2048 -nodes -days 365 \
-keyout redis.key -out redis.crt -subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1,DNS:redis"
The private key must be readable by Arconia, which copies it into the container unencrypted, where the service reads it. Certificates and keys for development are not secrets, but keep them out of the resources packaged for production anyway.
The bundle the application connects to the Dev Service with, which trusts the certificate the Dev Service presents, is registered in the SslBundles of the application under the name dev-services-<service-name>, so Spring Boot tooling reports it as any other bundle: the SSL information of the info actuator endpoint, when enabled, lists the trusted certificate chain, and the devservices endpoint reports it for the Dev Service (see Actuator). The dev-services- prefix is reserved for these bundles. The startup message of the Dev Service says SSL is enabled (see Startup Feedback).
The container is configured for SSL right after the common properties are applied and before your DevServiceContainerCustomizer beans run, so a customizer replacing the command or the configuration of the container must preserve the SSL part. A container kept across a Spring Boot DevTools restart keeps the SSL configuration it was started with, like the rest of its configuration: stop and start the application after changing the ssl properties (see Lifecycle Management).
The following Dev Services support SSL: Elasticsearch, Kafka, MongoDB, RabbitMQ, and Redis. The Elasticsearch Dev Service also works with the certificate Elasticsearch generates itself, with no certificate configured at all.
|
A Dev Service with SSL enabled and running in a container started by another application (see Reusing Dev Services) is connected to with the bundle built from the properties of this application: the applications sharing a Dev Service must configure the same |
Lifecycle Management
Arconia instructs Spring Boot to manage the lifecycle of Dev Services as beans in the application context:
-
Startup: Services start when the application context initializes.
-
Shutdown: Services stop when the application stops.
-
Persistence: Services remain available throughout the lifecycle of your application or tests.
When using Spring Boot DevTools in dev mode, Dev Services are not recreated on restart. They remain running in the background until the application process exits, ensuring a smooth development experience without wait times or state loss.
Since the container is kept, changes to the configuration of a Dev Service take effect once you stop and start the application again. The only container replaced on restart is one that is no longer running, for example, because it was removed manually.
A Dev Service can also use a container that is already running instead of starting a new one, which changes when the container is stopped. See Reusing Dev Services.
Dev Services in Test Mode
In test mode, every test application context starts its own containers and stops them when it closes, to ensure test isolation, consistency, and reliability. The features that keep or share containers are only available in dev mode: the reuse strategies, the persistence across Spring Boot DevTools restarts, and the devservices actuator endpoint.
Configuration Options
Each Dev Service can be customized through Spring Boot configuration properties. All Dev Services support a common set of properties under the arconia.dev.services.<service-name> prefix.
Common Properties
The following properties are available for all Dev Services.
|
All Dev Services are enabled by default. Other properties have sensible defaults that may vary by service. |
| Property | Description |
|---|---|
|
Whether the dev service is enabled. |
|
Full name of the container image used in the dev service. |
|
Environment variables to set in the service. |
|
Additional hostnames the dev service container is reachable by on the shared network, next to the name of the dev service. Only applicable when the shared network is enabled. |
|
Fixed port for exposing the primary service port to the host. When it’s 0 (default), a random available port is assigned dynamically. |
|
Resources from the classpath or host filesystem to copy into the container. They can be files or directories that will be copied to the specified destination path inside the container at startup and are immutable (read-only). |
|
Strategy for reusing a running container for the dev service across applications or restarts. Only applicable in dev mode. |
|
Maximum waiting time for the service to start, counted from the container start. |
|
Files or directories to mount from the host filesystem into the container. They are mounted at the specified destination path inside the container at startup and are mutable (read-write). Changes in either the host or the container will be immediately reflected in the other. |
Programmatic Customization
Configuration properties cover the most common scenarios. When you need full control over a container (for example, a custom wait strategy, a startup check strategy, extra labels, or additional commands), you can define a DevServiceContainerCustomizer<T> bean. Every customizer is applied to any Dev Service container that is an instance of its generic type T, right after the container is created and before it is started.
For example, to customize the wait strategy of the PostgreSQL Dev Service (using org.testcontainers.postgresql.PostgreSQLContainer):
@Configuration(proxyBeanMethods = false)
public class DevServicesConfiguration {
@Bean
DevServiceContainerCustomizer<PostgreSQLContainer> postgresCustomizer() {
return container -> container.waitingFor(Wait.forListeningPort()
.withStartupTimeout(Duration.ofMinutes(1)));
}
}
A wait strategy set by a customizer replaces the one the Dev Service configured, including the startup-timeout property applied to it. Set the timeout on the new strategy, as in the example above.
A customizer typed on a common supertype (e.g. GenericContainer<?>) applies to all Dev Service containers. When multiple customizers match the same container, they are applied following the semantics of the @Order annotation and Ordered interface.
|
Customizers reference classes from the Dev Services and Testcontainers dependencies, which are not present in production builds. Define them in a configuration class that is only included at development and test time, consistently with how you scoped the Dev Service dependency itself. |
Reusing Dev Services
An application can start its own container for a Dev Service and stop it on shutdown, or use a container that is already running instead of starting a new one. The arconia.dev.services.<service-name>.reuse-strategy property decides which. It accepts three values.
| Value | Behavior | Container Lifetime | Setup |
|---|---|---|---|
|
Arconia looks for a running container that provides the same Dev Service, started by another application, and connects to it. If none is found, the application starts its own container, which other applications can discover in turn. |
Stopped when the application that started it stops. |
None. |
|
The container is kept running across application runs, relying on the Reusable Containers feature of Testcontainers. The application connects to an existing container only if it was created with the same configuration. |
Never stopped automatically: you are in charge of cleaning up. |
You enable the feature on your machine. |
|
A new container is always started. |
Stopped when the application stops. |
None. |
The default depends on the Dev Service. It is framework for services that several applications typically use together, such as message brokers, identity providers, observability platforms, and resource-intensive services, and none for the others, such as databases. Each Dev Service page lists its default.
The two reuse strategies are mutually exclusive. A container kept running by Testcontainers is never discovered through the framework strategy, and the other way around.
|
Reuse is only applicable in dev mode (see Dev Services in Test Mode). |
Framework Strategy
The framework strategy lets multiple applications running simultaneously during development use the same containerized service instead of starting one container each. This is particularly useful for:
-
Distributed systems: Share a message broker (e.g., RabbitMQ, Kafka) or observability platform (e.g. Grafana LGTM) across multiple services.
-
Resource efficiency: Avoid running duplicate containers for the same service, especially for resource-intensive services (e.g., Docling, Ollama).
It works out of the box, with no additional setup required. Every Dev Service container is labeled, and the application first looks for a running container that already provides the same Dev Service. If one is found, the application connects to it instead of starting a new container. Otherwise, the application starts its own container, which other applications can discover in turn.
The application that started the container owns its lifecycle: the container is stopped when that application stops. Applications that were connected to it lose access to the service at that point. The next time they start, they look for a running container again and start their own if none is found.
A discovered container is used as it runs, with the configuration of the application that started it. Application-specific customization (environment variables, resources, image name, DevServiceContainerCustomizer beans) doesn’t apply to containers started by other applications. The application connects with its own configured settings, so any credentials must be the same across the applications using the service. For databases, that includes the username, the password, and the database name. If an application needs its own differently-configured service instance, set arconia.dev.services.<service-name>.reuse-strategy=none for that service.
When using Spring Boot DevTools, an application that started a container keeps using it across restarts, even if another application has started a container for the same Dev Service in the meantime.
The framework strategy is supported by all the Dev Services, whether or not it is their default. When it cannot be applied (see the Ollama Dev Service for the one such case), the startup message says so.
Testcontainers Strategy
The testcontainers strategy keeps a Dev Service container running across application runs. It relies on the Reusable Containers feature of Testcontainers, which is disabled by default: with this strategy, you explicitly opt into the feature and take charge of the containers it keeps. To enable it, create or edit the file ~/.testcontainers.properties in your home directory and add the following line:
testcontainers.reuse.enable=true
Alternatively, set the TESTCONTAINERS_REUSE_ENABLE environment variable to true, which is convenient on CI machines.
Once enabled, Dev Services using this strategy persist across application runs. When the feature is not enabled, the container is started and stopped with the application as usual, and the startup message says so.
Testcontainers identifies a reusable container by its configuration. Changing the configuration of the Dev Service (for example, its image, environment variables, or credentials) results in a new container being started, while the previous one keeps running. Arconia never stops a container kept by this strategy.
|
Reusable containers are never removed automatically. You are in charge of stopping and removing them with your container runtime (Docker/Podman) when they are no longer required (see Finding and Cleaning Up Containers). |
Finding and Cleaning Up Containers
The startup message of each Dev Service reports the container it runs in, and the reuse strategy in effect (see Startup Feedback). Every Dev Service container also carries the io.arconia.dev-service.name label, holding the name of the Dev Service, so you can list the containers with your container runtime:
docker ps --filter label=io.arconia.dev-service.name
docker ps --filter label=io.arconia.dev-service.name=rabbitmq
To stop and remove all the Dev Service containers left running, including the ones kept by the testcontainers strategy:
docker rm -f $(docker ps -q --filter label=io.arconia.dev-service.name)
Resource Mappings
Dev Services support copying files and directories from your classpath or host filesystem into the container at startup. This can be useful for various scenarios, including for loading configuration files, seeding initialization data, or making static resources available to containerized services.
Resources are copied to the specified destination path inside the container at startup and are never changed on the host after being copied (read-only). This means that any modifications made by the container to these files will not persist or affect the source files on the host.
This strategy is preferred over mounting host directories as volumes, as it avoids potential issues with file permission mismatches, path resolution, and cross-platform compatibility.
Configuration
Resource mappings are configured through the arconia.dev.services.<service-name>.resources property. Each mapping requires two values:
-
Source path: Location of the resource on the classpath or filesystem;
-
Container path: Destination path inside the container.
For example, to copy a configuration file from the classpath into an OpenTelemetry Collector container:
arconia:
dev:
services:
otel-collector:
resources:
- source-path: otel-collector-config.yml
container-path: /etc/otelcol-contrib/config.yaml
Source Path Resolution
The source path supports multiple resolution strategies:
-
Automatic resolution: Without a prefix, Arconia first attempts to locate the resource on the classpath. If not found, it searches the filesystem. For example,
config/database.confwill be resolved from the classpath if available, otherwise from the filesystem. -
Explicit classpath: Use the
classpath:prefix to load resources from the classpath. For example,classpath:config/database.conf. -
Explicit filesystem: Use the
file:prefix to load resources from the host filesystem. For example,file:./config/database.conf.
Using explicit prefixes (classpath: or file:) improves clarity and readability, making it clear where the resource is being loaded from. It also avoids ambiguity and potential resolution issues, especially in complex projects with multiple resource locations.
|
Volume Mappings
Dev Services support binding files and directories from the host filesystem into the container at startup. This can be useful for various scenarios, including for persisting data generated by the containerized service or for sharing files between your host and the container.
Files or directories specified in the volume mappings are mounted from the host filesystem into the container at the specified destination path inside the container at startup and are mutable (read-write). Changes in either the host or the container will be immediately reflected in the other.
Since this provides direct read-write access between the host and container, use this feature with caution. Ensure that the mounted paths are secure and do not expose sensitive data or system files. Furthermore, be aware of potential file permission issues that may arise due to differences between the host and container environments.
|
It’s recommended to use volume mappings only when necessary. Instead, consider using resource mappings for most use cases where read-only access is sufficient. |
Configuration
Volume mappings are configured through the arconia.dev.services.<service-name>.volumes property. Each mapping requires two values:
-
Host path: Location of the file or directory on the host filesystem;
-
Container path: Destination path inside the container.
For example, to mount a configuration directory from the host filesystem into a PostgreSQL container:
arconia:
dev:
services:
postgresql:
volumes:
- host-path: ./postgresql/data
container-path: /var/lib/postgresql/data/pgdata
Networks and Ports
By default, Dev Service containers are connected to the default network of your container runtime (Docker/Podman) and are accessible from your application via the local host and dynamically assigned ports.
Fixed Ports
By default, Dev Services use random available ports to avoid conflicts. However, you can configure fixed exposed ports when needed. Each service supports the arconia.dev.services.<service-name>.port property to specify a fixed port for exposing the primary service provided by the container.
Some Dev Services may expose multiple ports (e.g., management console ports). In such cases, the Dev Service will offer additional properties to configure fixed ports for those secondary services. For example, the RabbitMQ Dev Service provides the common arconia.dev.services.rabbitmq.port property for the main AMQP port and an additional arconia.dev.services.rabbitmq.management-console-port property for the management UI port.
A common use case for fixed ports is when other tools or services in your development environment need to connect to the Dev Service container using a known port, or for exposing UI consoles through well-known ports. For example, to expose Grafana on port 3000.
|
Using fixed ports may cause conflicts if another service is already using the port. Consider using fixed ports only when necessary. |
Shared Network
This is an advanced, opt-in feature. Most applications never need it: your application always reaches Dev Services over the local host and mapped ports, with no configuration.
Dev Service containers cannot, by default, reach each other by name. When you need container-to-container communication, for example, letting a Docling Dev Service send telemetry to a Grafana LGTM Dev Service, enable the shared network globally with the arconia.dev.services.network.enabled property (disabled by default). When enabled, all Dev Service containers join a common OCI network and are reachable by their service name, so you only need to point the consumer at the target’s service name and internal port:
arconia:
dev:
services:
network:
enabled: true (1)
docling:
environment:
OTEL_EXPORTER_OTLP_ENDPOINT: http://lgtm:4317 (2)
DOCLING_SERVE_OTEL_ENABLE_TRACES: "true"
DOCLING_SERVE_OTEL_ENABLE_OTLP_METRICS: "true"
| 1 | A single global switch attaches every Dev Service container to the shared network. |
| 2 | The lgtm hostname is the target’s service name, which every container on the shared network is reachable by, and 4317 is the container’s internal OTLP/gRPC port, not the host-mapped port. To reach a container by other hostnames as well, set its network-aliases property. |
Advanced Scenarios
-
Container reuse. The shared network doesn’t combine with the
testcontainersreuse strategy: the network is created anew with every run, and since the Testcontainers reuse hash includes it, a container kept by that strategy would never be matched again and would be left running after every run. When the shared network is enabled, the strategy is therefore not applied, and the startup message of the Dev Service says so. Use one or the other. -
Your own containers. The network is exposed as an injectable Testcontainers
Networkbean. To let a container you manage yourself reach Dev Services, enable the shared network, inject the bean, and attach your container:
@Bean
GenericContainer<?> daprContainer(Network devServicesNetwork) {
return new GenericContainer<>("daprio/daprd:latest")
.withNetwork(devServicesNetwork)
.withNetworkAliases("dapr");
}
A user-defined Network bean takes precedence over the one Arconia provides.
Startup Sequence
Control how Dev Services start using the spring.testcontainers.beans.startup property. It can be set to parallel or sequential. By default, Dev Services are started sequentially.
Startup Feedback
When a Dev Service is ready, Arconia logs a consistent startup message: one line about the container the Dev Service runs in, and one line with its links, such as management consoles and telemetry endpoints, when it has any:
...i.a.d.s.startup : Dev Service 'lgtm' is ready in container 3f2a9c1d7b4e (grafana/otel-lgtm, reuse-strategy: framework)
...i.a.d.s.startup : Dev Service 'lgtm' links: Grafana: http://localhost:32895, OTLP/HTTP: http://localhost:32896, OTLP/gRPC: http://localhost:32897, Prometheus: http://localhost:32898, Tempo MCP: http://localhost:32899/api/mcp
The first line states the container image, whether the container was started by another application (see Reusing Dev Services) or kept across a Spring Boot DevTools restart, in dev mode, the reuse strategy in effect, and whether SSL is enabled for the Dev Service (ssl). When the configured strategy could not be applied, the reason follows it in parentheses, for example, because the Testcontainers reusable containers feature is not enabled on your machine:
...i.a.d.s.startup : Dev Service 'lgtm' is ready in container 3f2a9c1d7b4e (grafana/otel-lgtm, started by another application, reuse-strategy: framework)
...i.a.d.s.startup : Dev Service 'postgresql' is ready in container 9b1c4e7a2d60 (postgres, kept across restart, reuse-strategy: none)
...i.a.d.s.startup : Dev Service 'redis' is ready in container 5e8d2b7f0c13 (redis, reuse-strategy: none, ssl)
The links are declared by each Dev Service and resolved against the container it runs in, whether the application started it or discovered it. The same information is available programmatically through the devservices actuator endpoint (see Actuator), for each service under a links list of label and url. For services with no HTTP interface, the endpoint also reports the host ports the container publishes, which is what you need to connect to them from a tool on your machine.
The messages are written by the io.arconia.dev.services.startup logger. Testcontainers logs its own progress (connecting to the container runtime, pulling images, starting containers) at info level as well. To keep only the Arconia messages, set logging.level.org.testcontainers=WARN and logging.level.tc=WARN.
When a container fails to start, Testcontainers writes the container’s logs to the application log at error level.
Ahead-of-Time Processing and Native Images
Dev Services are a dev and test time feature. Spring AOT processing and native images imply the prod mode, in which Dev Services are not active at all.
In AOT-processed tests (spring.aot.enabled=true), Dev Services are excluded from the generated code and are not available: their beans are created at startup from the state of the container runtime, which cannot be decided ahead of time. This is the same limitation Spring Boot has for @ServiceConnection on @Bean methods, @ImportTestcontainers, and Docker Compose in AOT-processed tests. Run tests that rely on Dev Services without AOT.
Global Configuration
In case you want to disable all Dev Services at once, you can set the arconia.dev.services.enabled property to false.
The arconia.dev.services.network.enabled property (default false) turns on the shared network: when enabled, all Dev Service containers join a common OCI network so they can reach each other by name (see Shared Network).
|
Disabling Dev Services globally overrides individual service settings. If global disabling is set, no Dev Services will start, regardless of their individual |
Supported Services
Is the service you need not in the list? You can build your own Dev Service.
Actuator
When running the application in dev mode, a devservices actuator endpoint is auto-configured if Spring Boot Actuator is present in the classpath. This endpoint exposes information about the running Dev Services containers, helping you inspect and debug your development environment.
By default, Spring Boot exposes only the health endpoint over HTTP. To access the devservices endpoint, include it in the web exposure configuration:
management:
endpoints:
web:
exposure:
include: devservices
Usage
List All Dev Services
Retrieve information about all running Dev Services:
http :8080/actuator/devservices
Response example:
{
"docling": {
"name": "docling",
"description": "Docling Dev Service",
"origin": "MANAGED",
"links": [
{
"label": "Docling UI",
"url": "http://localhost:45525/ui"
},
{
"label": "Docling OpenAPI",
"url": "http://localhost:45525/docs"
}
],
"containerInfo": {
"id": "dbbda8272b5dc8d2ccfa48d3723756d767eef727322d9c35e0fd4c44ba60e967",
"imageName": "ghcr.io/docling-project/docling-serve:latest",
"names": [
"vigilant_hopper"
],
"ports": [
{
"ip": "0.0.0.0",
"privatePort": 5001,
"publicPort": 45525,
"type": "tcp"
}
],
"labels": {
"io.arconia.dev-service.name": "docling",
"io.arconia.dev-service.discoverable": "true",
"io.arconia.dev-service.owner": "6f1c2a0e-3b8d-4c5e-9a7f-2d1e0c9b8a76",
"org.testcontainers.lang": "java",
"org.testcontainers": "true"
},
"state": "running",
"status": "Up About 67 minutes"
},
"ssl": null
},
"postgresql": {
"name": "postgresql",
"description": "PostgreSQL Dev Service",
"origin": "MANAGED",
"links": [],
"containerInfo": {
"id": "cbf5a15cf5420eddd2daf0e912256b140c0ad067f9329f425a2ecdaa01008bc5",
"imageName": "docker.io/pgvector/pgvector:latest",
"names": [
"unwritten_mithrandir"
],
"ports": [
{
"ip": "0.0.0.0",
"privatePort": 5432,
"publicPort": 36803,
"type": "tcp"
}
],
"labels": {
"io.arconia.dev-service.name": "postgresql",
"org.testcontainers.lang": "java",
"org.testcontainers": "true"
},
"state": "running",
"status": "Up About 67 minutes"
},
"ssl": null
}
}
Dev Services are listed in the order they were registered.
Get Details for a Specific Dev Service
Retrieve detailed information about a specific Dev Service:
http :8080/actuator/devservices/postgresql
Response example:
{
"name": "postgresql",
"description": "PostgreSQL Dev Service",
"origin": "MANAGED",
"links": [],
"containerInfo": {
"id": "cbf5a15cf5420eddd2daf0e912256b140c0ad067f9329f425a2ecdaa01008bc5",
"imageName": "docker.io/pgvector/pgvector:latest",
"names": [
"unwritten_mithrandir"
],
"ports": [
{
"ip": "0.0.0.0",
"privatePort": 5432,
"publicPort": 36803,
"type": "tcp"
}
],
"labels": {
"io.arconia.dev-service.name": "postgresql",
"org.testcontainers.lang": "java",
"org.testcontainers": "true"
},
"state": "running",
"status": "Up About 67 minutes"
},
"ssl": null
}
The endpoint provides visibility into container IDs, image names, port mappings, and other runtime information useful for troubleshooting and debugging. The containerInfo field is null when the container can no longer be inspected, for example, because it was removed manually or the container runtime is not reachable.
The state field is the lifecycle state of the container as defined by the Docker Engine API (created, running, paused, restarting, removing, exited, or dead), suitable for programmatic checks. The status field is the human-readable description the container runtime provides for that state, such as Up About 67 minutes or Exited (0) 2 minutes ago.
The links field lists the links the Dev Service exposes, such as management consoles (see Startup Feedback). A Dev Service that other applications can discover also carries the io.arconia.dev-service.discoverable and io.arconia.dev-service.owner labels.
The origin field indicates whether the Dev Service runs in a container managed by this application (MANAGED) or in a container started by another application and discovered by this one (DISCOVERED).
The ssl field reports the SSL bundle the application connects to a Dev Service with SSL enabled with (see SSL with Dev Services), in the form Spring Boot reports bundles in the info endpoint: the name the bundle is registered under, and, as its trust store certificate chains, the certificate chain of the Dev Service with the subject, issuer, validity period, and validity status of each certificate. It is null for a Dev Service without SSL, and for one using the certificate its container generates, which has no bundle of its own.
"ssl": {
"name": "dev-services-redis",
"certificateChains": [],
"trustStoreCertificateChains": [
{
"alias": "ssl-0",
"certificates": [
{
"subject": "CN=localhost,O=Acme",
"version": "V3",
"issuer": "CN=Acme Development CA,O=Acme",
"validityStarts": "2026-10-11T20:57:12Z",
"validityEnds": "2126-09-17T20:57:12Z",
"serialNumber": "4f8a1c2e9b7d6a5f3e2c1b0a9f8e7d6c5b4a3f2e",
"signatureAlgorithmName": "SHA256withRSA",
"validity": {
"status": "VALID",
"message": null
}
}
]
}
]
}
Arconia Dev Services vs. Spring Boot Development-time Services
Arconia Dev Services is a higher-level abstraction built on top of Spring Boot’s Testcontainers support. While both approaches leverage Testcontainers for provisioning services, Arconia Dev Services provides a more streamlined, zero-configuration experience.
Key Differences
The primary distinction is simplicity. Arconia Dev Services eliminates boilerplate code and configuration, allowing you to focus on development rather than infrastructure setup.
-
Arconia Dev Services
-
Spring Boot Development-time Services
dependencies {
testAndDevelopmentOnly 'io.arconia:arconia-dev-services-postgresql'
}
Run your application normally:
./gradlew bootRun
dependencies {
testAndDevelopmentOnly 'org.springframework.boot:spring-boot-testcontainers'
testAndDevelopmentOnly 'org.testcontainers:postgresql'
}
Create a test configuration class:
@TestConfiguration(proxyBeanMethods = false)
public class TestContainersConfiguration {
@Bean
@ServiceConnection
@RestartScope
PostgreSQLContainer postgresContainer() {
return new PostgreSQLContainer("postgres:latest");
}
}
Create a test main class:
public class TestApplication {
public static void main(String[] args) {
SpringApplication.from(Application::main)
.with(TestContainersConfiguration.class)
.run(args);
}
}
Run from the test classpath:
./gradlew bootTestRun
Import the Testcontainers configuration in each test class needing the service:
@SpringBootTest
@Import(TestContainersConfiguration.class)
class ApplicationTests {
}
Migration Path
If your project already uses Spring Boot’s Testcontainers support, you can adopt Arconia Dev Services incrementally:
-
Add Arconia dependencies for services you want to manage automatically.
-
Keep existing Testcontainers configuration for custom or unsupported services.
-
Gradually migrate more services to Arconia as needed.
Both approaches work alongside each other, allowing smooth transitions without disrupting your workflow.
|
Coexistence is per service. When your application defines its own |
Feature Comparison
| Aspect | Arconia Dev Services | Spring Boot Development-time Services |
|---|---|---|
Dependencies |
Single dependency per service. |
Multiple dependencies per service. |
Code Requirements |
Zero additional code required |
Requires: |
Configuration |
Declarative via |
Programmatic configuration in Java code when defining container beans. |
Application Startup |
Standard commands: |
Special test classpath commands: |
Integration Testing |
Automatic service discovery and wiring: no imports or annotations needed. |
Requires explicit |
DevTools Live Restart |
Automatic persistence across restarts in dev mode: containers survive application reloads. |
Requires |
Container Reuse |
Declarative via properties: |
Manual configuration when defining container beans with |
Customization |
Configuration properties for common scenarios. |
Full programmatic control. Direct access to Testcontainers API in bean definitions. |
SSL |
Declarative via properties, with the keys of a Spring Boot SSL bundle: |
Application side only, via the |
Flexibility |
Opinionated with sensible defaults. Configuration properties are available for common use cases. |
Maximum flexibility. Full control over container lifecycle and configuration. |
Learning Curve |
Minimal |
Moderate |
Best For |
Rapid development, standard use cases, cloud native and microservices, teams seeking simplicity. |
Advanced scenarios requiring custom container configuration or specialized setups |