testcontainers-java Documentation

Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or...

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy testcontainers-java on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name testcontainers-java -p 6379:6379 --restart always redis:6-alpine
Configured Services & Ports
โš™๏ธ redis
image: redis:6-alpine
๐Ÿ”Œ Ports: 6379
docker-compose.yml
yaml (docker-compose.yml)
services:
  redis:
    image: redis:6-alpine
    ports:
      - 6379
    environment:
      foo: bar
    labels:
      label1: value1

File: README.md

Testcontainers

Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

[Read the documentation here](https://java.testcontainers.org)

License

See LICENSE.

Copyright (c) 2015 - 2021 Richard North and other authors.

MS SQL Server module is (c) 2017 - 2021 G DATA Software AG and other authors.

Hashicorp Vault module is (c) 2017 - 2021 Capital One Services, LLC and other authors.

See contributors for all contributors.


File: core/testlib/README.md

This directory contains a synthetic JAR (fakejar.jar) that is needed for org.testcontainers.utility.MountableFileTest.

The create_fakejar.sh script may be used to recreate it.


File: docs/features/advanced_options.md

Advanced options

Container labels

To add a custom label to the container, use withLabel:

Adding a single label inside_block:single_label

Additionally, multiple labels may be applied together from a map:

Adding multiple labels inside_block:multiple_labels

Image Pull Policy

By default, the container image is retrieved from the local Docker images cache.
This works well when running against a specific version, but for images with a static tag (i.e. 'latest') this may lead to a newer version not being pulled.

It is possible to specify an Image Pull Policy to determine at runtime whether an image should be pulled or not:

Setting image pull policy inside_block:built_in_image_pull_policy

... or providing a function:

Custom image pull policy inside_block:custom_image_pull_policy

You can also configure Testcontainers to use your custom implementation by using pull.policy

=== "src/test/resources/testcontainers.properties"
text pull.policy=com.mycompany.testcontainers.ExampleImagePullPolicy

You can also use the provided implementation to always pull images

=== "src/test/resources/testcontainers.properties"
text pull.policy=org.testcontainers.images.AlwaysPullPolicy

Please see the documentation on configuration mechanisms for more information.

Customizing the container

Using docker-java

It is possible to use the docker-java API directly to customize containers before creation. This is useful if there is a need to use advanced Docker features that are not exposed by the Testcontainers API. Any customizations you make using withCreateContainerCmdModifier will be applied on top of the container definition that Testcontainers creates, but before it is created.

For example, this can be used to change the container hostname:

Using modifier to change hostname inside_block:hostname

... or modify container memory (see this if it does not appear to work):

Using modifier to change memory limits inside_block:memory

!!! note
It is recommended to use this sparingly, and follow changes to the docker-java API if you choose to use this.
It is typically quite stable, though.

For what is possible, consult the docker-java CreateContainerCmd source code.

Using CreateContainerCmdModifier

Testcontainers provides a CreateContainerCmdModifier to customize docker-java CreateContainerCmd
via Service Provider Interface (SPI) mechanism.

CreateContainerCmd example implementation

The previous implementation should be registered in META-INF/services/org.testcontainers.core.CreateContainerCmdModifier file.

!!! warning
CreateContainerCmdModifier implementation will apply to all containers created by Testcontainers.

Parallel Container Startup

Usually, containers are started sequentially when more than one container is used.
Using Startables.deepStart(container1, container2, ...).join() will start all containers in parallel.
This can be advantageous to reduce the impact of the container startup overhead.


File: docs/features/commands.md

Executing commands

Container startup command

By default the container will execute whatever command is specified in the image's Dockerfile. To override this, and specify a different command, use withCommand. For example:

Specifying a startup command inside_block:startupCommand

Executing a command

Your test can execute a command inside a running container, similar to a docker exec call:

Executing a command inside a running container inside_block:standaloneExec

This can be useful for software that has a command line administration tool. You can also get the output (stdout/stderr) and exit code from the command - for example:

Executing a command inside a running container and reading the result inside_block:execReadingStdout

Environment variables

To add environment variables to the container, use withEnv:

java
new GenericContainer(...)
		.withEnv("API_TOKEN", "foo")

File: docs/features/configuration.md

Custom configuration

You can override some default properties if your environment requires that.

Configuration locations

The configuration will be loaded from multiple locations. Properties are considered in the following order:

  1. Environment variables
  2. .testcontainers.properties in user's home folder. Example locations:
    Linux: /home/myuser/.testcontainers.properties
    Windows: C:/Users/myuser/.testcontainers.properties
    macOS: /Users/myuser/.testcontainers.properties
  3. testcontainers.properties on the classpath.

Note that when using environment variables, configuration property names should be set in upper
case with underscore separators, preceded by TESTCONTAINERS_ - e.g. checks.disable becomes
TESTCONTAINERS_CHECKS_DISABLE.

The classpath testcontainers.properties file may exist within the local codebase (e.g. within the src/test/resources directory) or within library dependencies that you may have.
Any such configuration files will have their contents merged.
If any keys conflict, the value will be taken on the basis of the first value found in:

  • 'local' classpath (i.e. where the URL of the file on the classpath begins with file:), then
  • other classpath locations (i.e. JAR files) - considered in alphabetical order of path to provide deterministic ordering.

Disabling the startup checks

checks.disable = [true|false]

Before running any containers Testcontainers will perform a set of startup checks to ensure that your environment is configured correctly. Usually they look like this:

text
โ„น๏ธŽ Checking the system...
        โœ” Docker version should be at least 1.6.0
        โœ” File should be mountable
        โœ” A port exposed by a docker container should be accessible

It takes a couple of seconds, but if you want to speed up your tests, you can disable the checks once you have everything configured. Add checks.disable=true to your $HOME/.testcontainers.properties to completely disable them.

Customizing images

!!! note
This approach is discouraged and deprecated, but is documented for completeness.
Overriding individual image names via configuration may be removed in 2021.
See Image Name Substitution for other strategies for substituting image names to pull from other registries.

Testcontainers uses public Docker images to perform different actions like startup checks, VNC recording and others.
Some companies disallow the usage of Docker Hub, but you can override *.image properties with your own images from your private registry to workaround that.

ryuk.container.image = testcontainers/ryuk:0.3.3
Performs fail-safe cleanup of containers, and always required (unless Ryuk is disabled)

tinyimage.container.image = alpine:3.17
Used to check whether images can be pulled at startup, and always required (unless startup checks are disabled)

sshd.container.image = testcontainers/sshd:1.4.0
Required if exposing host ports to containers

vncrecorder.container.image = testcontainers/vnc-recorder:1.3.0
Used by VNC recorder in Testcontainers' Selenium integration

socat.container.image = alpine/socat
compose.container.image = docker/compose:1.8.0
Required if using Docker Compose

kafka.container.image = confluentinc/cp-kafka
Used by KafkaContainer

localstack.container.image = localstack/localstack
Used by LocalStack

pulsar.container.image = apachepulsar/pulsar:2.2.0
Used by Apache Pulsar

Customizing Ryuk resource reaper

ryuk.container.image = testcontainers/ryuk:0.3.3
The resource reaper is responsible for container removal and automatic cleanup of dead containers at JVM shutdown

ryuk.container.privileged = true
In some environments ryuk must be started in privileged mode to work properly (--privileged flag)

Disabling Ryuk

Ryuk must be started as a privileged container.
If your environment already implements automatic cleanup of containers after the execution,
but does not allow starting privileged containers, you can turn off the Ryuk container by setting
TESTCONTAINERS_RYUK_DISABLED environment variable to true.

!!!tip
Note that Testcontainers will continue doing the cleanup at JVM's shutdown, unless you kill -9 your JVM process.

Customizing image pull behaviour

pull.timeout = 120
By default Testcontainers will timeout if pull takes more than this duration (in seconds)

pull.pause.timeout = 30
By default Testcontainers will abort the pull of an image if the pull appears stalled (no data transferred) for longer than this duration (in seconds).

Customizing client ping behaviour

client.ping.timeout = 10
Specifies for how long Testcontainers will try to connect to the Docker client to obtain valid info about the client before giving up and trying next strategy, if applicable (in seconds).

Customizing Docker host detection

Testcontainers will attempt to detect the Docker environment and configure everything to work automatically.

However, sometimes customization is required. Testcontainers will respect the following environment variables:

DOCKER_HOST = unix:///var/run/docker.sock
See Docker environment variables

TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE
Path to Docker's socket. Used by Ryuk, Docker Compose, and a few other containers that need to perform Docker actions.
Example: /var/run/docker-alt.sock

TESTCONTAINERS_HOST_OVERRIDE
Docker's host on which ports are exposed.
Example: docker.svc.local

For advanced users, the Docker host connection can be configured via configuration in ~/.testcontainers.properties.
Note that these settings require use of the EnvironmentAndSystemPropertyClientProviderStrategy. The example below
illustrates usage:

properties
docker.client.strategy=org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy
docker.host=tcp\://my.docker.host\:1234     # Equivalent to the DOCKER_HOST environment variable. Colons should be escaped.
docker.tls.verify=1                         # Equivalent to the DOCKER_TLS_VERIFY environment variable
docker.cert.path=/some/path                 # Equivalent to the DOCKER_CERT_PATH environment variable

In addition, you can deactivate this behaviour by specifying:

properties
dockerconfig.source=autoIgnoringUserProperties # 'auto' by default

File: docs/features/container_logs.md

Accessing container logs

It is possible to capture container output using:

  • the getLogs() method, which simply returns a String snapshot of a container's entire log output
  • the followOutput() method. This method accepts a Consumer and (optionally)
    a varargs list stating which of STDOUT, STDERR, or both, should be followed. If not specified, both will be followed.

At present, container output will always begin from the time of container creation.

Reading all logs (from startup time to present)

getLogs() is the simplest mechanism for accessing container logs, and can be used as follows:

Accessing all output (stdout and stderr) inside_block:docsGetAllLogs

Accessing just stdout inside_block:docsGetStdOut

Accessing just stderr inside_block:docsGetStdErr

Streaming logs

Testcontainers includes some out-of-the-box Consumer implementations that can be used with the streaming followOutput() model; examples follow.

Streaming container output to an SLF4J logger

Given an existing SLF4J logger instance named LOGGER:

java
Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER);
container.followOutput(logConsumer);

