TestcontainerEx.CustomContainer (testcontainer_ex v0.5.1)

Copy Markdown View Source

A flexible, user-defined container specification with full lifecycle control.

CustomContainer lets users define any container configuration and then manage it through a unified API — start, stop, restart, pause, inspect, exec, logs, stats, file upload/download, and more.

Defining a custom container

alias TestcontainerEx.CustomContainer
alias TestcontainerEx.Container.Config

config =
  CustomContainer.new("my-app:latest")
  |> CustomContainer.with_exposed_port(8080)
  |> CustomContainer.with_exposed_port(5432)
  |> CustomContainer.with_env("DATABASE_URL", "postgres://localhost/mydb")
  |> CustomContainer.with_volume("/host/data", "/app/data")
  |> CustomContainer.with_cmd(["my-app", "start"])
  |> CustomContainer.with_network("my-network")
  |> CustomContainer.with_wait_strategy(
    TestcontainerEx.Wait.http("/health", 8080, status_code: 200)
  )

Starting and controlling

# Start the container
{:ok, container} = TestcontainerEx.start_container(config)

# Execute a command inside
{:ok, output} = TestcontainerEx.exec(container.container_id, ["ls", "/app"])

# Stream logs
{:ok, logs} = TestcontainerEx.container_logs(container.container_id, tail: 100)

# Get resource usage stats
stats = TestcontainerEx.container_stats(container.container_id)

# Stop and remove
:ok = TestcontainerEx.stop_container(container.container_id)
:ok = TestcontainerEx.container_remove(container.container_id, force: true)

Using with ExUnit

import TestcontainerEx.ExUnit

# Per-test container
container :my_app, CustomContainer.new("my-app:latest")

Summary

Functions

Sets a callback to run after the container starts successfully. Receives (custom_container, started_container_config, conn).

Returns the host and port for a given container port.

Returns a connection URL for common protocols.

Returns a connection URL with authentication.

Creates a custom container from an existing Config struct.

Creates a new custom container with the given image.

Returns a map of runtime information for a started container.

Sets whether the container should be auto-removed when stopped.

Sets the command to run in the container.

Adds a file to copy into the container at startup.

Sets CPU limit (fraction of a CPU core, e.g. 0.5 for half a core).

Sets DNS servers.

Sets the domain name.

Sets the entrypoint.

Sets an environment variable.

Sets multiple environment variables.

Adds an exposed port (random host port).

Adds multiple exposed ports.

Adds an extra host entry (hostname -> ip).

Adds a fixed port mapping (container_port -> host_port).

Sets the hostname inside the container.

Sets the container image.

Adds a label to the container.

Adds multiple labels.

Sets memory limit in bytes.

Sets the container name.

Sets the network mode or network name.

Sets the network mode (e.g. "host", "bridge", "none").

Sets privileged mode.

Sets the pull policy.

Sets the restart policy (e.g. "always", "unless-stopped", "on-failure:5").

Sets the stop signal (e.g. "SIGTERM", "SIGKILL").

Sets the stop timeout in seconds.

Sets the user (UID or user:group) for the container.

Adds a bind mount (host path -> container path).

Adds multiple wait strategies.

Adds a wait strategy for container readiness.

Sets the working directory inside the container.

Types

t()

@type t() :: %TestcontainerEx.CustomContainer{
  after_start: (TestcontainerEx.Container.Config.t(),
                TestcontainerEx.Container.Config.t(),
                Req.Request.t() ->
                  :ok | {:error, term()}),
  auto_remove: boolean(),
  config: TestcontainerEx.Container.Config.t(),
  labels: %{required(String.t()) => String.t()},
  wait_strategies: [struct()]
}

Functions

after_start(cc, callback)

@spec after_start(t(), (t(), TestcontainerEx.Container.Config.t(), Req.Request.t() ->
                    term())) :: t()

Sets a callback to run after the container starts successfully. Receives (custom_container, started_container_config, conn).

endpoint(container, container_port)

@spec endpoint(TestcontainerEx.Container.Config.t(), integer()) ::
  {String.t(), integer()} | nil

Returns the host and port for a given container port.

endpoint_url(container, container_port, scheme)

@spec endpoint_url(TestcontainerEx.Container.Config.t(), integer(), String.t()) ::
  String.t() | nil

Returns a connection URL for common protocols.

Examples

iex> CustomContainer.endpoint_url(container, 5432, "postgres")
"postgres://localhost:5432"

iex> CustomContainer.endpoint_url(container, 6379, "redis")
"redis://localhost:6379"

endpoint_url(container, container_port, scheme, opts)

@spec endpoint_url(
  TestcontainerEx.Container.Config.t(),
  integer(),
  String.t(),
  keyword()
) ::
  String.t() | nil

Returns a connection URL with authentication.

