Edit this Page

Dev Services for Databases

When testing or running in dev mode Quarkus can provide you with a zero-config database out of the box, a feature we refer to as Dev Services. Depending on your database type you may need Docker installed in order to use this feature. Dev Services is supported for the following databases:

  • DB2 (container) (requires license acceptance)

  • Derby (in-process)

  • H2 (in-process)

  • MariaDB (container)

  • Microsoft SQL Server (container) (requires license acceptance)

  • MySQL (container)

  • Oracle Express Edition (container)

  • PostgreSQL (container)

If you want to use Dev Services then all you need to do is include the relevant extension for the type of database you want (either reactive or JDBC, or both). Don’t configure a database URL, username and password - Quarkus will provide the database and you can just start coding without worrying about config.

Production databases need to be configured as normal, so if you want to include a production database config in your application.properties and continue to use Dev Services we recommend that you use the %prod. profile to define your database settings.

Enabling / Disabling Dev Services for Database

Dev Services for databases automatically starts a database server in dev mode and when running tests. So, you don’t have to start a server manually. The application is configured automatically.

You can disable the automatic database start in application.properties via:

quarkus.devservices.enabled=false
# OR
quarkus.datasource.devservices.enabled=false

Dev Services for databases relies on Docker to start the server (except for H2 and Derby which are run in process). If your environment does not support Docker, you will need to start the server manually, or connect to an already running server.

Proprietary Databases - License Acceptance

If you are using a proprietary database such as DB2 or MSSQL you will need to accept the license agreement. To do this create a src/main/resources/container-license-acceptance.txt files in your project and add a line with the image name and tag of the database. By default, Quarkus uses the default image for the current version of Testcontainers, if you attempt to start Quarkus the resulting failure will tell you the exact image name in use for you to add to the file.

An example file is shown below:

src/main/resources/container-license-acceptance.txt
ibmcom/db2:11.5.0.0a
mcr.microsoft.com/mssql/server:2022-latest

Capturing Logs

By default, logs of the underlying database are not exposed. By capturing the logs, they become visible amongst other log statements:

quarkus.datasource.devservices.show-logs=true

Reusing Dev Services

General case

Within a dev mode session or test suite execution, Quarkus will always reuse database Dev Services as long as their configuration (username, password, environment, port bindings, …​) did not change.

When the configuration of any database Dev Services changes, Quarkus will always restart all database Dev Services.

When a dev mode session or test suite execution ends, Quarkus will (by default) stop all database Dev Services.

Reusing Dev Service containers across runs

Assuming you rely on Dev Services based on containers (unlike H2 or Derby), if you want to keep Dev Service containers running after a dev mode session or test suite execution to reuse them in the next dev mode session or test suite execution, this is possible as well. Just enable TestContainers reuse by inserting this line in one of your TestContainers configuration file (generally ~/.testcontainers.properties or C:/Users/myuser/.testcontainers.properties):

testcontainers.reuse.enable=true

Even with container reuse enabled, containers will only be reused if their startup command did not change: same environment variables (username/password in particular), same port bindings, same volume mounts, …​

Reusing containers implies reusing their internal state, including the database schema and the content of tables.

If that’s not what you want — and if your tests write to the database, that’s probably not what you want — consider configuring Hibernate ORM appropriately, or using Flyway or Liquibase.

With container reuse enabled, old containers (especially with obsolete configuration) might be left running indefinitely, even after starting a new Quarkus dev mode session or test suite execution.

In that case, you will need to stop and remove these containers manually.

If you want to reuse containers for some Quarkus applications but not all of them, or some Dev Services but not all of them, you can disable this feature for a specific Dev Service by setting the configuration property quarkus.datasource.devservices.reuse/quarkus.datasource."datasource-name".devservices.reuse to false.

Mapping volumes into Dev Services for Database

Mapping volumes from the Docker host’s filesystem to the containers is handy to provide files like scripts or configuration, but also to preserve database data and reuse it after an application restart.

Mapping volumes will only work in Dev Services with a container-based database like PostgreSQL.

Dev Services volumes can be mapped to the filesystem or the classpath:

