3 Popular Crates for Working with Containers in Rust

Hey there, Rustaceans! 🦀 Let’s talk containers.

3 Popular Crates for Working with Containers in Rust

Hey there, Rustaceans! 🦀 Let’s talk containers.

In this article, we’re diving into three crates that are making waves in the Rust container ecosystem: shiplift, bollard, and dockworker. Whether you're a seasoned pro or just dipping your toes into the world of containers, these crates are like having a Swiss Army knife in your toolbox. Let's explore what makes them so cool, shall we? 🌊🚀

1. Shiplift: A Versatile Interface to Docker

Shiplift is a Rust crate designed to interact with the Docker daemon, providing a high-level API to manage Docker containers and images. It abstracts the complexities of Docker’s API, offering Rust developers a more accessible and idiomatic way to control their containerized environments.

Key Components

Shared Traits and Structures:

  • Docker: The core structure in Shiplift. It serves as the entry point to interact with the Docker daemon.
  • Image and Container Builders: These builders provide a fluent interface to create and manage Docker images and containers.

Code Example: Creating a Docker instance

use shiplift::Docker; 
 
fn main() { 
    let docker = Docker::new(); 
    // Now you can use `docker` to interact with the Docker daemon 
}

Container Management:

  • Starting and Stopping Containers: Shiplift allows you to start, stop, and manage the lifecycle of containers.
  • Executing Commands: Run commands inside running containers.

Code Example: Starting a Container

use shiplift::{Docker, ContainerOptions}; 
 
#[tokio::main] 
async fn main() { 
    let docker = Docker::new(); 
    let container = docker.containers() 
                          .create(&ContainerOptions::builder("hello-world").build()) 
                          .await.unwrap(); 
    container.start().await.unwrap(); 
    // The container starts executing here 
}

Image Management:

  • Pulling and Pushing Images: Handle Docker images, allowing you to pull from or push to registries.
  • Building Images: Build Docker images directly from your Rust code.

Code Example: Pulling an Image

use shiplift::Docker; 
 
#[tokio::main] 
async fn main() { 
    let docker = Docker::new(); 
    let images = docker.images(); 
    images.pull(&Default::default()).await.unwrap(); 
    // Pulls the specified image 
}

Log Streaming:

  • Stream Logs: Fetch and stream logs from a running container, crucial for debugging and monitoring.

Code Example: Streaming Container Logs

use shiplift::{Docker, LogsOptions}; 
 
#[tokio::main] 
async fn main() { 
    let docker = Docker::new(); 
    let logs = docker.containers() 
                     .get("container_id") 
                     .logs(&LogsOptions::builder().stdout(true).build()) 
                     .await.unwrap(); 
    for line in logs { 
        println!("{}", line.unwrap()); 
    } 
}

Advanced Features

Network and Volume Management:

  • Manage Docker networks and volumes, essential for complex container setups.

Interaction with Docker Compose:

  • Although Shiplift doesn’t directly interface with Docker Compose, it can be used alongside it for more advanced container orchestration.

2. Navigating Container Operations in Rust with Bollard

Bollard leverages Rust’s asynchronous features to interact with the Docker API, offering a modern, efficient way to handle container operations. It’s designed for Rust applications that need to create, manage, or orchestrate Docker containers and images.

2. Key Components of Bollard

Docker API Client:

  • The primary entry point for interacting with the Docker daemon.
  • Facilitates various operations like container management, image operations, and more.

Code Example: Creating a Docker API Client

use bollard::Docker; 
 
#[tokio::main] 
async fn main() { 
    let docker = Docker::connect_with_unix_defaults().unwrap(); 
    // Now you can use `docker` to interact with the Docker API 
}

Container Management:

  • Comprehensive functionalities for creating, starting, stopping, and inspecting containers.
  • Includes advanced features like pausing, unpausing, and removing containers.

Code Example: Running a Container

use bollard::container::{CreateContainerOptions, Config}; 
 
#[tokio::main] 
async fn main() { 
    let docker = Docker::connect_with_unix_defaults().unwrap(); 
    let options = Some(CreateContainerOptions { 
        name: "my_container", 
    }); 
    let config = Config { 
        image: Some("hello-world"), 
        ..Default::default() 
    }; 
    let _ = docker.create_container(options, config).await; 
    // Code to start the container 
}

Image Operations:

  • Pull, push, build, and manage Docker images.
  • Handle image registries and tag images.

Code Example: Pulling an Image

use bollard::image::CreateImageOptions; 
 
#[tokio::main] 
async fn main() { 
    let docker = Docker::connect_with_unix_defaults().unwrap(); 
    let image_options = Some(CreateImageOptions { 
        from_image: "hello-world", 
        ..Default::default() 
    }); 
    let _ = docker.create_image(image_options, None, None).await; 
    // Code to handle the pulled image 
}

Network and Volume Management:

  • Create, inspect, and manage Docker networks and volumes.
  • Essential for setting up complex container environments.

