Introducing Dev Services for Spring Boot using Arconia
Enhance the Spring Boot developer experience with Arconia: zero-code and zero-config infrastructure provisioning. Add one dependency. That's it!

Have you ever felt the pain of setting up local infrastructure for a Spring Boot application? Perhaps you've struggled with configuring a PostgreSQL database, an OpenTelemetry collector, or even an AI inference service like Ollama. Whether you're using Docker Compose or Testcontainers for defining the external services your application depends on, the process can involve a lot of boilerplate code, manual configuration, and changes to your development workflow.
Before you can even start coding the business logic, you might find yourself spending time with preliminary tasks that detract from your productivity. If you bootstrap new applications often, you'll have to repeat these steps each time, risking being trapped in a cycle of copying and pasting boilerplate code from one project to another. And if you're just getting started with Spring Boot, all this setup can feel even more overwhelming.
Wouldn't it be great if you could just add a dependency to your application project and have everything work out of the box? That's exactly what Arconia Dev Services bring to the table.
In this article, I'll present the main features of Arconia Dev Services and how they can transform your local development experience. Then, I'll walk you through how to use Arconia Dev Services to provide a PostgreSQL database when running a Spring Boot application with Spring Data JDBC and Flyway. You'll see how easy it is to get started without any boilerplate code or extra configuration.
What is Arconia?
Arconia is an open-source framework that acts as an add-on for Spring Boot. I created Arconia to enhance the development of modern enterprise applications with Java. You can add Arconia to an existing Spring Boot application to boost developer experience, reduce boilerplate, and seamlessly adopt cloud native patterns.
Some of the key features Arconia aims to provide include:
- Developer Experience. Introducing first-class support for development and testing modes in Spring Boot applications for making local development and testing easier, more productive, and more fun. This includes features like Dev Services, a solution pioneered by Quarkus to handle the automatic provisioning of external services using containers.
- Generative AI. Extending integration capabilities for Spring Boot applications to include AI observability and evaluation platforms, AI inference services, and AI document processors.
- Kubernetes. Simplifying the configuration and deployment of Spring Boot applications to Kubernetes, including the build of multi-architecture container images, support for the Service Binding specification, and automatic generation of Kubernetes manifests.
- Multitenancy. Offering built-in support for multitenant applications, including web, data, security, and configuration aspects.
- Observability. Providing unified observability for Spring Boot applications, combining full support for OpenTelemetry API, SDK, and Instrumentation with full support for Micrometer API and Instrumentation. Currently, using OpenTelemetry in Spring Boot is not straightforward. The goal is to provide a single, unified observability solution for Spring Boot applications that can give you the best of both worlds: the standardization and ubiquity of OpenTelemetry combined with the robustness and stability of Micrometer.
The framework is currently in active development and working towards the first stable release planned for early 2026. Many of the core features are already available, including Arconia Dev Services.
Why Arconia Dev Services?
Let's face it: wiring up local infrastructure is tedious and time-consuming. You often have to write a lot of boilerplate code and configuration to get everything working. This can lead to frustration, especially when you're trying to focus on building features rather than setting up infrastructure.
Arconia Dev Services solve this by providing automatic, containerized services for development and testing. Here's the beauty of it: add a single dependency, and you get a fully managed instance of your desired service spun up for you: no configuration, no code changes, no headaches.
This behaviour should feel familiar since it's how Spring Boot auto-configuration works. You add a dependency, and Spring Boot configures everything for you. Arconia Dev Services extend this concept to external services, making it incredibly easy to get started.
Arconia Dev Services leverage Testcontainers under the hood, but with a twist. Instead of requiring you to write boilerplate code to define and manage containers, Arconia detects what services your application needs based on the dependencies you include. It then automatically starts and configures those services when you run your application or tests. That's made possible by building on top of Spring Boot's support for development-time services with Testcontainers, responsible for managing the lifecycle of containers as beans, and determining the connection details.
Dev Services work seamlessly with your existing development workflow. There's no need to change how you run your applications or tests. Once you add the appropriate Arconia Dev Service dependency, you can focus on building features while Arconia handles the plumbing.
At this point, you might be wondering how Arconia Dev Services compare to Spring Boot's native Testcontainers support. I'll get to it in a moment, but first, let's have a look at a practical example.
Arconia Dev Services for PostgreSQL
Let's build a practical example to demonstrate how Arconia Dev Services can simplify your local development experience. We'll create a simple Spring Boot application that uses Spring Data JDBC to interact with a PostgreSQL database, with Flyway managing our database migrations.
The complete source code for this example is available on GitHub.
1. Project Setup
Start by creating a new Spring Boot project. You can use the Spring Initializr or set it up manually. From the Spring Initializr, choose the following options: Spring Web, Spring Data JDBC, PostgreSQL, and Flyway.
For this example, I'll use Gradle and Java 25. Here's how the dependencies section of your build.gradle
file should look:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-database-postgresql'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
That's a standard Spring Boot setup for an application of this type. Now, on top of that, we add the Arconia Dev Service for PostgreSQL. You could specify the version directly in the dependency declaration, but I recommend using a BOM to manage versions consistently across your project:
dependencies {
testAndDevelopmentOnly 'io.arconia:arconia-dev-services-postgresql'
}
dependencyManagement {
imports {
mavenBom "io.arconia:arconia-bom:0.17.1"
}
}
testAndDevelopmentOnly
scope for the Arconia Dev Service dependency. This ensures the service is only available during development and testing, and is completely excluded from production builds: exactly what you want for a development tool.You can optionally add the Spring Boot DevTools dependency for live-restart support during development:
dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
Here's where it gets interesting: when DevTools is present, Arconia keeps the PostgreSQL container running between code changes so you don't have to wait for it to restart every time. This makes the development experience much smoother.
2. Define the Domain Model
Let's create a simple Book
record that represents our core domain:
record Book(@Id Long id, String title) {}
Spring Data JDBC encourages the use of immutable data classes, and Java records are a perfect fit for that. The @Id
annotation marks the primary key field.
3. Create the Repository
Spring Data offers a repository abstraction that makes data access straightforward. Here's how to define a repository for our Book
entity:
interface BookRepository extends ListCrudRepository<Book, Long> {}
As you can see, there's no database-specific code here. Spring Data JDBC handles the SQL generation and mapping automatically, while Arconia ensures there's a database ready to connect to.
4. Implement the REST Controller
Now let's expose the book data through a simple HTTP API:
@RestController
@RequestMapping("/books")
class BookController {
private final BookRepository bookRepository;
BookController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
@GetMapping
List<Book> getBooks() {
return bookRepository.findAll();
}
@PostMapping
Book createBook(@RequestBody Book book) {
return bookRepository.save(book);
}
@GetMapping("/{id}")
Optional<Book> getBookById(@PathVariable("id") Long id) {
return bookRepository.findById(id);
}
}
This controller provides endpoints to create and retrieve books. The data persistence is delegated to the BookRepository
, which interacts with the PostgreSQL database.
5. Database Schema with Flyway
In a real application, you would typically use a tool like Flyway to manage your database schema.
Create a Flyway migration file (src/main/resources/db/migration/V1__Create_book_table.sql
) to set up your database schema:
CREATE TABLE book (
id BIGSERIAL PRIMARY KEY NOT NULL,
title VARCHAR(255) NOT NULL
);
Each migration represents a discrete change to your database schema and is controlled through versioned SQL scripts. By default, the naming convention for Flyway migration files is V<version>__<description>.sql
. Spring Boot auto-configures Flyway to run these migrations on application startup. If the migrations have already been applied, Flyway will skip them.
6. Run the Application
It's time to see everything in action. Fire up your app using the standard Spring Boot command for Gradle:
./gradlew bootRun
Or, if you prefer using the Arconia CLI:
arconia dev
When you run the application, you'll notice several things happening in the logs:
- Arconia detects the application is running in development mode and activates the dev profile.
- Arconia automatically starts a PostgreSQL container using Testcontainers that will keep running as long as your application is running. If you have Spring Boot DevTools enabled, the services will keep running even across code changes, so you don't have to wait for it to restart every time.
- Spring Boot detects the PostgreSQL container and configures a
DataSource
to connect to it automatically. That means you don't need to configure explicitly thespring.datasource.url
,spring.datasource.username
, andspring.datasource.password
properties. - Flyway runs the migration scripts to set up the database schema.
- Finally, your application starts up and is ready to handle requests.
By default, Arconia will provision a PostgreSQL container using the postgres
image from Docker Hub with the default username, password, and database name all set to test
. You can customize these settings through application properties if needed, but for most development scenarios, the defaults work perfectly.
Arconia also lets you define SQL scripts for Testcontainers to run when the database starts, which is useful for initialization tasks only needed during development or testing. You can find all the configuration options in the PostgreSQL Dev Service documentation.
7. Call the Application
Let's verify the application is working as expected. For this example, I'll use httpie, a command-line HTTP client that makes it easy to interact with HTTP APIs.
First, create a new book:
http :8080/books title="The Hitchhiker's Guide to the Galaxy"
Then, retrieve the list of books:
http :8080/books
Finally, get a specific book by its ID:
http GET :8080/books/1
You should see your data being persisted correctly in the PostgreSQL database and retrieved through the API.
8. Integration Testing
Let's not forget about testing. Integration tests are crucial for ensuring your application works correctly with the database. Arconia ensures that the Dev Services are available during tests as well, all without any extra configuration.
As an example, here's a simple integration test for our application:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class ApplicationTests {
@Autowired
private WebTestClient webTestClient;
@Test
void createBook() {
webTestClient
.post()
.uri("/books")
.bodyValue(new Book(null, "The Decameron"))
.exchange()
.expectStatus().isOk()
.expectBody(Book.class)
.value(book -> {
assertThat(book.id()).isNotNull();
assertThat(book.title()).isEqualTo("The Decameron");
});
}
}
Under the hood, Arconia will start a PostgreSQL container for the test context, and Spring Boot will configure the datasource to connect to it. Once the tests complete, the container will be automatically stopped and removed.
You can run the tests using Gradle:
./gradlew test
Or with the Arconia CLI:
arconia test
Arconia vs. Spring Boot Development-time Services
Spring Boot 3.1 introduced native support for Testcontainers, including the ability to automatically start containers for databases and other services during development and testing. You might be wondering how Arconia Dev Services compare to this built-in functionality.
Let's consider the example above with PostgreSQL and imagine we remove the Arconia Dev Service dependency and instead rely solely on Spring Boot's native support. First, you would need to add these dependencies to the project:
dependencies {
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:postgresql'
}
Notice how the dependencies are included to the testImplementation
scope, meaning that the feature will only be available in test mode.
If using Spring Boot DevTools, you would need to change the scope of the dependency from developmentOnly
to testAndDevelopmentOnly
:
dependencies {
testAndDevelopmentOnly 'org.springframework.boot:spring-boot-devtools'
}
Next, you would create a test application class in the test classpath (e.g., src/test/java/com/example/demo/TestApplication.java
) with a main
method that bootstraps the main application class (the one with the @SpringBootApplication
annotation) and activates the TestcontainersConfiguration
class:
public class TestApplication {
public static void main(String[] args) {
SpringApplication.from(Application::main)
.with(TestcontainersConfiguration.class)
.run(args);
}
}
Then, you would need to create a configuration class (e.g., src/test/java/com/example/demo/TestcontainersConfiguration.java
) that defines a bean for the PostgreSQL container and marks it with the @ServiceConnection
annotation. Optionally, if you're using Spring Boot DevTools, you would also need to add the @RestartScope
annotation to support live restart:
@TestConfiguration(proxyBeanMethods = false)
class TestcontainersConfiguration {
@Bean
@RestartScope
@ServiceConnection
PostgreSQLContainer<?> postgresContainer() {
return new PostgreSQLContainer<>(DockerImageName.parse("postgres:latest"));
}
}
If you want the PostgreSQL container to be provisioned when running a certain integration test, you would need to annotate the test class with @Import
to import the configuration class containing the container bean definition:
@SpringBootTest
@Import(TestcontainersConfiguration.class)
class DemoApplicationTests {
...
}
Finally, you would need to change your development workflow. Instead of running the application from the main class, you would need to run it from the test application class you created earlier. This is necessary to ensure that the TestcontainersConfiguration
class is activated and the PostgreSQL container is started, since the Testcontainers support is only active in the test classpath.
So, instead of running the application with the standard command (./gradlew bootRun
or ./mvnw spring-boot:run
), you would need to run it using a special command that runs the Spring Boot application from the test classpath:
./gradlew bootTestRun
Or with Maven:
./mvnw spring-boot:test-run
If you're running the application from an IDE, you would need to create a separate run configuration that runs the TestApplication
class instead of the main application class. IntelliJ IDEA and Visual Studio Code both detect the main
method in the test classpath, but it's not the default run configuration. So you would need to select it explicitly when running the application.
You can think of Arconia Dev Services as a higher-level feature built on top of Spring Boot's Testcontainers support for development-time services. It abstracts away all the boilerplate code and configuration required to set up and manage containers, aiming at providing the most seamless developer experience possible when working with Spring Boot applications.
I hope the Spring Boot project will eventually offer a similar experience to Arconia Dev Services natively. Until then, Arconia Dev Services can fill that gap and provide a more streamlined experience for developers. I have suggested this feature to the Spring Boot team. If you're interested in seeing it implemented, please upvote the feature request on GitHub.
Conclusion
In this article, I introduced you to Arconia Dev Services and demonstrated how they can enhance the developer experience by automatically provisioning and managing local infrastructure for Spring Boot applications. The key takeaway is that you can now add a single dependency to your project and have everything work out of the box, without any boilerplate code or configuration. Furthermore, you don't need to change your development workflow or how you run your applications and tests.
If your projects are already using Spring Boot development-time services with Docker Compose or Testcontainers, you can adopt Arconia Dev Services incrementally as they can co-exist in the same application. You can start by adding the Arconia Dev Service dependencies for the services you want to manage automatically, while keeping your existing Docker Compose or Testcontainers setup for any other services or custom configurations. Over time, you can migrate more services to be managed by Arconia Dev Services as needed.
Currently, Arconia offers Dev Services for data stores (MariaDB, MongoDB, MongoDB Atlas, MySQL, Oracle, Oracle XE, PostgreSQL, Redis), event brokers (Artemis, Kafka, RabbitMQ), Docling, Grafana LGTM/OpenTelemetry, Ollama, Phoenix. More services are planned for the future. You can find the complete list of available services in the Arconia Dev Services documentation.
Stay tuned for more articles about Arconia and its features. In the coming weeks, I'll publish more tutorials and deep dives into other aspects of the framework, such as the observability features with OpenTelemetry, multitenancy patterns, and AI document processing with Docling.
Are you using Arconia Dev Services? What's your current experience with setting up local infrastructure for Spring Boot applications? I'd love to hear from you! Share your experience on Bluesky or LinkedIn. And if you'd like to contribute to the Arconia framework, feel free to reach out on our Github project!
Cover picture from Pexels.