Install mix_project via Hex
mainTo use this project in your Elixir application, add it to your deps list in your mix.exs file.
def deps do
[
{:mix_project, "~> 0.1.0"}
]
endrepository·main·Indexed 41 days ago
https://github.com/testcontainers/testcontainers-elixirAn Elixir library for managing lightweight, throwaway instances of common services like databases or browsers using Docker containers. It provides a generic Container API, predefined modules like RedisContainer, and integration with ExUnit via the Testcontainers.ExUnit macro. Includes a Mix task `mix testcontainers.run` to wrap tasks with containerized infrastructure and a Compose CLI for managing Docker Compose lifecycles.
To use this project in your Elixir application, add it to your deps list in your mix.exs file.
def deps do
[
{:mix_project, "~> 0.1.0"}
]
endYou can manage containers using a generic API or use predefined modules like RedisContainer which include optimized waiting strategies and defaults.
Define everything manually using the %Testcontainers.Container{} struct:
{:ok, _} = Testcontainers.start_link()
config = %Testcontainers.Container{image: "redis:5.0.3-alpine"}
{:ok, container} = Testcontainers.start_container(config)Use specialized modules for common services. You can also override the image or check image using builder patterns:
{:ok, _} = Testcontainers.start_link()
# Using default Redis configuration
config = Testcontainers.RedisContainer.new()
{:ok, container} = Testcontainers.start_container(config)
# Using an alternative image (e.g., Valkey)
config =
Testcontainers.RedisContainer.new()
|> Testcontainers.RedisContainer.with_image("valkey/valkey:latest")
|> Testcontainers.RedisContainer.with_check_image("valkey/valkey")
{:ok, container} = Testcontainers.start_container(config)config = Testcontainers.RedisContainer.new()
{:ok, container} = Testcontainers.start_container(config)To add Testcontainers to your Elixir project, follow these steps:
testcontainers to your mix.exs dependencies, restricted to :test and :dev environments:def deps do
[
{:testcontainers, "~> X.XX", only: [:test, :dev]}
]
end(Replace X.XX with the current version).
Run mix deps.get.
Initialize Testcontainers in your test/test_helper.exs:
Testcontainers.start_link()def deps do
[
{:testcontainers, "~> X.XX", only: [:test, :dev]}
]
endTo start a Phoenix server in a local development environment, follow these steps:
mix setup.mix phx.server or start an interactive Elixir shell (IEx) with the server running using iex -S mix phx.server.Once started, the server is accessible at http://localhost:4000.
mix setup
mix phx.server
# OR
iex -S mix phx.serverThere are two ways to use Testcontainers on Windows:
Download and install Testcontainers Desktop. This provides a managed environment where everything is pre-configured.
If running natively with Elixir/Erlang, you must:
DOCKER_HOST environment variable:$Env:DOCKER_HOST = "tcp://localhost:2375"set DOCKER_HOST = "tcp://localhost:2375"To allow Testcontainers to inject the containerized database connection into your application, configure your config/runtime.exs to read the DATABASE_URL environment variable provided by the testcontainers.run task.
# config/runtime.exs
if config_env() in [:dev, :test] do
if url = System.get_env("DATABASE_URL") do
config :my_app, MyApp.Repo,
url: url,
pool: Ecto.Adapters.SQL.Sandbox,
show_sensitive_data_on_connection_error: true,
pool_size: 10
end
endif config_env() in [:dev, :test] do
if url = System.get_env("DATABASE_URL") do
config :my_app, MyApp.Repo,
url: url,
pool: Ecto.Adapters.SQL.Sandbox,
end
endA MongoContainer is a configuration struct used to define how a MongoDB instance should be launched. It implements the Testcontainers.DatabaseBehaviour and Testcontainers.ContainerBuilder protocols.
When you call ContainerBuilder.build/2 with a MongoContainer config, the library translates your high-level settings (like user and database) into Docker-specific instructions, such as environment variables and command-line wait strategies. This abstraction allows you to focus on database credentials and connectivity rather than low-level Docker orchestration.
Use Testcontainers.RabbitMQContainer.new/0 to create a default RabbitMQ configuration and use the with_* functions to override settings like image, port, credentials, and virtual hosts.
Note that the default starting command includes chmod 400 /var/lib/rabbitmq/.erlang.cookie, which is required for the rabbitmq-diagnostics check_running waiting strategy to work correctly.
Common configuration functions:
with_image(config, image)with_port(config, port)with_wait_timeout(config, timeout)with_username(config, username)with_password(config, password)with_virtual_host(config, vhost)with_cmd(config, cmd)with_reuse(config, boolean)with_force_reuse(config)config =
Testcontainers.RabbitMQContainer.new()
|> Testcontainers.RabbitMQContainer.with_image("rabbitmq:xyz")
|> Testcontainers.RabbitMQContainer.with_port(1111)
|> Testcontainers.RabbitMQContainer.with_username("rabbitmq")
|> Testcontainers.RabbitMQContainer.with_password("rabbitmq")Testcontainers.KafkaContainer provides functionality for creating and managing Kafka containers using the official apache/kafka Docker image in KRaft mode (no Zookeeper required).
By default, it selects a random host port between 29000-29999 to avoid conflicts, as the Kafka image requires the advertised listener address to be known at startup.
To use it, create a configuration with KafkaContainer.new/0, then start it using Testcontainers.start_container/1. You can retrieve the connection string using KafkaContainer.bootstrap_servers/1.
config = KafkaContainer.new()
{:ok, container} = Testcontainers.start_container(config)
# Get the bootstrap server address for your client
bootstrap_servers = KafkaContainer.bootstrap_servers(container)Use Testcontainers.EmqxContainer to define the configuration for an EMQX container. You can initialize a default configuration using new/0 and then use various with_* functions to override settings like the Docker image, ports, and reuse behavior. To actually start the container, pass the configuration to a ContainerBuilder (typically via Testcontainers.Container.start/1 or similar orchestration logic in your project).
config = Testcontainers.EmqxContainer.new()
|> Testcontainers.EmqxContainer.with_image("emqx:5.6.0")
|> Testcontainers.EmqxContainer.with_ports(1883, 8883, 8083, 8084, 18083)
|> Testcontainers.EmqxContainer.with_reuse(true)
# The config is then used to build/start the containerIf you are using the ToxiproxyEx library, you can automatically configure it to point to your running Toxiproxy container using configure_toxiproxy_ex/1. This sets the :toxiproxy_ex application environment :host to the container's API URL.
{:ok, toxiproxy} = Testcontainers.start_container(ToxiproxyContainer.new())
:ok = Testcontainers.ToxiproxyContainer.configure_toxiproxy_ex(toxiproxy)
# Now ToxiproxyEx is ready to use
ToxiproxyEx.get!("my_proxy"){:ok, toxiproxy} = Testcontainers.start_container(ToxiproxyContainer.new())
:ok = Testcontainers.ToxiproxyContainer.configure_toxiproxy_ex(toxiproxy)
# Now ToxiproxyEx will use this container
ToxiproxyEx.get!("my_proxy") |> ToxiproxyEx.down!(fn -> ... end)Use Testcontainers.CephContainer to create and customize configurations for Ceph containers. You can start with a default configuration using CephContainer.new() and then use various with_* functions to override settings like the image, authentication keys, bucket name, port, and wait timeout.
Commonly, you will pass this configuration to ContainerBuilder.build/2 to obtain a running %Container{} instance.
config =
CephContainer.new()
|> CephContainer.with_image("quay.io/ceph/alternative")
|> CephContainer.with_access_key("my_access_key")
|> CephContainer.with_secret_key("my_secret_key")
|> CephContainer.with_bucket("my_bucket")
|> CephContainer.with_port(8081)
built_container = ContainerBuilder.build(config, [])