or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

container-management.mddocker-compose.mdindex.mdnetworking.mdutilities.mdwait-strategies.md
tile.json

index.mddocs/

Testcontainers

Testcontainers is a NodeJS library for managing Docker containers during test execution. It provides programmatic control over container lifecycle, enabling developers to create lightweight, throwaway instances of databases, message brokers, web browsers, and any Docker-compatible service for integration testing, end-to-end testing, and local development.

Package Information

  • Package Name: testcontainers
  • Package Type: npm
  • Language: TypeScript/JavaScript
  • Installation: npm install testcontainers

Core Imports

import { GenericContainer, Wait } from 'testcontainers';

For CommonJS:

const { GenericContainer, Wait } = require('testcontainers');

Basic Usage

import { GenericContainer, Wait } from 'testcontainers';

// Start a Redis container
const container = await new GenericContainer('redis:7-alpine')
  .withExposedPorts(6379)
  .withWaitStrategy(Wait.forLogMessage('Ready to accept connections'))
  .start();

// Get connection details
const host = container.getHost();
const port = container.getMappedPort(6379);

// Use the container
// ... your test code here ...

// Clean up
await container.stop();

Architecture

Testcontainers is built around several key components:

  • Container Management: Core GenericContainer class with fluent builder API for configuration
  • Lifecycle Control: Methods for starting, stopping, restarting containers with automatic cleanup
  • Wait Strategies: Flexible system for determining when containers are ready (health checks, log messages, HTTP endpoints, ports)
  • Docker Compose: Support for multi-container environments using Docker Compose files
  • Networking: Create and manage Docker networks for inter-container communication
  • Runtime Client: Abstraction layer supporting both Docker and Podman container runtimes
  • Resource Management: Automatic cleanup via Ryuk reaper container, container reuse for performance

Capabilities

Container Management

Core container lifecycle management with fluent configuration API. Create containers from images or Dockerfiles, configure environment variables, ports, volumes, and resource limits.

class GenericContainer {
  constructor(image: string);
  static fromDockerfile(context: string, dockerfileName?: string): GenericContainerBuilder;

  // Lifecycle
  start(): Promise<StartedTestContainer>;

  // Configuration
  withCommand(command: string[]): this;
  withEntrypoint(entrypoint: string[]): this;
  withName(name: string): this;
  withEnvironment(environment: { [key: string]: string }): this;
  withExposedPorts(...ports: PortWithOptionalBinding[]): this;
  withBindMounts(bindMounts: BindMount[]): this;
  withWaitStrategy(waitStrategy: WaitStrategy): this;
  withStartupTimeout(startupTimeoutMs: number): this;
  withNetwork(network: StartedNetwork): this;
  withNetworkMode(networkMode: string): this;
  withNetworkAliases(...networkAliases: string[]): this;
  withUser(user: string): this;
  withPrivilegedMode(): this;
  withHealthCheck(healthCheck: HealthCheck): this;
  withWorkingDir(workingDir: string): this;
  withReuse(): this;
  withPullPolicy(pullPolicy: ImagePullPolicy): this;
}

interface StartedTestContainer {
  stop(options?: Partial<StopOptions>): Promise<StoppedTestContainer>;
  restart(options?: Partial<RestartOptions>): Promise<void>;
  getHost(): string;
  getMappedPort(port: number, protocol?: string): number;
  getName(): string;
  getId(): string;
  exec(command: string | string[], opts?: Partial<ExecOptions>): Promise<ExecResult>;
  logs(opts?: { since?: number; tail?: number }): Promise<Readable>;
}

Container Management

Docker Compose

Manage multi-container environments using Docker Compose files. Configure services, networks, and volumes with per-service wait strategies.

class DockerComposeEnvironment {
  constructor(composeFilePath: string, composeFiles: string | string[]);

  withBuild(): this;
  withEnvironment(environment: { [key: string]: string }): this;
  withProfiles(...profiles: string[]): this;
  withWaitStrategy(containerName: string, waitStrategy: WaitStrategy): this;
  withStartupTimeout(startupTimeoutMs: number): this;
  up(services?: Array<string>): Promise<StartedDockerComposeEnvironment>;
}

