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.:

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:

public static final DockerImageName REDIS_IMAGE = DockerImageName.parse("redis:3.0.2");



@ClassRule
public static GenericContainer<?> redis =
    new GenericContainer<>(REDIS_IMAGE)
            .withExposedPorts(6379);

Further options may be specified:

// Set up a plain OS container and customize environment,
//   command and exposed ports. This just listens on port 80
//   and always returns '42'
@ClassRule
public static GenericContainer<?> alpine =
    new GenericContainer<>(ALPINE_IMAGE)
            .withExposedPorts(80)
            .withEnv("MAGIC_NUMBER", "42")
            .withCommand("/bin/sh", "-c",
            "while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done");

These containers, as @ClassRules, will be started before any tests in the class run, and will be destroyed after all tests have run.