Zero Config Database configuration with Quarkus (DevServices)

Quarkus 1.13 ships with a new feature called “DevServices” which allows testing or running in dev mode Quarkus without an actual database configuration. Basically, all you need to do is including the extension in your pom.xml file and Quarkus will set up the playground for you. No need to start or configure a database!

Let’s see an example. The Hibernate ORM example has been modified for this purpose: https://github.com/quarkusio/quarkus-quickstarts/tree/main/hibernate-orm-quickstart

If you check the application.properties, you will see that a configuration has been added only for the production profile:

%prod.quarkus.datasource.db-kind=postgresql
%prod.quarkus.datasource.username=quarkus_test
%prod.quarkus.datasource.password=quarkus_test
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/quarkus_test
%prod.quarkus.datasource.jdbc.max-size=8
%prod.quarkus.datasource.jdbc.min-size=2

quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.log.sql=true
quarkus.hibernate-orm.sql-load-script=import.sql

Within the pom.xml, Quarkus will find PostgreSQL extension so that will be used:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>

In order to use the DevServices feature you need to start the Docker service so that the container image of the Database is pulled and started with the required settings. The only exception is H2 Database which will run as In-Process application. Besides it, DB2 and MSSQL require you to include a license acceptance file named src/main/resources/container-license-acceptance.txt in your project.

An example file is shown below:

ibmcom/db2:11.5.0.0a
mcr.microsoft.com/mssql/server:2017-CU12

Enough talking. Let’s see this feature in action. First we start the Docker daemon:

$ service docker start

Now you can run/test the application as follows:

$ mvn install quarkus:dev

The Test Phase will kick-in, then the application is launched:

2021-05-09 19:10:02,999 INFO  [org.tes.doc.DockerClientProviderStrategy] (build-13) Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2021-05-09 19:10:03,000 INFO  [org.tes.DockerClientFactory] (build-13) Docker host IP address is localhost
2021-05-09 19:10:03,023 INFO  [org.tes.DockerClientFactory] (build-13) Connected to docker: 
  Server Version: 1.13.1
  API Version: 1.26
  Operating System: Fedora 29 (Workstation Edition)
  Total Memory: 31542 MB
2021-05-09 19:10:03,025 INFO  [org.tes.uti.ImageNameSubstitutor] (build-13) Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
2021-05-09 19:10:03,796 INFO  [org.tes.DockerClientFactory] (build-13) Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
2021-05-09 19:10:03,796 INFO  [org.tes.DockerClientFactory] (build-13) Checking the system...
2021-05-09 19:10:03,796 INFO  [org.tes.DockerClientFactory] (build-13) ✔︎ Docker server version should be at least 1.6.0
2021-05-09 19:10:03,995 INFO  [org.tes.DockerClientFactory] (build-13) ✔︎ Docker environment should have more than 2GB free disk space
2021-05-09 19:10:04,013 INFO  [🐳 .2]] (build-13) Creating container for image: postgres:13.2
2021-05-09 19:10:04,090 INFO  [🐳 .2]] (build-13) Starting container with ID: 620cd106ce403136bc6e8de84b0cca691f17c421a15315582bcb6a977c878d40
2021-05-09 19:10:04,500 INFO  [🐳 .2]] (build-13) Container postgres:13.2 is starting: 620cd106ce403136bc6e8de84b0cca691f17c421a15315582bcb6a977c878d40
2021-05-09 19:10:06,285 INFO  [🐳 .2]] (build-13) Container postgres:13.2 started in PT2.289385S
Hibernate: 
    
    drop table if exists known_fruits cascade
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2021-05-09 19:10:07,241 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (Quarkus Main Thread) SQL Warning Code: 0, SQLState: 00000
2021-05-09 19:10:07,242 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (Quarkus Main Thread) table "known_fruits" does not exist, skipping
Hibernate: 
    
    drop sequence if exists known_fruits_id_seq
2021-05-09 19:10:07,242 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (Quarkus Main Thread) SQL Warning Code: 0, SQLState: 00000
2021-05-09 19:10:07,243 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (Quarkus Main Thread) sequence "known_fruits_id_seq" does not exist, skipping
Hibernate: create sequence known_fruits_id_seq start 10 increment 1
Hibernate: 
    
    create table known_fruits (
       id int4 not null,
        name varchar(40),
        primary key (id)
    )
Hibernate: 
    
    alter table if exists known_fruits 
       add constraint UK_57g3m8wr3qxoj706a6hsqg6ye unique (name)
Hibernate: 
    INSERT INTO known_fruits(id, name) VALUES (1, 'Cherry')
Hibernate: 
    INSERT INTO known_fruits(id, name) VALUES (2, 'Apple')
Hibernate: 
    INSERT INTO known_fruits(id, name) VALUES (3, 'Banana')
2021-05-09 19:10:07,510 INFO  [io.quarkus] (Quarkus Main Thread) hibernate-orm-quickstart 1.0.0-SNAPSHOT on JVM (powered by Quarkus 1.13.3.Final) started in 5.610s. Listening on: http://localhost:8080
2021-05-09 19:10:07,512 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-05-09 19:10:07,512 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, jdbc-postgresql, mutiny, narayana-jta, resteasy, resteasy-jackson, s

As you can see, the PostgreSQL image has been

$ docker images

REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE
docker.io/postgres              13.2                26c8bcd8b719        4 weeks ago         314 MB

We have just covered a new amazing Quarkus feature that greatly simplifies testing and developing database applications.

Found the article helpful? if so please follow us on Socials