🚨 AtomicJar is now part of Docker 🐋! Read the blog
Testcontainers Desktop

Docs for Testcontainers Desktop

Overview

Testcontainers Desktop is a companion app for the open source Testcontainers libraries that makes local development and testing with real dependencies simple. It’s a closed-source app available on macOS, Windows, and Linux, that includes a free plan for individual developers. It’s lightweight and runs in your system tray, so you can remain in your IDE while developing.

Testcontainers Desktop overview

Open source Testcontainers libraries must remain self-sufficient to write and run tests, from desktop to CI. Testcontainers Desktop, as an optional desktop-only app, focuses on improving the developer experience. The features of Testcontainers Desktop are broken down into four main categories:

  1. Select a container runtime
  2. Debug Testcontainers-based services
  3. Manage the lifecycle of containers
  4. Track and analyze test sessions

Installation and sign-in

Install Testcontainers Desktop

Go to the download page, select your OS-specific distribution, and install it.

Alternatively, if you use macOS, you can install the app via Homebrew:

brew install atomicjar/tap/testcontainers-desktop

Create a free account or sign in

The first time Testcontainers Desktop starts it asks you to create a free account at app.testcontainers.cloud. If you already have an account, you should sign in instead. If you’d like to join a colleague’s organization, you can ask them to invite you from the members page. Unauthenticated usage is not supported at this time.

User guide

Select a container runtime

Open source Testcontainers libraries rely on a container runtime compatible with the Docker API. The following container runtime environments are officially supported:

Refer to this page for more extensive information on supported container runtime environments, as well as known limitations of alternative container runtime environments.

Switch between local runtimes

Testcontainers Desktop local runtime selection

Testcontainers Desktop lets you switch between local container runtimes. This is particularly useful if you’re trying to adopt an OSS runtime such as podman or colima, or are looking to locate and clean up old runtimes that are interfering with your tests.

Enable Testcontainers Desktop’s embedded runtime (beta)

Testcontainers Desktop embedded runtime

Testcontainers Desktop aims to deliver a batteries-included developer experience for local development and testing. As of version 1.4.18 Testcontainers Desktop embeds a lightweight and fast runtime, optimized for Testcontainers usage. The embedded runtime is currently in beta, and only available on macOS 11 or later to benefit from Apple’s native Virtualization Framework. It is available as the top option for local runtimes.

The runtime takes a few seconds to initialize the first time you run a command, displaying “Embedded Runtime (Starting…)” in the menu. The menu changes to “Embedded Runtime (Started)” and the icon displays a “play” icon when ready. If you run into any issues, join us in the #testcontainers-desktop channel of the public slack to troubleshoot.

Run with Testcontainers Cloud

Testcontainers Desktop cloud runtime

Testcontainers Desktop provides seamless access to Testcontainers Cloud to run containers in the cloud on demand, without consuming local resources or requiring a local docker daemon. Besides sparing CPU and RAM, running containers in the cloud provides a consistent Linux x86 architecture, just like in production, regardless of what operating system developers use for local development (e.g. macOS with ARM CPU, Windows with WSL, etc.).

The free plan for individual developers includes a free monthly quota of 300 minutes of cloud runtime. Paid plans are available to users who need to lift this restriction. See this knowledge article for details on usage metering and billing.

To switch to the cloud runtime, select “Run with Testcontainers Cloud” in the menu. Once selected, the menu displays “Testcontainers Cloud” as confirmation. When Testcontainers libraries run containers, a cloud worker is allocated dynamically and the icon changes to display the “play” icon. Testcontainers Desktop supports parallelizing test execution across multiple workers via Turbo mode, which requires a paid account.

The “Connected” sub-menu containers useful troubleshooting information, including the worker-id and associated latency, and also confirmation of whether the self-check was successful, potentially identifying any connectivity issues. See the knowledge base for further troubleshooting information.

Testcontainers Desktop cloud diagnosis menu

Use the app’s docker context

Testcontainers Desktop detects local runtimes based on existing docker contexts. Testcontainers Desktop does not automatically switch docker context for you; instead the app creates a context called tcc or tcd that links dynamically to the selected runtime. For example, the following commands run docker ps through Testcontainers Desktop, ensuring that it works regardless of the selected local or cloud runtime.

docker context list
docker context use tcc
docker ps
Testcontainers Desktop docker contexts

Open a terminal to your container runtime

Testcontainers Desktop Open Terminal

Testcontainers Desktop now makes it easy to “open a terminal” to your container runtime. If you rely on Testcontainers Cloud, you’ll connect to the cloud worker, and if you run containers locally (including with the new embedded runtime!), you’ll connect to the VM on your machine. Either way, the docker context is set automatically so that commands such as docker ps and docker stats work out of the box. The terminal opens in a web browser for portability reasons, with access limited to localhost and secured by a unique hash.