Advanced Features and Real-World Use Cases

Bollard is not just limited to basic container and image operations. It also offers:

  • Stream processing: Attach to container streams for logs and events.
  • Exec API: Run commands in a running container.
  • Swarm Management: Interact with Docker’s swarm mode for clustering and orchestration.

In real-world scenarios, Bollard is used in:

  • Automated testing environments.
  • CI/CD pipelines for building, testing, and deploying applications.
  • Microservice orchestration in complex application architectures.

3. Simplifying Docker Operations in Rust with Dockworker

Dockworker is a Rust crate designed for interacting with the Docker Remote API. It allows Rust developers to control Docker containers and images directly from their Rust applications, offering an array of functionalities that are both powerful and user-friendly.

Key Components of Dockworker

Docker API Client:

  • Acts as the gateway for all interactions with the Docker daemon.
  • Facilitates operations like container and image management.

Code Example: Creating a Docker Client

use dockworker::Docker; 
 
fn main() { 
    let docker = Docker::connect_with_defaults().unwrap(); 
    // `docker` is now ready to interact with the Docker daemon 
}

Container Operations:

  • Comprehensive tools for creating, starting, stopping, and inspecting Docker containers.
  • Also allows for more advanced functionalities like pausing and removing containers.

Code Example: Running a Container

use dockworker::{Docker, ContainerCreateOptions}; 
 
fn main() { 
    let docker = Docker::connect_with_defaults().unwrap(); 
    let options = ContainerCreateOptions::new("hello-world:latest"); 
    let container = docker.create_container(None, &options).unwrap(); 
    docker.start_container(&container.id).unwrap(); 
    // The container is now running 
}

Image Management:

  • Provides the ability to pull, push, and manage Docker images.
  • Essential for handling image repositories and versioning.

Code Example: Pulling an Image

use dockworker::Docker; 
 
fn main() { 
    let docker = Docker::connect_with_defaults().unwrap(); 
    docker.pull_image("hello-world:latest", None, None, None).unwrap(); 
    // The image is now pulled and ready to use 
}

Stream Processing:

  • Allows attachment to container streams to fetch logs and events.
  • Crucial for monitoring and debugging running containers.

Code Example: Fetching Container Logs

use dockworker::{Docker, ContainerCreateOptions, ContainerLogOptions}; 
 
fn main() { 
    let docker = Docker::connect_with_defaults().unwrap(); 
    let options = ContainerCreateOptions::new("hello-world:latest"); 
    let container = docker.create_container(None, &options).unwrap(); 
    let logs = docker.logs(&container.id, &ContainerLogOptions::default()).unwrap(); 
    for log in logs { 
        println!("{}", log); 
    } 
    // Logs from the container are printed to the console 
}

Shiplift, bollard, and dockworker each cater to different needs and preferences within the Rust community, from complex, asynchronous operations to simple, straightforward container management.

Whether you’re building large-scale, high-performance applications or just starting with containerization, Rust’s container ecosystem has the tools you need to succeed.

🚀 Explore a Wealth of Resources in Software Development and More by Luis Soares

đź“š Learning Hub: Expand your knowledge in various tech domains, including Rust, Software Development, Cloud Computing, Cyber Security, Blockchain, and Linux, through my extensive resource collection:

  • Hands-On Tutorials with GitHub Repos: Gain practical skills across different technologies with step-by-step tutorials, complemented by dedicated GitHub repositories. Access Tutorials
  • In-Depth Guides & Articles: Deep dive into core concepts of Rust, Software Development, Cloud Computing, and more, with detailed guides and articles filled with practical examples. Read More
  • E-Books Collection: Enhance your understanding of various tech fields with a series of free e-Books, including titles like “Mastering Rust Ownership” and “Application Security Guide” Download eBook
  • Project Showcases: Discover a range of fully functional projects across different domains, such as an API Gateway, Blockchain Network, Cyber Security Tools, Cloud Services, and more. View Projects
  • LinkedIn Newsletter: Stay ahead in the fast-evolving tech landscape with regular updates and insights on Rust, Software Development, and emerging technologies by subscribing to my newsletter on LinkedIn. Subscribe Here

đź”— Connect with Me:

  • Medium: Read my articles on Medium and give claps if you find them helpful. It motivates me to keep writing and sharing Rust content. Follow on Medium
  • Personal Blog: Discover more on my personal blog, a hub for all my Rust-related content. Visit Blog
  • LinkedIn: Join my professional network for more insightful discussions and updates. Connect on LinkedIn
  • Twitter: Follow me on Twitter for quick updates and thoughts on Rust programming. Follow on Twitter

Wanna talk? Leave a comment or drop me a message!

All the best,

Luis Soares

Senior Software Engineer | Cloud Engineer | SRE | Tech Lead | Rust | Golang | Java | ML AI & Statistics | Web3 & Blockchain

Read more