By default both standard out and standard error will both be emitted at INFO level.
Standard error may be emitted at ERROR level, if desired:

java
Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER).withSeparateOutputStreams();

The Mapped Diagnostic Context (MDC) for emitted messages may be configured using the withMdc(...) option:

java
Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER).withMdc("key", "value");

or using an existing map of key-value pairs:

java
Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(LOGGER).withMdc(map);

Capturing container output as a String

To stream logs live or customize the decoding, ToStringConsumer may be used:

java
ToStringConsumer toStringConsumer = new ToStringConsumer();
container.followOutput(toStringConsumer, OutputType.STDOUT);

String utf8String = toStringConsumer.toUtf8String();

// Or if the container output is not UTF-8
String otherString = toStringConsumer.toString(CharSet.forName("ISO-8859-1"));

Waiting for container output to contain expected content

WaitingConsumer will block until a frame of container output (usually a line) matches a provided predicate.

A timeout may be specified, as shown in this example.

java
WaitingConsumer consumer = new WaitingConsumer();

container.followOutput(consumer, STDOUT);

consumer.waitUntil(frame -> 
    frame.getUtf8String().contains("STARTED"), 30, TimeUnit.SECONDS);

Additionally, as the Java 8 Consumer functional interface is used, Consumers may be composed together. This is
useful, for example, to capture all the container output but only when a matching string has been found. e.g.:

