Crates.io | anchor |
lib.rs | anchor |
version | 0.1.3 |
created_at | 2025-06-11 21:25:44.83842+00 |
updated_at | 2025-06-23 08:56:57.075847+00 |
description | A Rust library for managing Docker container clusters through declarative JSON manifests |
homepage | https://github.com/FreddyWordingham/anchor |
repository | https://github.com/FreddyWordingham/anchor |
max_upload_size | |
id | 1709128 |
size | 1,539,860 |
Anchor
Declarative Docker Cluster Management in Rust
A Rust library for managing Docker container clusters from Rust. Anchor simplifies the process of downloading images, building containers, and orchestrating multi-container applications.
Add this to your Cargo.toml
:
[dependencies]
anchor = "0.1.0"
# Enable AWS ECR support (optional)
anchor = { version = "0.1.0", features = ["aws_ecr"] }
use anchor::prelude::*;
use bollard::auth::DockerCredentials;
#[tokio::main]
async fn main() -> AnchorResult<()> {
// Create a Docker client
let client = Client::new(DockerCredentials::default()).await?;
// Check if Docker is running
if !client.is_docker_running().await {
start_docker_daemon()?;
}
// Pull an image
client.pull_image("nginx:latest").await?;
// Create and start a container
let container_id = client.build_container(
"nginx:latest",
"my-nginx",
&[(80, 8080)], // Port mapping: container:host
&[("ENV_VAR", "value")], // Environment variables
&[MountType::bind("/host/path", "/container/path")], // Mounts
).await?;
client.start_container("my-nginx").await?;
// Get container metrics
let metrics = client.get_container_metrics("my-nginx").await?;
println!("Container uptime: {}", metrics.uptime.as_secs());
println!("Memory usage: {}", metrics.memory_usage_display());
println!("CPU usage: {:.1}%", metrics.cpu_percentage);
Ok(())
}
Anchor tracks the lifecycle of Docker resources through the ResourceStatus
enum:
let status = client.get_resource_status("nginx:latest", "my-nginx").await?;
match status {
ResourceStatus::Missing => println!("Need to pull image"),
ResourceStatus::Available => println!("Ready to build container"),
ResourceStatus::Built => println!("Ready to start container"),
ResourceStatus::Running => println!("Container is running"),
}
Anchor supports three types of mounts:
// Bind mount - mount host directory/file into container
let bind_mount = MountType::bind("/host/data", "/app/data");
let readonly_bind = MountType::bind_ro("/host/config", "/app/config");
// Named volume - use Docker-managed volume
let volume_mount = MountType::volume("my-volume", "/app/storage");
let readonly_volume = MountType::volume_ro("config-vol", "/app/config");
// Anonymous volume - create temporary volume
let anon_volume = MountType::anonymous_volume("/tmp/cache");
let readonly_anon = MountType::anonymous_volume_ro("/app/readonly");
Get detailed runtime information about your containers:
let metrics = client.get_container_metrics("my-container").await?;
println!("Uptime: {}", format_duration(metrics.uptime));
println!("Memory: {}", metrics.memory_usage_display());
println!("CPU: {:.1}%", metrics.cpu_percentage);
println!("Network: {}", metrics.network_usage_display());
println!("Disk I/O: {}", metrics.disk_io_display());
println!("Health: {}", metrics.health_status.unwrap_or_default());
When the aws_ecr
feature is enabled, you can authenticate with Amazon ECR:
use anchor::prelude::*;
#[tokio::main]
async fn main() -> AnchorResult<()> {
// Get ECR credentials (requires AWS credentials in environment)
let credentials = get_ecr_credentials().await
.map_err(|e| AnchorError::ECRCredentialsError(e.to_string()))?;
let client = Client::new(credentials).await?;
// Pull from ECR
client.pull_image("123456789012.dkr.ecr.us-west-2.amazonaws.com/my-app:latest").await?;
Ok(())
}
use anchor::prelude::*;
async fn handle_container(client: &Client) -> AnchorResult<()> {
match client.start_container("my-app").await {
Ok(()) => println!("Container started successfully"),
Err(AnchorError::ContainerError { container, message }) => {
eprintln!("Failed to start {}: {}", container, message);
}
Err(AnchorError::ConnectionError(msg)) => {
eprintln!("Docker connection failed: {}", msg);
start_docker_daemon()?;
}
Err(e) => eprintln!("Unexpected error: {}", e),
}
Ok(())
}
use std::time::Duration;
use tokio::time::sleep;
async fn monitor_container_health(client: &Client, name: &str) -> AnchorResult<()> {
loop {
let status = client.get_container_status(name).await?;
if status.is_running() {
let metrics = client.get_container_metrics(name).await?;
if let Some(health) = metrics.health_status {
match health {
HealthStatus::Healthy => println!("â
Container is healthy"),
HealthStatus::Unhealthy => println!("â Container is unhealthy"),
HealthStatus::Starting => println!("đ Health check starting"),
HealthStatus::None => println!("âšī¸ No health check configured"),
}
}
// Alert on high resource usage
if metrics.cpu_percentage > 80.0 {
println!("â ī¸ High CPU usage: {:.1}%", metrics.cpu_percentage);
}
if let Some(mem_pct) = metrics.memory_percentage {
if mem_pct > 80.0 {
println!("â ī¸ High memory usage: {:.1}%", mem_pct);
}
}
}
sleep(Duration::from_secs(30)).await;
}
}
Anchor automatically detects and adapts to your platform:
systemctl
or service
commands to start Docker daemonThe library automatically starts the Docker daemon when needed:
if !client.is_docker_running().await {
start_docker_daemon()?;
}
Anchor provides comprehensive error handling:
DockerNotInstalled
- Docker is not installed on the systemConnectionError
- Cannot connect to Docker daemonECRCredentialsError
- AWS ECR authentication failedImageError
- Image-related operation failedContainerError
- Container-related operation failedIoStreamError
- I/O operation failedThis project is licensed under the MIT License - see the LICENSE file for details.
bollard
- Docker API clienttokio
- Async runtimechrono
- Date and time handlingaws-sdk-ecr
- AWS ECR integration (optional)base64
- Base64 encoding/decodingRust 1.70 or higher is required.