# Using a filesystem volume:
quarkus.datasource.devservices.volumes."/path/from"=/container/to (1)
# Using a classpath volume:
quarkus.datasource.devservices.volumes."classpath:./file"=/container/to (2)
1 The file or folder "/path/from" from the local machine will be accessible at "/container/to" in the container.
2 When using classpath volumes, the location has to start with "classpath:". The file or folder "./file" from the project’s classpath will be accessible at "/container/to" in the container.
when using a classpath volume, the container will only be granted read permission. On the other hand, when using a filesystem volume, the container will be granted read and write permission.

Example of mapping volumes to persist the database data

Let’s see an example using PostgreSQL where we’ll map a file system volume to keep the database data permantently and use it:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.devservices.volumes."/local/test/data"=/var/lib/postgresql/data

The appropriate in-container location varies depending on the database vendor. For PostgreSQL is "/var/lib/postgresql/data", but for MySQL, you would need this configuration instead:

quarkus.datasource.db-kind=mysql
quarkus.datasource.devservices.volumes."/local/test/data"=/var/lib/mysql

When starting Dev Services (for example, in tests or in dev mode), you will see that the folder "/local/test/data" will be created at your file sytem and that will contain all the database data. When rerunning again the same Dev Services, this data will contain all the data you might have created beforehand.

When using Dev Services with Hibernate ORM, by default Quarkus will wipe out the database on application startup, which will wipe out the database data on your Docker host’s filesystem. Configure quarkus.hibernate-orm.database.generation=none or quarkus.hibernate-orm.database.generation=validate to avoid this behavior.

Also, using Flyway to migrate your schema when starting the application will modify the database data on your Docker hosts’s file system.

Database Vendor Specific Configuration

All services based on containers are run using Testcontainers but Quarkus is not using the Testcontainers JDBC driver. Thus, even though extra JDBC URL properties can be set in your application.properties file, specific properties supported by the Testcontainers JDBC driver such as TC_INITSCRIPT, TC_INITFUNCTION, TC_DAEMON, TC_TMPFS are not supported.

Quarkus can support specific properties sent to the container itself though, e.g. this is the case for TC_MY_CNF which allows to override the MariaDB/MySQL configuration file.

Overriding the MariaDB/MySQL configuration would be done as follows:

quarkus.datasource.devservices.container-properties.TC_MY_CNF=testcontainers/mysql-conf

This support is database specific and needs to be implemented in each Dev Service specifically.

Connect To Database Run as a Dev Service

You can connect to a database running as a Dev Service as you would do with any database running inside a Docker container.

Login credentials are the same for most databases, except when the database requirements don’t allow it:

Database Username Password Database name

PostgreSQL, MariaDB, MySQL, IBM Db2, H2

quarkus for the default datasource or name of the datasource

quarkus

quarkus

Microsoft SQL Server

SA

Quarkus123

The Microsoft SQL Server Testcontainer doesn’t support defining the username or database name. It also requires a strong password.

For databases supporting it (i.e. all of them except Microsoft SQL Server for which it is only possible to override the password), you can override the database name, username and password used by the Dev Service.

See Configuration Reference for more information.

Keep in mind that, except if configured otherwise (see below), a Dev Service runs on a random port. For instance, when you run PostgreSQL as a Dev Service and have psql installed on the host, you can connect via:

psql -h localhost -p <random port> -U quarkus

The random port can be found with docker ps

docker ps

# returns something like this:

CONTAINER ID   IMAGE           [..]    PORTS                                         [..]
b826e3a168c4   postgres:14.2   [..]    0.0.0.0:49174->5432/tcp, :::49174->5432/tcp   [..] (1)
1 The random port is 49174.

You can require a fixed port for a database Dev Service using:

quarkus.datasource.devservices.port=<your fixed port> (1)

quarkus.datasource."datasource-name".devservices.port=<your fixed port> (2)
1 Fixed port for the default datasource.
2 Fixed port for a named datasource.

docker ps allows for more advanced retrieval of container information using the --format argument. For example, to get the running container ID, the image, the labels and the ports, the following command can be used:

docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Labels}}\t{{.Ports}}

An example output using Dev Services for PostgreSQL is the following:

CONTAINER ID   IMAGE          LABELS                                                                        PORTS
a7034c91a392   postgres:14    org.testcontainers.sessionId=xyz,datasource=default,org.testcontainers=true   0.0.0.0:49154->5432/tcp, :::49154->5432/tcp

