lmrc-docker

Crates.iolmrc-docker
lib.rslmrc-docker
version0.3.16
created_at2025-11-26 17:44:33.657954+00
updated_at2025-12-11 13:27:11.396961+00
descriptionDocker client library for the LMRC Stack - ergonomic fluent APIs for containers, images, networks, volumes, and registry management
homepagehttps://gitlab.com/lemarco/lmrc-stack/tree/main/libs/docker-manager
repositoryhttps://gitlab.com/lemarco/lmrc-stack
max_upload_size
id1951917
size151,854
Le Marc (lemarco)

documentation

https://docs.rs/lmrc-docker

README

lmrc-docker

Part of the LMRC Stack - Infrastructure-as-Code toolkit for building production-ready Rust applications

Crates.io Documentation License

An ergonomic, comprehensive Docker client library for Rust with fluent builder APIs for managing containers, images, networks, volumes, and registries.

Features

  • Fluent Builder APIs: Ergonomic, chainable methods for creating and configuring Docker resources
  • Full Docker API Coverage: Complete support for containers, images, networks, and volumes
  • Registry Management: Search, authenticate, and manage images across multiple registries (Docker Hub, GitHub Container Registry, custom registries)
  • Async/Await: Built on Tokio for modern async Rust
  • Type-Safe: Leverages Rust's type system for compile-time safety
  • Comprehensive Error Handling: Detailed error types using thiserror
  • Well Documented: Extensive documentation and examples

Installation

Add this to your Cargo.toml:

[dependencies]
lmrc-docker = "0.1"
tokio = { version = "1.0", features = ["full"] }

Quick Start

use lmrc_docker::{DockerClient, Result};

#[tokio::main]
async fn main() -> Result<()> {
    // Create a client
    let client = DockerClient::new()?;

    // Check Docker is available
    client.ping().await?;

    // Pull an image
    client.images().pull("nginx:alpine", None).await?;

    // Create and start a container
    let container = client.containers()
        .create("nginx:alpine")
        .name("my-nginx")
        .port(8080, 80, "tcp")
        .env("ENV", "production")
        .build()
        .await?;

    container.start().await?;
    println!("Container started: {}", container.id());

    // Stop and remove the container
    container.stop(Some(10)).await?;
    container.remove(false, false).await?;

    Ok(())
}

Examples

Container Management

use lmrc_docker::DockerClient;

let client = DockerClient::new()?;

// Create a container with advanced configuration
let container = client.containers()
    .create("redis:alpine")
    .name("my-redis")
    .port(6379, 6379, "tcp")
    .env("REDIS_PASSWORD", "secret")
    .restart_always()
    .memory_limit(512 * 1024 * 1024) // 512MB
    .build()
    .await?;

// Start the container
container.start().await?;

// View logs
let logs = container.logs(true, true, true, None).await?;
println!("Logs: {}", logs);

// Execute a command
let exec_id = container.exec(vec!["redis-cli".into(), "ping".into()], false).await?;

// Stop and remove
container.stop(Some(10)).await?;
container.remove(true, true).await?;

Image Operations

use lmrc_docker::DockerClient;

let client = DockerClient::new()?;

// Pull an image
client.images().pull("alpine:latest", None).await?;

// Build an image from a Dockerfile
let image_id = client.images()
    .build("./my-app")
    .tag("my-app:latest")
    .dockerfile("Dockerfile")
    .cache_from(vec!["my-app:cache"])
    .execute()
    .await?;

// Push to registry (requires authentication)
client.images().push("username/my-app:latest", None).await?;

// List images
let images = client.images().list(false).await?;
for image in images {
    println!("Image: {:?}", image.repo_tags);
}

// Remove an image
client.images().remove("my-app:latest", false, false).await?;

Registry Management

use lmrc_docker::{DockerClient, RegistryConfig};

let client = DockerClient::new()?;
let registry = client.registry();

// Search for images
let results = registry.search("nginx", Some(10)).await?;
for result in results {
    println!("{}: {} stars", result.name, result.star_count.unwrap_or(0));
}

