Executing Commands in Containers¶
Testcontainers-Python provides several ways to execute commands inside containers. This is useful for setup, verification, and debugging during tests.
Basic Command Execution¶
The simplest way to execute a command is using the exec
method:
from testcontainers.generic import GenericContainer
with GenericContainer("alpine:latest") as container:
# Execute a simple command
exit_code, output = container.exec(["ls", "-la"])
print(output) # Command output as string
Command Execution with Options¶
You can customize command execution with various options:
with GenericContainer("alpine:latest") as container:
# Execute command with user
exit_code, output = container.exec(
["whoami"],
user="nobody"
)
# Execute command with environment variables
exit_code, output = container.exec(
["echo", "$TEST_VAR"],
environment={"TEST_VAR": "test_value"}
)
# Execute command with working directory
exit_code, output = container.exec(
["pwd"],
workdir="/tmp"
)
Interactive Commands¶
For interactive commands, you can use the exec_interactive
method:
with GenericContainer("alpine:latest") as container:
# Start an interactive shell
container.exec_interactive(["sh"])
Command Execution with Timeout¶
You can set a timeout for command execution:
with GenericContainer("alpine:latest") as container:
# Execute command with timeout
try:
exit_code, output = container.exec(
["sleep", "10"],
timeout=5 # Timeout in seconds
)
except TimeoutError:
print("Command timed out")
Command Execution with Privileges¶
For commands that require elevated privileges:
with GenericContainer("alpine:latest") as container:
# Execute command with privileges
exit_code, output = container.exec(
["mount"],
privileged=True
)
Command Execution with TTY¶
For commands that require a TTY:
with GenericContainer("alpine:latest") as container:
# Execute command with TTY
exit_code, output = container.exec(
["top"],
tty=True
)
Best Practices¶
- Use appropriate timeouts for long-running commands
- Handle command failures gracefully
- Use environment variables for configuration
- Consider security implications of privileged commands
- Clean up after command execution
- Use appropriate user permissions
- Handle command output appropriately
- Consider using shell scripts for complex commands
Common Use Cases¶
Database Setup¶
from testcontainers.postgres import PostgresContainer
with PostgresContainer() as postgres:
# Create a database
postgres.exec(["createdb", "testdb"])
# Run migrations
postgres.exec(["psql", "-d", "testdb", "-f", "/path/to/migrations.sql"])
File Operations¶
with GenericContainer("alpine:latest") as container:
# Create a directory
container.exec(["mkdir", "-p", "/data"])
# Set permissions
container.exec(["chmod", "755", "/data"])
# List files
exit_code, output = container.exec(["ls", "-la", "/data"])
Service Management¶
with GenericContainer("nginx:alpine") as container:
# Check service status
exit_code, output = container.exec(["nginx", "-t"])
# Reload configuration
container.exec(["nginx", "-s", "reload"])
Troubleshooting¶
If you encounter issues with command execution:
- Check command syntax and arguments
- Verify user permissions
- Check container state
- Verify command availability
- Check for timeout issues
- Verify environment variables
- Check working directory
- Verify TTY requirements