Python library for throwaway instances of anything that can run in a Docker container
The fundamental Docker container lifecycle management capabilities that form the foundation of all testcontainers functionality. The DockerContainer class provides comprehensive configuration options, networking, volume mounting, and environment setup through a fluent API.
Core container lifecycle management including creation, startup, shutdown, and resource cleanup with automatic or manual control.
class DockerContainer:
def __init__(
self,
image: str,
docker_client_kw: Optional[dict[str, Any]] = None,
command: Optional[str] = None,
env: Optional[dict[str, str]] = None,
name: Optional[str] = None,
ports: Optional[list[int]] = None,
volumes: Optional[list[tuple[str, str, str]]] = None,
network: Optional[Network] = None,
network_aliases: Optional[list[str]] = None,
**kwargs: Any
):
"""
Initialize a Docker container.
Args:
image: Docker image name and tag
docker_client_kw: Docker client configuration
command: Container command to execute
env: Environment variables dictionary
name: Container name
ports: Ports to expose
volumes: Volume mounts as (host_path, container_path, mode) tuples
network: Network to connect to
network_aliases: Network aliases for the container
**kwargs: Additional Docker container options
"""
def start(self) -> "DockerContainer":
"""
Start the container.
Returns:
Self for method chaining
"""
def stop(self, force: bool = True, delete_volume: bool = True) -> None:
"""
Stop and remove the container.
Args:
force: Force container removal
delete_volume: Delete associated volumes
"""
def __enter__(self) -> "DockerContainer":
"""Context manager entry - starts container."""
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
"""Context manager exit - stops container."""Fluent API for configuring container properties including environment variables, ports, volumes, networking, and Docker-specific options.
def with_env(self, key: str, value: str) -> "DockerContainer":
"""
Add environment variable.
Args:
key: Environment variable name
value: Environment variable value
Returns:
Self for method chaining
"""
def with_envs(self, **variables: str) -> "DockerContainer":
"""
Add multiple environment variables.
Args:
**variables: Environment variables as keyword arguments
Returns:
Self for method chaining
"""
def with_env_file(self, env_file: Union[str, PathLike]) -> "DockerContainer":
"""
Load environment variables from file.
Args:
env_file: Path to environment file
Returns:
Self for method chaining
"""
def with_command(self, command: Union[str, list[str]]) -> "DockerContainer":
"""
Set container command.
Args:
command: Command to execute in container
Returns:
Self for method chaining
"""
def with_name(self, name: str) -> "DockerContainer":
"""
Set container name.
Args:
name: Container name
Returns:
Self for method chaining
"""
def with_kwargs(self, **kwargs: Any) -> "DockerContainer":
"""
Add Docker container creation arguments.
Args:
**kwargs: Docker client container creation arguments
Returns:
Self for method chaining
"""
def with_user(self, user: str) -> "DockerContainer":
"""
Set container user.
Args:
user: User to run container as (user or user:group)
Returns:
Self for method chaining
"""
def with_working_directory(self, working_directory: str) -> "DockerContainer":
"""
Set container working directory.
Args:
working_directory: Working directory path
Returns:
Self for method chaining
"""Configure port exposure and binding for container network access, supporting both automatic port assignment and explicit host port binding.
def with_exposed_ports(self, *ports: int) -> "DockerContainer":
"""
Expose ports without binding to host ports.
Args:
*ports: Port numbers to expose
Returns:
Self for method chaining
"""
def with_bind_ports(self, container: int, host: Optional[int] = None) -> "DockerContainer":
"""
Bind container port to specific host port.
Args:
container: Container port number
host: Host port number (random if None)
Returns:
Self for method chaining
"""
def get_exposed_port(self, port: int) -> str:
"""
Get the host port mapped to container port.
Args:
port: Container port number
Returns:
Host port number as string
Raises:
NoSuchPortExposed: If port not exposed
"""
def get_container_host_ip(self) -> str:
"""
Get the IP address to connect to the container.
Returns:
IP address string
"""Mount host directories and files into containers with configurable access modes and path mapping.
def with_volume_mapping(self, host: str, container: str, mode: str = "ro") -> "DockerContainer":
"""
Mount host path into container.
Args:
host: Host filesystem path
container: Container filesystem path
mode: Mount mode ('ro', 'rw', 'z', 'Z')
Returns:
Self for method chaining
"""Connect containers to Docker networks with custom aliases and network-specific configuration.
def with_network(self, network: Network) -> "DockerContainer":
"""
Connect container to network.
Args:
network: Network instance to connect to
Returns:
Self for method chaining
"""
def with_network_aliases(self, *aliases: str) -> "DockerContainer":
"""
Set network aliases for container.
Args:
*aliases: Network alias names
Returns:
Self for method chaining
"""Access container runtime information, execute commands, and retrieve logs for debugging and integration.
def get_wrapped_container(self) -> "Container":
"""
Get the underlying Docker container object.
Returns:
Docker container instance
"""
def get_docker_client(self) -> DockerClient:
"""
Get the Docker client instance.
Returns:
Docker client
"""
def get_logs(self) -> tuple[bytes, bytes]:
"""
Get container logs.
Returns:
Tuple of (stdout, stderr) as bytes
"""
def exec(self, command: Union[str, list[str]]) -> ExecResult:
"""
Execute command in running container.
Args:
command: Command to execute
Returns:
Execution result with exit_code and output
"""Handle cross-platform differences and architecture emulation for consistent behavior across development environments.
def maybe_emulate_amd64(self) -> "DockerContainer":
"""
Enable AMD64 emulation on ARM platforms.
Returns:
Self for method chaining
"""from testcontainers.core.container import DockerContainer
# Simple container with automatic cleanup
with DockerContainer("nginx:alpine") as container:
container.with_exposed_ports(80)
host_port = container.get_exposed_port(80)
host_ip = container.get_container_host_ip()
print(f"Nginx available at http://{host_ip}:{host_port}")from testcontainers.core.container import DockerContainer
from testcontainers.core.network import Network
# Create custom network
with Network() as network:
# Configure container with multiple options
container = DockerContainer("postgres:13") \
.with_env("POSTGRES_DB", "testdb") \
.with_env("POSTGRES_USER", "testuser") \
.with_env("POSTGRES_PASSWORD", "testpass") \
.with_exposed_ports(5432) \
.with_volume_mapping("./data", "/var/lib/postgresql/data", "rw") \
.with_network(network) \
.with_network_aliases("database", "db") \
.with_name("test-postgres")
with container:
# Container is now running with full configuration
connection_host = container.get_container_host_ip()
connection_port = container.get_exposed_port(5432)with DockerContainer("ubuntu:20.04") as container:
container.with_command("sleep 30")
# Execute commands in running container
result = container.exec("ls -la /")
print(f"Exit code: {result.exit_code}")
print(f"Output: {result.output.decode()}")
# Get container logs
stdout, stderr = container.get_logs()
print(f"Container output: {stdout.decode()}")class Mount(TypedDict):
bind: str # Container path
mode: str # Mount mode ('ro', 'rw', etc.)
class Network:
def __init__(
self,
docker_client_kw: Optional[dict] = None,
docker_network_kw: Optional[dict] = None
): ...
def create(self) -> "Network": ...
def remove(self) -> None: ...
def connect(self, container_id: str, network_aliases: Optional[list[str]] = None) -> None: ...
@property
def name(self) -> str: ...
@property
def id(self) -> str: ...Install with Tessl CLI
npx tessl i tessl/pypi-testcontainers