Note: if you’d like to connect to someone else’s cloud worker instead, for example to troubleshoot automated tests in your CI, you can do so by using the connect command.

Debug Testcontainers-based services

Set fixed ports to easily debug development services

Testcontainers Desktop services

Testcontainers libraries dynamically map the container’s ports onto random ports on the host machine to avoid conflicts, ensuring that automated tests run reliably. However, during development it can be cumbersome to check which random port is assigned on the host to connect local debugging tools such as an IDE plugin to inspect a datastore, or k9s to manage a Kubernetes cluster. Testcontainers Desktop simplifies debugging by letting you define services and exposing them on fixed ports for debugging purposes.

A “service” is a collection of running containers and associated mechanisms to interract with them. To configure services, click on Services → Open config location. The app ships with 15+ preconfigured configuration files for popular technologies, including postgres, kafka, and many others. Simply rename a file from .example to a .toml extension to get started with the corresponding technology.

A minimal configuration file called postgres-datastore.toml might look as follows:

ports = [
    {local-port = 5432, container-port = 5432},
]

selector.image-names = ["postgres"]

This configuration file:

  1. Defines a service called postgres-datastore (base on the filename).
  2. Selects all running containers that contain the string “postgres” in the image name (e.g. "postgres:15.2-alpine").
  3. Maps the PostgreSQL container’s port 5432 onto the host’s port 5432.

With this service defined, Testcontainers Desktop automatically reloads the configuration and lets you connect to a running container with your IDE plugin for relational databases, or the following command:

psql -h localhost -p 5432 -U test -d test

Configured services are listed under the “Services” menu alongside their exposed port(s). If a service is misconfigured, such as containing a typo in a core attribute, it is indicated as having “no ports configured”.

Define services based on docker labels

When running automated tests it’s possible for multiple containers belonging to the same service to run concurrently. In order to provide a stable experience, Testcontainers Desktop maps the fixed port to the oldest running container, and only switches over if it terminates.

The example files also contain instructions to go beyond the default configuration. For example, you might be running 2 separate services based on the same image, or you might want to target the leader and replicas separately. If so, follow the instructions to fine-tune how the service selects containers based on labels, which open source Testcontainers libraries let you add easily from your code.

The following service configuration selects all running containers that contain the string “postgres” in the image name AND the specified docker label:

ports = [
    {local-port = 5432, container-port = 5432},
]

selector.image-names = ["postgres"]

[selector.label]
"com.testcontainers.desktop.service" = "postgres-datastore"

Tail logs and connect to a Testcontainers-based service

Testcontainers Desktop Tail Logs

Testcontainers Desktop simplifies debugging by letting you define services and exposing them on fixed ports. Besides connecting a local debug tool or IDE plugin via a fixed port, the two most common debug actions are: reviewing container logs and opening a shell. Both are now only a click away in the “services” menu! You’ll want to ensure a container is running for the corresponding service, so consider freezing their shutdown while you investigate.

Manage the lifecycle of containers

Freeze containers to halt their shutdown (beta)

Testcontainers Desktop freeze containers shutdown

While running your tests, you may want to inspect data before the test terminates and the container is automatically cleaned up. You can use the “Freeze containers shutdown” to halt containers termination.

Turning on this feature is conceptually similar to setting a dynamic breakpoint before any container termination. When enabled, Testcontainers Desktop prevents your application from shuting down containers, effectively keeping the tests running indefinitely. Once you’re done with your investigation, uncheck the “Freeze containers shutdown” button to resume normal test execution, including clean-up. Alternatively, see the next section on how to “Terminate containers”.

Freezing containers shutdown lets you inspect development services via a fixed port (see previous section). A notification lets you know when a container becomes frozen:

Testcontainers Desktop freeze notification

This feature is currently in beta, with the following known limitations:

  • Some test frameworks have a built-in timeout configured and will terminate a test and associated containers if frozen for too long.
  • Freeze only supports containers with a managed lifecycle. For example, in Testcontainers Java, it’s common practice to manage the lifecycle of containers via the @Container annotation or inside a “try-with-resources” block. Such containers will be properly frozen when the code attempts to close() them. It is not currently possible to freeze long-lived, unmanaged containers such as those defined by a singleton pattern and reusable containers.

Terminate containers

Testcontainers Desktop terminate containers

By default, Testcontainers libraries spin up ephemeral containers that are automatically cleaned up when your tests complete. You can use the “Terminate containers” command to clean up all running Testcontainers-powered containers, while sparing other vanilla containers.

This command is useful when working with long-lived containers, such as when you:

  • Rely on reusable containers to speed up your tests and local development.
  • Disable “Ryuk” (i.e. the resource reaper).
  • Enable “Freeze containers shutdown”.