// Authenticate with Docker Hub
let config = RegistryConfig::docker_hub(
    "username".to_string(),
    "password".to_string()
);
registry.login(&config).await?;

// Authenticate with GitHub Container Registry
let config = RegistryConfig::github(
    "username".to_string(),
    "github_token".to_string()
);
registry.login(&config).await?;

// Check if an image exists locally
let exists = registry.image_exists_locally("alpine:latest").await?;

// Tag an image
registry.tag_image("alpine:latest", "my-alpine", Some("v1.0")).await?;

// Export/Import images
let tar_data = registry.export_image("alpine:latest").await?;
let image_id = registry.import_image(tar_data, Some("imported:latest")).await?;

// Prune unused images
let reclaimed = registry.prune_images(true).await?;
println!("Reclaimed {} bytes", reclaimed);

Network Management

use lmrc_docker::DockerClient;

let client = DockerClient::new()?;

// Create a network
let network = client.networks()
    .create("my-network")
    .driver("bridge")
    .await?;

// Connect a container to a network
network.connect("container-id", None).await?;

// Disconnect a container
network.disconnect("container-id", false).await?;

// List networks
let networks = client.networks().list().await?;

// Remove network
network.remove().await?;

Volume Management

use lmrc_docker::DockerClient;

let client = DockerClient::new()?;

// Create a volume
let volume = client.volumes()
    .create("my-volume")
    .driver("local")
    .await?;

// List volumes
let volumes = client.volumes().list().await?;

// Remove volume
volume.remove(false).await?;

// Prune unused volumes
let pruned = client.volumes().prune().await?;

Configuration

Custom Docker Connection

use lmrc_docker::{DockerClient, DockerClientConfig};

// Connect via Unix socket
let client = DockerClient::connect_with_unix("/var/run/docker.sock")?;

// Connect via TCP
let client = DockerClient::connect_with_tcp("localhost:2375")?;

// Custom configuration
let config = DockerClientConfig::new()
    .timeout(60)
    .api_version("1.43");
let client = DockerClient::with_config(config)?;

Environment Variables

The client respects the DOCKER_HOST environment variable:

export DOCKER_HOST=tcp://localhost:2375
export DOCKER_HOST=unix:///var/run/docker.sock

Error Handling

The library uses a comprehensive error type system:

use lmrc_docker::{DockerClient, DockerError, Result};

match client.containers().get("unknown-container") {
    Ok(container) => println!("Found container"),
    Err(DockerError::ContainerNotFound(id)) => {
        eprintln!("Container {} not found", id);
    }
    Err(DockerError::Connection(msg)) => {
        eprintln!("Connection error: {}", msg);
    }
    Err(e) => eprintln!("Other error: {}", e),
}

Architecture

The library is organized into modular components:

  • client: Docker client configuration and connection management
  • containers: Container lifecycle operations with ContainerBuilder
  • images: Image operations with ImageBuilder for building images
  • networks: Network creation and management
  • volumes: Volume operations
  • registry: Registry authentication, search, and image management
  • error: Comprehensive error types

Advanced Usage

Direct Bollard Access

For operations not covered by the high-level API:

let client = DockerClient::new()?;
let bollard = client.inner();

// Use bollard directly
let info = bollard.info().await?;

Streaming Logs

use futures_util::StreamExt;

let container = client.containers().get("my-container").await?;
let mut logs_stream = container.logs_stream(true, true, true, None).await?;

while let Some(log) = logs_stream.next().await {
    match log {
        Ok(line) => println!("{}", line),
        Err(e) => eprintln!("Error: {}", e),
    }
}

Requirements

  • Rust 1.70 or later
  • Docker daemon running and accessible

Examples

See the examples directory for complete working examples:

Run examples with:

cargo run --example basic_container
cargo run --example registry_operations

Testing

The library includes integration tests that require a running Docker daemon:

# Run tests
cargo test

# Run specific test
cargo test test_container_lifecycle

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

Part of the LMRC Stack project. Licensed under either of:

at your option.

Acknowledgments

Built on top of Bollard, the excellent Docker daemon API for Rust.

Related Projects

Commit count: 0

cargo fmt