Skip to main content
Build a compact Rust CLI to manage Docker: list containers/images, start/stop containers, and pull images. This guide walks through scaffolding the project, adding async Docker support with Bollard, parsing commands with Clap, organizing a modular code layout, and implementing the core commands.
A presentation slide titled "Project: Manage Docker Containers using Docker Clients in Rust." A teal-blue curved shape on the right shows a white monitor/code icon, with a small "© Copyright KodeKloud" in the bottom-left.
Prerequisites
  • Rust toolchain (rustup + cargo)
  • Docker running locally (Docker Desktop on macOS/Windows or Docker daemon on Linux)
  • Basic familiarity with async/await in Rust
  • Optional: VS Code (or your preferred editor)
Create the project From your projects directory:
After this, your project will contain the standard Rust layout (Cargo.toml, src/main.rs, etc.).
A dark-themed Visual Studio Code window showing the Explorer pane with a Rust project named "MYDOCKER" (files like Cargo.toml, src, .gitignore) on the left. The main area displays a large VS Code logo and keyboard shortcut hints (Show All Commands, Go to File, Find in Files, etc.).
Add dependencies (Cargo.toml) Open Cargo.toml and add these dependencies. Bollard provides the async Docker API client, Clap handles CLI parsing, Tokio is the async runtime, and futures-util gives helper utilities.
Download dependencies once:
Dependency reference table Project structure We will keep the code modular:
  • src/cli.rs — Clap definitions (commands/subcommands)
  • src/docker.rs — DockerClient wrapper around Bollard
  • src/main.rs — Top-level wiring and command dispatch
CLI: define the command structure (using Clap) Create src/cli.rs and define a clear subcommand hierarchy for list/start/stop/pull.
CLI usage hierarchy
  • mydocker list containers [—all | -a]
  • mydocker list images
  • mydocker start <container_name>
  • mydocker stop <container_name>
  • mydocker pull <image_name>
Quick help example:
Callout — Docker socket and Docker Desktop
Ensure Docker is running (Docker Desktop or a daemon on Linux). The typical Docker socket path on Linux is /var/run/docker.sock. On Docker Desktop (macOS/Windows) the socket path may differ — use docker context inspect to find the “Host” value and adjust the socket path in DockerClient::new if needed.
Example output of docker context inspect (used to discover socket path):
Docker client module Create src/docker.rs. This module wraps Bollard to provide the operations we need: listing containers/images, starting/stopping containers, and pulling images. The implementation uses async functions returning Result types mapped to Bollard errors.
Top-level main Create or update src/main.rs to wire the CLI and DockerClient together, then dispatch subcommands. We use Tokio for async main.
CLI commands and examples Run & test examples
  • Show general help:
  • List running containers:
  • List all containers, including stopped:
  • List images:
  • Start a container:
  • Stop a container:
  • Pull an image:
Notes and behavior
  • Docker returns many optional fields (names, status, IDs). The example code uses unwrap_or_default() to avoid panics and print reasonable defaults.
  • Bollard’s create_image returns a stream of progress messages — the client consumes and prints these lines to provide visible progress.
  • If a resource does not exist, Docker returns an error (often a 404-like response). The CLI forwards the error message returned by the Docker daemon to stderr.
Callout — Permissions and socket path
If you use a Unix socket (e.g., /var/run/docker.sock) your user needs permission to access that socket (membership in the docker group, or run the binary with appropriate privileges). On macOS/Windows with Docker Desktop, the socket path may differ — use docker context inspect to find the socket path and adjust DockerClient::new accordingly.
Extending the project This modular structure makes it straightforward to add features:
  • container inspect, remove, exec
  • filtering lists by labels, status, or health
  • richer output formatting (JSON, table)
  • authentication support for pulling from private registries
Summary
  • Built a small Rust CLI (mydocker) using Clap for argument parsing and Bollard for Docker API access.
  • Organized code into src/cli.rs, src/docker.rs, and src/main.rs for clarity and maintainability.
  • Implemented list (containers/images), start, stop, and pull commands with async/await using Tokio.
  • The project is a solid foundation to grow into a full-featured Docker management tool in Rust.
Links and references

Watch Video