A notification confirms how many containers are terminated:

Testcontainers Desktop terminate notification

Enable reusable containers

Testcontainers Desktop enable reussable containers

Reusable containers are an experimental capability that delivers a useful performance optimization: by keeping containers running and allowing multiple tests to reuse the same container, it’s possible to shave off container start times. However, reusable containers are not suited for CI usage, and therefore activating the capability on desktop requires setting the testcontainers.reuse.enable=true property in the local ~/.testcontainers.properties file. Testcontainers Desktop sets this property by default. It’s possible to disable it under Preferences → Enable reusable containers.

This feature is currently in beta, with the following known limitations:

  • Some Testcontainers languages do not yet implement reuse.
  • reuse in Testcontainers Java does not currently support networks, in the sense that they can change the container’s configuration and prevent reuse. In turn, this can impact methods such as exposeHostPorts.
  • Testcontainers Go matches the container on req.Name alone, instead of its full configuration, and within a single package. This can lead to accidental reuse if separate containers share the same name.
  • Testcontainers Node does not rely on the testcontainers.reuse.enable=true property, and therefore this feature cannot deactivate reuse as expected.
  • While reuse prevents Ryuk from cleaning-up containers, they are stopped by regular lifecycle commands (e.g. close() or similar). In practice, this means they’re best defined via the singleton pattern.

Track and analyze test sessions

Testcontainers Desktop open dashboard

Testcontainers Desktop tracks and analyzes your testing sessions to provide insights into your development and testing patterns. You can access your dashboard by clicking “Open dashboard…” or directly at https://app.testcontainers.cloud/dashboard.

Dashboards are collaborative: they aggregate test data across desktop and CI, as well as across all users in the same organization. Testcontainers Desktop tracks test data for both local and cloud runtimes, though additional insights are available when running containers in the cloud.

Testcontainers Desktop dashboard widgets

Dashboards contain widgets for your testing sessions that let you answer questions such as:

  • How consistently do we test on desktop before pushing to the CI?
  • Has a recent release impacted our team’s testing velocity?
  • What are the most popular container images we test with?
  • Are there outdated dependencies used in test suites?
  • Etc.
Testcontainers Desktop dashboard session

Dashboards contain a detailed timeline of each testing session, which can help identify bottlenecks in test suites, or opportunities to run tests in parallel. When using Turbo mode, each test session also helps validate load balancing of test suites across multiple cloud workers.

Account management

Invite and remove users

View and manage your team by visiting the Account page.

The “Users” tab lists all users within your organization, and their associated roles. If you have Admin rights, you can manage access for existing team members.

Testcontainers Desktop Account tab

You also have the option to delete a specific user from the team or grant them admin rights.

To invite new users, open the “Invite Users” menu, copy the secret invitation link, and share it with them. When a user signs up with the invitation link, they join your organization instead of creating their own, and their name gets added to the list of active members.

Join a different organization

A user belongs to a single organization at a time. If you wish to leave your current organization and join another one, follow these steps:

  1. Navigate to your Account page
  2. Click on the three dots next to your user row and select the “Leave” option.
    Testcontainers Desktop Account tab
  3. Once you’re redirected to the authentication page, click on “Log Out” under your profile menu, and then close the tab.
  4. To log off from Testcontainers Desktop, open the application and select “Reset” under the Preferences tab.
    Testcontainers Desktop Reset
  5. In the new web page called “Sign up for Testcontainers Desktop”, you can either sign up and create a new organization, or follow the invitation link provided by your colleague to join their organization.
    Testcontainers Desktop Sign Up

If you need to switch between multiple organizations, you need a separate user account for each. You can achieve this by signing up with a different email address or provider (e.g. github, gmail). To switch the Testcontainers Desktop application from one organization to another, follow these steps:

  1. Log out from https://app.testcontainers.cloud.
  2. Click on “Reset” under the Testcontainers Desktop application preferences.
  3. Once you’re redirected to the “Sign up for Testcontainers Desktop” page, click on “Log In” and authenticate with the credentials associated with the organization you wish to join.

To verify which account is associated with the Testcontainers Desktop application, expand the tray icon and check the username and authentication provider listed below the title and version.

Troubleshooting

If you experience unexpected behavior with Testcontainers Desktop, there are a few common issues you can investigate and resolve independently. A common first step is to review the logs for the app, possibly after enabling verbose logging.

Testcontainers Desktop show logs

It’s also possible to reset the app to its default settings, which will require signing back in.

Testcontainers Desktop reset

If you continue to have trouble, click “Get help…” to open the knowledge base or report an issue.

Testcontainers Desktop get help

Finally, consider joining open-source maintainers, AtomicJar engineers, and fellow users in the #testcontainers-desktop channel of the public slack.