In the labels tab, we see that Quarkus added the datasource label, which can be very useful in differentiating containers when multiple Dev Services have been started.

Configuration Reference

Dev Services for Databases support the following configuration options:

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

quarkus.datasource."datasource-name".devservices.enabled

Whether this Dev Service should start with the application in dev mode or tests.

Dev Services are enabled by default unless connection configuration (e.g. the JDBC URL or reactive client URL) is set explicitly.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_ENABLED

Show more

boolean

quarkus.datasource."datasource-name".devservices.image-name

The container image name for container-based Dev Service providers.

This has no effect if the provider is not a container-based database, such as H2 or Derby.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_IMAGE_NAME

Show more

string

quarkus.datasource."datasource-name".devservices.container-env."environment-variable-name"

Environment variables that are passed to the container.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_CONTAINER_ENV__ENVIRONMENT_VARIABLE_NAME_

Show more

Map<String,String>

quarkus.datasource."datasource-name".devservices.container-properties."property-key"

Generic properties that are passed for additional container configuration.

Properties defined here are database-specific and are interpreted specifically in each database dev service implementation.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_CONTAINER_PROPERTIES__PROPERTY_KEY_

Show more

Map<String,String>

quarkus.datasource."datasource-name".devservices.properties."property-key"

Generic properties that are added to the database connection URL.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_PROPERTIES__PROPERTY_KEY_

Show more

Map<String,String>

quarkus.datasource."datasource-name".devservices.port

Optional fixed port the dev service will listen to.

If not defined, the port will be chosen randomly.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_PORT

Show more

int

quarkus.datasource."datasource-name".devservices.command

The container start command to use for container-based Dev Service providers.

This has no effect if the provider is not a container-based database, such as H2 or Derby.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_COMMAND

Show more

string

quarkus.datasource."datasource-name".devservices.db-name

The database name to use if this Dev Service supports overriding it.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_DB_NAME

Show more

string

quarkus.datasource."datasource-name".devservices.username

The username to use if this Dev Service supports overriding it.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_USERNAME

Show more

string

quarkus.datasource."datasource-name".devservices.password

The password to use if this Dev Service supports overriding it.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_PASSWORD

Show more

string

quarkus.datasource."datasource-name".devservices.init-script-path

The path to a SQL script to be loaded from the classpath and applied to the Dev Service database.

This has no effect if the provider is not a container-based database, such as H2 or Derby.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_INIT_SCRIPT_PATH

Show more

string

quarkus.datasource."datasource-name".devservices.volumes."host-path"

The volumes to be mapped to the container.

The map key corresponds to the host location; the map value is the container location. If the host location starts with "classpath:", the mapping loads the resource from the classpath with read-only permission.

When using a file system location, the volume will be generated with read-write permission, potentially leading to data loss or modification in your file system.

This has no effect if the provider is not a container-based database, such as H2 or Derby.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_VOLUMES__HOST_PATH_

Show more

Map<String,String>

quarkus.datasource."datasource-name".devservices.reuse

Whether to keep Dev Service containers running after a dev mode session or test suite execution to reuse them in the next dev mode session or test suite execution.

Within a dev mode session or test suite execution, Quarkus will always reuse Dev Services as long as their configuration (username, password, environment, port bindings, …​) did not change. This feature is specifically about keeping containers running when Quarkus is not running to reuse them across runs.

This feature needs to be enabled explicitly in testcontainers.properties, may require changes to how you configure data initialization in dev mode and tests, and may leave containers running indefinitely, forcing you to stop and remove them manually. See this section of the documentation for more information.

This configuration property is set to true by default, so it is mostly useful to disable reuse, if you enabled it in testcontainers.properties but only want to use it for some of your Quarkus applications or datasources.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_REUSE

Show more

boolean

true

quarkus.datasource."datasource-name".devservices.show-logs

Whether the logs should be consumed by the JBoss logger.

This has no effect if the provider is not a container-based database, such as H2 or Derby.

Environment variable: QUARKUS_DATASOURCE_DEVSERVICES_SHOW_LOGS

Show more

boolean

false

Related content