interface StartedDockerComposeEnvironment {
  getContainer(containerName: string): StartedTestContainer;
  stop(): Promise<StoppedDockerComposeEnvironment>;
  down(options?: Partial<ComposeDownOptions>): Promise<DownedDockerComposeEnvironment>;
}

Docker Compose

Networking

Create and manage Docker networks for container communication and isolation.

class Network {
  start(): Promise<StartedNetwork>;
}

interface StartedNetwork {
  getId(): string;
  getName(): string;
  stop(): Promise<StoppedNetwork>;
}

Networking

Wait Strategies

Flexible strategies for determining when containers are ready for use. Supports health checks, log messages, HTTP endpoints, port checks, and shell commands.

class Wait {
  static forAll(waitStrategies: WaitStrategy[]): WaitStrategy;
  static forListeningPorts(): WaitStrategy;
  static forLogMessage(message: string | RegExp, times?: number): WaitStrategy;
  static forHealthCheck(): WaitStrategy;
  static forHttp(path: string, port: number, options?: HttpWaitStrategyOptions): HttpWaitStrategy;
  static forSuccessfulCommand(command: string): WaitStrategy;
}

interface WaitStrategy {
  withStartupTimeout(startupTimeoutMs: number): WaitStrategy;
}

interface HttpWaitStrategy extends WaitStrategy {
  forStatusCode(statusCode: number): this;
  forStatusCodeMatching(predicate: (statusCode: number) => boolean): this;
  withMethod(method: string): this;
  withHeaders(headers: { [key: string]: string }): this;
  withBasicCredentials(username: string, password: string): this;
  usingTls(): this;
}

Wait Strategies

Utilities

Helper classes and functions for advanced use cases including port management, image naming, logging, retry logic, and host port exposure.

class TestContainers {
  static exposeHostPorts(...ports: number[]): Promise<void>;
}

function getContainerRuntimeClient(): Promise<ContainerRuntimeClient>;

class ImageName {
  constructor(registry: string | undefined, image: string, tag: string);
  static fromString(string: string): ImageName;
  readonly registry: string | undefined;
  readonly image: string;
  readonly tag: string;
  readonly string: string;
}

Utilities

Types

type Environment = { [key: string]: string };

type BindMode = 'rw' | 'ro' | 'z' | 'Z';

interface BindMount {
  source: string;
  target: string;
  mode?: BindMode;
}

interface HealthCheck {
  test: ['CMD-SHELL', string] | ['CMD', ...string[]];
  interval?: number;
  timeout?: number;
  retries?: number;
  startPeriod?: number;
}

interface ExecOptions {
  workingDir?: string;
  user?: string;
  env?: { [key: string]: string };
}

interface ExecResult {
  output: string;
  stdout: string;
  stderr: string;
  exitCode: number;
}

interface StopOptions {
  timeout: number;
  remove: boolean;
  removeVolumes: boolean;
}

interface RestartOptions {
  timeout: number;
}

interface HttpWaitStrategyOptions {
  abortOnContainerExit?: boolean;
}

interface ComposeDownOptions {
  timeout?: number;
  removeVolumes?: boolean;
}

type PortWithOptionalBinding =
  | number
  | `${number}/${'tcp' | 'udp'}`
  | PortWithBinding;

interface PortWithBinding {
  container: number;
  host: number;
  protocol?: 'tcp' | 'udp';
}

type ContainerRuntime = 'docker' | 'podman';

type HealthCheckStatus = 'none' | 'starting' | 'unhealthy' | 'healthy';

type HostPortBindings = Array<{ hostIp: string; hostPort: number }>;

type Ports = { [containerPortWithProtocol: string]: HostPortBindings };

interface NetworkSettings {
  networkId: string;
  ipAddress: string;
}

interface InspectResult {
  name: string;
  hostname: string;
  ports: Ports;
  healthCheckStatus: HealthCheckStatus;
  networkSettings: { [networkName: string]: NetworkSettings };
  state: {
    status: string;
    running: boolean;
    startedAt: Date;
    finishedAt: Date | undefined;
  };
  labels: { [key: string]: string };
}