java
WaitingConsumer waitingConsumer = new WaitingConsumer();
ToStringConsumer toStringConsumer = new ToStringConsumer();

Consumer<OutputFrame> composedConsumer = toStringConsumer.andThen(waitingConsumer);
container.followOutput(composedConsumer);

waitingConsumer.waitUntil(frame -> 
    frame.getUtf8String().contains("STARTED"), 30, TimeUnit.SECONDS);

String utf8String = toStringConsumer.toUtf8String();

File: docs/features/creating_container.md

Creating a container

Creating a generic container based on an image

Testcontainers' generic container support offers the most flexibility, and makes it easy to use virtually any container
images as temporary test dependencies. For example, if you might use it to test interactions with:

  • NoSQL databases or other data stores (e.g. redis, elasticsearch, mongo)
  • Web servers/proxies (e.g. nginx, apache)
  • Log services (e.g. logstash, kibana)
  • Other services developed by your team/organization which are already dockerized

With a generic container, you set the container image using a parameter to the rule constructor, e.g.:

java
new GenericContainer(DockerImageName.parse("jboss/wildfly:9.0.1.Final"))

Specifying an image

Many Container classes in Testcontainers have historically supported:

  • a no-args constructor - for example new GenericContainer() and new ElasticsearchContainer(). With these constructors, Testcontainers has traditionally used a default image name (including a fixed image tag/version). This has caused a conflict between the need to keep the defaults sane (i.e. up to date) and the need to avoid silently upgrading these dependencies along with new versions of Testcontainers.
  • a single string-argument constructor, which has taken either a version or an image name as a String. This has caused some ambiguity and confusion.

Since v1.15.0, both of these constructor types have been deprecated, for the reasons given above.

Instead, it is highly recommended that all containers be constructed using a constructor that accepts a DockerImageName object.
The DockerImageName class is an unambiguous reference to a docker image.

