Docker Compose Support¶
Testcontainers-Python provides support for running Docker Compose environments in your tests. This is useful when you need to test against multiple containers that work together.
Basic Usage¶
The simplest way to use Docker Compose is with the DockerCompose
class:
from testcontainers.compose import DockerCompose
# Create a compose environment
compose = DockerCompose(
context="path/to/compose/directory",
compose_file_name="docker-compose.yml"
)
# Start the environment
with compose:
# Your test code here
pass
Configuration Options¶
The DockerCompose
class supports various configuration options:
compose = DockerCompose(
context="path/to/compose/directory",
compose_file_name=["docker-compose.yml", "docker-compose.override.yml"], # Multiple compose files
pull=True, # Pull images before starting
build=True, # Build images before starting
wait=True, # Wait for services to be healthy
env_file=".env", # Environment file
services=["service1", "service2"], # Specific services to run
profiles=["profile1", "profile2"], # Compose profiles to use
keep_volumes=False # Whether to keep volumes after stopping
)
Accessing Services¶
You can access service information and interact with containers:
with DockerCompose("path/to/compose/directory") as compose:
# Get service host and port
host = compose.get_service_host("web")
port = compose.get_service_port("web", 8080)
# Get both host and port
host, port = compose.get_service_host_and_port("web", 8080)
# Execute commands in a container
stdout, stderr, exit_code = compose.exec_in_container(
["ls", "-la"],
service_name="web"
)
# Get container logs
stdout, stderr = compose.get_logs("web")
Waiting for Services¶
You can wait for services to be ready:
with DockerCompose("path/to/compose/directory") as compose:
# Wait for a specific URL to be accessible
compose.wait_for("http://localhost:8080/health")
Example with Multiple Services¶
Here's a complete example using multiple services:
from testcontainers.compose import DockerCompose
import requests
def test_web_application():
compose = DockerCompose(
"path/to/compose/directory",
compose_file_name="docker-compose.yml",
pull=True,
build=True
)
with compose:
# Get web service details
host = compose.get_service_host("web")
port = compose.get_service_port("web", 8080)
# Make a request to the web service
response = requests.get(f"http://{host}:{port}/api/health")
assert response.status_code == 200
# Execute a command in the database service
stdout, stderr, exit_code = compose.exec_in_container(
["psql", "-U", "postgres", "-c", "SELECT 1"],
service_name="db"
)
assert exit_code == 0
Best Practices¶
- Use context managers (
with
statement) to ensure proper cleanup - Set appropriate timeouts for service startup
- Use health checks in your compose files
- Keep compose files in your test directory
- Use environment variables for configuration
- Consider using profiles for different test scenarios
- Clean up volumes when not needed
- Use specific service names in your tests