from_config(config)

@spec from_config(TestcontainerEx.Container.Config.t()) :: t()

Creates a custom container from an existing Config struct.

new(image)

@spec new(String.t()) :: t()

Creates a new custom container with the given image.

runtime_info(container)

@spec runtime_info(TestcontainerEx.Container.Config.t()) :: map()

Returns a map of runtime information for a started container.

with_auto_remove(cc, auto_remove)

@spec with_auto_remove(t(), boolean()) :: t()

Sets whether the container should be auto-removed when stopped.

with_cmd(cc, cmd)

@spec with_cmd(t(), [String.t()]) :: t()

Sets the command to run in the container.

with_copy_file(cc, container_path, contents)

@spec with_copy_file(t(), String.t(), String.t()) :: t()

Adds a file to copy into the container at startup.

with_cpu_limit(cc, cpus)

@spec with_cpu_limit(t(), float()) :: t()

Sets CPU limit (fraction of a CPU core, e.g. 0.5 for half a core).

with_dns(cc, dns_servers)

@spec with_dns(t(), [String.t()]) :: t()

Sets DNS servers.

with_domainname(cc, domain)

@spec with_domainname(t(), String.t()) :: t()

Sets the domain name.

with_entrypoint(cc, entrypoint)

@spec with_entrypoint(t(), [String.t()]) :: t()

Sets the entrypoint.

with_env(cc, key, value)

@spec with_env(t(), String.t() | atom(), String.t()) :: t()

Sets an environment variable.

with_envs(cc, envs)

@spec with_envs(t(), %{required(String.t()) => String.t()} | keyword()) :: t()

Sets multiple environment variables.

with_exposed_port(cc, port)

@spec with_exposed_port(t(), integer()) :: t()

Adds an exposed port (random host port).

with_exposed_ports(cc, ports)

@spec with_exposed_ports(t(), [integer()]) :: t()

Adds multiple exposed ports.

with_extra_host(cc, hostname, ip)

@spec with_extra_host(t(), String.t(), String.t()) :: t()

Adds an extra host entry (hostname -> ip).

with_fixed_port(cc, container_port, host_port)

@spec with_fixed_port(t(), integer(), integer()) :: t()

Adds a fixed port mapping (container_port -> host_port).

with_hostname(cc, hostname)

@spec with_hostname(t(), String.t()) :: t()

Sets the hostname inside the container.

with_image(cc, image)

@spec with_image(t(), String.t()) :: t()

Sets the container image.

with_label(cc, key, value)

@spec with_label(t(), String.t(), String.t()) :: t()

Adds a label to the container.

with_labels(cc, labels)

@spec with_labels(t(), %{required(String.t()) => String.t()}) :: t()

Adds multiple labels.

with_memory_limit(cc, bytes)

@spec with_memory_limit(t(), integer()) :: t()

Sets memory limit in bytes.

with_name(cc, name)

@spec with_name(t(), String.t()) :: t()

Sets the container name.

with_named_volume(cc, volume, container_path, read_only \\ false)

@spec with_named_volume(t(), String.t(), String.t(), boolean()) :: t()

Adds a named volume mount.

with_network(cc, network)

@spec with_network(t(), String.t()) :: t()

Sets the network mode or network name.

with_network_mode(cc, mode)

@spec with_network_mode(t(), String.t()) :: t()

Sets the network mode (e.g. "host", "bridge", "none").

with_privileged(cc, privileged)

@spec with_privileged(t(), boolean()) :: t()

Sets privileged mode.

with_pull_policy(cc, policy)

@spec with_pull_policy(
  t(),
  struct()
) :: t()

Sets the pull policy.

with_restart_policy(cc, policy)

@spec with_restart_policy(t(), String.t()) :: t()

Sets the restart policy (e.g. "always", "unless-stopped", "on-failure:5").

with_stop_signal(cc, signal)

@spec with_stop_signal(t(), String.t()) :: t()

Sets the stop signal (e.g. "SIGTERM", "SIGKILL").

with_stop_timeout(cc, seconds)

@spec with_stop_timeout(t(), integer()) :: t()

Sets the stop timeout in seconds.

with_user(cc, user)

@spec with_user(t(), String.t()) :: t()

Sets the user (UID or user:group) for the container.

with_volume(cc, host_path, container_path, options \\ "ro")

Adds a bind mount (host path -> container path).

with_wait_strategies(cc, strategies)

@spec with_wait_strategies(t(), [struct()]) :: t()

Adds multiple wait strategies.

with_wait_strategy(cc, strategy)

@spec with_wait_strategy(
  t(),
  struct()
) :: t()

Adds a wait strategy for container readiness.

with_workdir(cc, workdir)

@spec with_workdir(t(), String.t()) :: t()

Sets the working directory inside the container.