It is suggested that developers treat DockerImageNames as you would any other potentially-constant value - consider defining a constant in your test codebase that matches the production version of the dependency you are using.

Examples

A generic container rule can be used with any public docker image; for example:

Creating a Redis container inside_block:container

The container, as @Container, will be started before any tests in the class run, and will be destroyed after all
tests have run.


File: docs/features/creating_images.md

Creating images on-the-fly

Overview

In situations where there is no pre-existing Docker image, Testcontainers can create a new temporary image on-the-fly
from a Dockerfile. For example, when the component under test is the Docker image itself, or when an existing base
image needs to be customized for specific test(s).

Simply pass a configured instance of ImageFromDockerfile as a constructor parameter to GenericContainer.
Testcontainers will docker build a temporary container image, and will use it when creating the container.

Dockerfile from String, file or classpath resource

ImageFromDockerfile accepts arbitrary files, strings or classpath resources to be used as files in the build context.
At least one of these needs to be a Dockerfile.

java
GenericContainer container = new GenericContainer(
    new ImageFromDockerfile()
            .withFileFromString("folder/someFile.txt", "hello")
            .withFileFromClasspath("test.txt", "mappable-resource/test-resource.txt")
            .withFileFromClasspath("Dockerfile", "mappable-dockerfile/Dockerfile"))

The following methods may be used to provide the Dockerfile and any other required build context files:

  • withFileFromString(buildContextPath, content)
  • withFileFromClasspath(buildContextPath, classpathPath)
  • withFileFromPath(buildContextPath, filesystemPath)
  • withFileFromFile(buildContextPath, filesystemFile)

!!! info
In older versions of Testcontainers (before 1.3.0) it was necessary to explicitly declare each file that needed to
be present in the Docker build context.
This can be replaced with the following syntax:

text
[Passing an entire directory of files to the Dockerfile build context](../../core/src/test/java/org/testcontainers/images/builder/DockerfileBuildTest.java) inside_block:docsShowRecursiveFileInclusion


Where `RESOURCE_PATH` is the path to a directory containing a `Dockerfile` and any files that it needs to refer to.
Doing this is equivalent to `docker build RESOURCE_PATH` on the command line.

To mimic `docker build .`, `RESOURCE_PATH` would simply be set to `.` as well.

Dockerfile DSL

If a static Dockerfile is not sufficient (e.g. your test needs to cover many variations that are best generated
programmatically), there is a DSL available to allow Dockerfiles to be defined in code. e.g.:

java
new GenericContainer(
        new ImageFromDockerfile()
                .withDockerfileFromBuilder(builder ->
                        builder
                                .from("alpine:3.17")
                                .run("apk add --update nginx")
                                .cmd("nginx", "-g", "daemon off;")
                                .build()))
                .withExposedPorts(80);

See ParameterizedDockerfileContainerTest for a very basic example of using this in conjunction with JUnit
parameterized testing.

Automatic deletion

Temporary container images will be automatically removed when the test JVM shuts down. If this is not desired and
the image should be retained between tests, pass a stable image name and false flag to the ImageFromDockerfile
constructor.

Retaining the image between tests will use Docker's image cache to accelerate subsequent test runs.

By default the no-args constructor will use an image name of the form testcontainers/ + random string:

  • public ImageFromDockerfile()
  • public ImageFromDockerfile(String dockerImageName)
  • public ImageFromDockerfile(String dockerImageName, boolean deleteOnExit)

Alternative Dockerfiles

Normally Docker will automatically build an image from any /Dockerfile that it finds in the root of the build context.
To override this behaviour, use .withDockerfilePath("./Name-Of-Other-Dockerfile").

Build Args

Build Args may be used to allow lightweight parameterization.

To specify build args, use .withBuildArg("varname", "value") or provide a Map of args using .withBuildArgs(map).


File: docs/features/files.md

Files and volumes

Copying files

Files can be copied into the container before startup, or can be copied from the container after the container has started.

!!! note
This is the recommended approach for portability cross-docker environments.

Copying to a container before startup

Copying files using MountableFile inside_block:copyToContainer

Using Transferable, file content will be placed in the specified location.

Copying files using Transferable inside_block:transferableFile

Setting file mode is also possible.

Copying files using Transferable with file mode inside_block:transferableWithFileMode

Copying a file from a running container

Copying files from a container inside_block:copyFileFromContainer


File: docs/features/image_name_substitution.md

Image name substitution

Testcontainers supports automatic substitution of Docker image names.

This allows replacement of an image name specified in test code with an alternative name - for example, to replace the
name of a Docker Hub image dependency with an alternative hosted on a private image registry.

