camel-component-container
Docker container component for rust-camel
Overview
The Container component provides Docker container lifecycle management for rust-camel routes. It supports both producer operations (list, run, start, stop, remove containers) and consumer mode (subscribe to Docker events).
Features
- Batteries Included: Auto-pull images, auto-remove containers, sensible defaults
- Container Lifecycle: Create, start, stop, and remove containers
- Event Streaming: Subscribe to Docker daemon events (formatted for readability)
- Container Tracking: Track created containers for cleanup on shutdown (hot-reload safe)
- Header-based Control: Override operations and parameters via exchange headers
- Automatic Cleanup: Orphaned containers are removed if start fails after create
- Reconnection: Consumer automatically reconnects on connection failures
- Graceful Shutdown: Clean cancellation via
CancellationToken
Installation
Add to your Cargo.toml:
[]
= "0.3"
URI Format
container:<operation>[?options]
Operations
| Operation | Mode | Description |
|---|---|---|
list |
Producer | List all containers |
run |
Producer | Create and start a container from an image |
start |
Producer | Start an existing container |
stop |
Producer | Stop a running container |
remove |
Producer | Remove a container |
events |
Consumer | Subscribe to Docker daemon events |
logs |
Consumer | Stream logs from a container |
URI Options
| Option | Default | Description |
|---|---|---|
image |
- | Container image for run operation |
name |
- | Container name for run operation |
cmd |
- | Command to run in container (e.g., sleep 30) |
ports |
- | Port mappings in format hostPort:containerPort (e.g., 8080:80,8443:443) |
env |
- | Environment variables in format KEY=value (e.g., FOO=bar,BAZ=qux) |
network |
- | Network mode (bridge, host, none, or custom network name). When unset, Docker uses bridge by default. |
containerId |
- | Container ID or name for logs consumer |
follow |
true |
Follow log output (logs consumer only) |
timestamps |
false |
Include timestamps in logs (logs consumer only) |
tail |
all |
Number of lines to show from end of logs (e.g., 100) |
autoPull |
true |
Automatically pull image if not present locally |
autoRemove |
true |
Automatically remove container when it exits |
host |
unix:///var/run/docker.sock |
Docker host (Unix socket only) |
Headers
Input Headers (for operations)
| Header | Description |
|---|---|
CamelContainerAction |
Override operation (list, run, start, stop, remove) |
CamelContainerImage |
Container image (required for run) |
CamelContainerId |
Container ID (required for start, stop, remove) |
CamelContainerName |
Container name (optional for run) |
Output Headers (from responses)
| Header | Description |
|---|---|
CamelContainerActionResult |
Operation result (success) |
CamelContainerId |
Created container ID (from run), or container ID for logs |
CamelContainerLogStream |
Log stream type: stdout, stderr, console (logs consumer only) |
CamelContainerLogTimestamp |
Log timestamp when timestamps=true (logs consumer only) |
Usage
Simple Container Run (Batteries Included)
The simplest way to run a container - just specify the image:
use ;
use ContainerComponent;
let route = from
.to
.to
.build?;
This will:
- Pull
alpine:latestif not present (autoPull=trueby default) - Run
sleep 30in the container - Auto-remove the container when it exits (
autoRemove=true)
Listing Containers
use ;
use ContainerComponent;
let route = from
.to
.to
.build?;
Running a Container with Custom Name
let route = from
.set_header
.set_header
.to
.to
.build?;
Running a Web Server with Port Mapping
// Run nginx with port 8080 on host → 80 in container
let route = from
.to
.to
.build?;
Note: If port mapping doesn't work on your system (firewall issues), use
network=hostinstead. The container will share the host's network stack and ports don't need mapping:.to // nginx will be accessible at http://localhost:80
Running a Container with Environment Variables
// Run a container with custom environment variables
let route = from
.to
.to
.build?;
Stopping and Removing a Container
let route = from
.set_header
.to
.to
.build?;
Subscribing to Docker Events
Events are formatted for readability:
[CREATE] Container my-container (alpine:latest)
[START] Container my-container
[DIE] Container my-container (exit: 0)
[DESTROY] Container my-container
let route = from
.to
.build?;
Dynamic Operation via Header
// Override operation at runtime
let route = from
.set_header
.to // Base URI, overridden by header
.build?;
Streaming Container Logs
The logs consumer streams log output from a container:
// Stream logs from a container
let route = from
.to
.build?;
Each log line becomes an exchange with:
- Body: The log line content
- CamelContainerId: Container ID/name
- CamelContainerLogStream:
stdoutorstderr - CamelContainerLogTimestamp: Timestamp (when
timestamps=true)
Options:
follow=true(default): Stream new logs as they arrivefollow=false: Get historical logs and exittail=100: Get last 100 lines onlytimestamps=true: Include Docker timestamps
# YAML DSL example
routes:
- id: "nginx-logs"
from: "container:logs?containerId=nginx-demo×tamps=true"
steps:
- log: "[${header.CamelContainerLogStream}] ${body}"
Error Handling
The component provides clear, actionable error messages:
- Image not found:
Image 'foo' not found locally. Set autoPull=true to pull automatically, or run: docker pull foo - Auth required:
Authentication required for image 'private/image'. Configure Docker credentials: docker login - Container conflict:
Container name 'my-container' already exists. Use a unique name or remove the existing container first - Missing headers: Specific messages indicating which header is required
- Connection failures: Clear Docker daemon connection errors
Known Limitations
- Unix socket only: TCP/TLS Docker hosts are not supported
- No event filtering: The
eventsconsumer receives all Docker events - Limited
runoptions: Volumes and advanced networking options are not configurable - No image operations:
pull,build,push,tagare not implemented (useautoPull=trueinstead) - No
exec: Running commands inside containers is not supported
Example: Full Lifecycle
use ;
use ;
use ;
use ;
use DirectComponent;
use LogComponent;
use TimerComponent;
use CamelContext;
async
YAML DSL
The container component works with the YAML DSL:
routes:
- id: "container-monitor"
from: "timer:tick?period=60000"
steps:
- log: "Listing containers..."
- to: "container:list"
- to: "log:info?showBody=true"
- id: "run-container"
from: "timer:run?period=30000"
steps:
- to: "container:run?image=alpine:latest&cmd=sleep 10&autoRemove=true"
- to: "log:info?showHeaders=true"
- id: "container-events"
from: "container:events"
steps:
- log: "${body}"
Cleanup on Shutdown
Containers created via run operation are tracked globally. Call cleanup_tracked_containers() on shutdown to force-remove any containers that are still running:
use cleanup_tracked_containers;
async
This is especially important for:
- Hot-reload scenarios: Prevents orphaned containers when the application restarts
- Long-running containers: Ensures cleanup even if containers haven't finished naturally
- Graceful shutdown: Guarantees no containers are left behind
Note: With autoRemove=true (the default), Docker will automatically remove containers when they exit naturally. The cleanup function handles cases where the application exits before containers finish.
Global Configuration
Configure default Docker host in Camel.toml that applies to all Container endpoints:
[]
= "unix:///var/run/docker.sock" # Docker daemon socket (default)
Remote Docker Host
[]
= "tcp://docker-proxy:2375" # TCP socket (note: only Unix sockets fully supported)
URI parameter host always overrides global default:
// Uses global docker_host
.to
// Overrides to use different host
.to
Documentation
License
Apache-2.0
Contributing
Contributions are welcome! Please see the main repository for details.