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.
Documentation
License
Apache-2.0
Contributing
Contributions are welcome! Please see the main repository for details.