This is advisable to avoid Docker Hub rate limiting, and some companies will prefer this for policy reasons.

This page describes four approaches for image name substitution:

It is assumed that you have already set up a private registry hosting all the Docker images your build requires.

Manual substitution

Consider this if:

  • You use only a few images and updating code is not a chore
  • All developers and CI machines in your organisation have access to a common registry server
  • You also use one of the automated mechanisms to substitute the images that Testcontainers itself requires

This approach simply entails modifying test code manually, e.g. changing:

For example, you may have a test that uses the mysql container image from Docker Hub:

Direct Docker Hub image name inside_block:directDockerHubReference

to:

Private registry image name inside_block:hardcodedMirror

Automatically modifying Docker Hub image names

Testcontainers can be configured to modify Docker Hub image names on the fly to apply a prefix string.

Consider this if:

  • Developers and CI machines need to use different image names. For example, developers are able to pull images from Docker Hub, but CI machines need to pull from a private registry
  • Your private registry has copies of images from Docker Hub where the names are predictable, and just adding a prefix is enough.
    For example, registry.mycompany.com/mirror/mysql:8.0.36 can be derived from the original Docker Hub image name (mysql:8.0.36) with a consistent prefix string: registry.mycompany.com/mirror/

In this case, image name references in code are unchanged.
i.e. you would leave as-is:

Unchanged direct Docker Hub image name inside_block:directDockerHubReference

You can then configure Testcontainers to apply the prefix registry.mycompany.com/mirror/ to every image that it tries to pull from Docker Hub.
This can be done in one of two ways:

  • Setting environment variables TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX=registry.mycompany.com/mirror/
  • Via config file, setting hub.image.name.prefix in either:
    • the ~/.testcontainers.properties file in your user home directory, or
    • a file named testcontainers.properties on the classpath

Testcontainers will automatically apply the prefix to every image that it pulls from Docker Hub - please verify that all the required images exist in your registry.

Testcontainers will not apply the prefix to:

  • non-Hub image names (e.g. where another registry is set)
  • Docker Hub image names where the hub registry is explicitly part of the name (i.e. anything with a docker.io or registry.hub.docker.com host part)

Developing a custom function for transforming image names on the fly

Consider this if:

  • You have complex rules about which private registry images should be used as substitutes, e.g.:
    • non-deterministic mapping of names meaning that a name prefix cannot be used
    • rules depending upon developer identity or location
  • or you wish to add audit logging of images used in the build
  • or you wish to prevent accidental usage of images that are not on an approved list

In this case, image name references in code are unchanged.
i.e. you would leave as-is:

Unchanged direct Docker Hub image name inside_block:directDockerHubReference

You can implement a custom image name substitutor by:

  • subclassing org.testcontainers.utility.ImageNameSubstitutor
  • configuring Testcontainers to use your custom implementation

The following is an example image substitutor implementation:

Example Image Substitutor block:ExampleImageNameSubstitutor

Testcontainers can be configured to find it at runtime via configuration.
To do this, create or modify a file on the classpath named testcontainers.properties.

For example:

=== "src/test/resources/testcontainers.properties"
text image.substitutor=com.mycompany.testcontainers.ExampleImageNameSubstitutor

Note that it is also possible to provide this same configuration property:

  • in a testcontainers.properties file at the root of a library JAR file (useful if you wish to distribute a drop-in image substitutor JAR within an organization)
  • in a properties file in the user's home directory (~/.testcontainers.properties; note the leading .)
  • or as an environment variable (e.g. TESTCONTAINERS_IMAGE_SUBSTITUTOR=com.mycompany.testcontainers.ExampleImageNameSubstitutor).

Please see the documentation on configuration mechanisms for more information.

Also, you can use the ServiceLoader mechanism to provide the fully qualified class name of the ImageNameSubstitutor implementation:

=== "src/test/resources/META-INF/services/org.testcontainers.utility.ImageNameSubstitutor"
text com.mycompany.testcontainers.ExampleImageNameSubstitutor

Overriding image names individually in configuration

!!! note
This approach is discouraged and deprecated, but is documented for completeness.
Please consider one of the other approaches outlined in this page instead.
Overriding individual image names via configuration may be removed in the future.

Consider this if:

  • You have many references to image names in code and changing them is impractical, and
  • None of the other options are practical for you

In this case, image name references in code are left unchanged.
i.e. you would leave as-is:

Unchanged direct Docker Hub image name inside_block:directDockerHubReference

You can force Testcontainers to substitute in a different image using a configuration file, which allows some (but not all) container names to be substituted.