FluentDocker
FluentDocker is a .NET library providing a fluent API for Docker and Docker Compose. It simplifies container management for development, testing, and CI/CD pipelines.
New Here?
Start with this sequence:
- Learning Path for a beginner-to-advanced map
- Getting Started for your first working container
- One focused topic: Containers or Compose
What’s New in v3.0.0
- Namespace renamed:
Ductus.FluentDocker→FluentDocker - Full async/await support with CancellationToken
- Driver Layer architecture replacing Commands namespace
- Kernel + WithinDriver() scoping for multi-driver support
- Lambda-based builder API —
UseContainer(Action<IContainerBuilder>) - Container Stats — CPU, memory, network monitoring
- Label-based filtering — 5.5x faster container cleanup
- Static IPv4/IPv6 assignment for containers
- Directory copy support (recursive)
- Docker Compose V2 — uses
docker compose
See the Migration Guide for upgrading from v2.x.
Quick Start (Beginner)
using System.Linq;
using FluentDocker.Builders;
using FluentDocker.Kernel;
// Multiple kernels per app are supported.
using var kernel = await FluentDockerKernel.Create()
.WithDockerCli("docker", d => d.AsDefault())
.BuildAsync();
1) Run one container
using FluentDocker.Services.Extensions;
await using var results = await new Builder()
.WithinDriver("docker", kernel)
.UseContainer(c => c
.UseImage("nginx:alpine")
.ExposePort("80")
.WaitForPort("80/tcp", 30000))
.BuildAsync();
var endpoint = results.Containers.First()
.ToHostExposedEndpoint("80/tcp");
Console.WriteLine($"Endpoint: {endpoint.Address}:{endpoint.Port}");
2) Run multi-service compose
await using var results = await new Builder()
.WithinDriver("docker", kernel)
.UseCompose(c => c
.WithComposeFile("docker-compose.yml")
.WithRemoveOrphans()
.WithWait()
.WithWaitTimeout(30))
.BuildAsync();
var compose = results.ComposeServices.First();
Advanced Quick Samples
Podman container runtime
using var kernel = await FluentDockerKernel.Create()
.WithPodmanCli("podman", d => d.WithAutoStartMachine().AsDefault())
.BuildAsync();
await using var results = await new Builder()
.WithinDriver("podman", kernel)
.UseContainer(c => c
.UseImage("nginx:alpine")
.ExposePort("80")
.WaitForPort("80/tcp", 30000))
.BuildAsync();
Podman Kubernetes (kube play / kube down)
using FluentDocker.Drivers.Podman;
using FluentDocker.Kernel;
using FluentDocker.Model.Drivers;
using var kernel = await FluentDockerKernel.Create()
.WithPodmanCli("podman", d => d.WithAutoStartMachine().AsDefault())
.BuildAsync();
var context = new DriverContext("podman");
var kube = kernel.SysCtl<IPodmanKubernetesDriver>("podman");
await kube.PlayAsync(context, new KubePlayConfig { YamlPath = "pod.yaml", Replace = true });
await kube.DownAsync(context, "pod.yaml");
DriverContext carries per-operation driver state (driver ID, host URI, certs, sudo, timeouts). End-users only construct one when invoking a driver via SysCtl<T> directly — the builder/kernel flow supplies it implicitly.
Installation
dotnet add package FluentDocker
dotnet add package FluentDocker.Testing.Xunit # xUnit adapter
dotnet add package FluentDocker.Testing.MsTest # MSTest adapter
dotnet add package FluentDocker.Testing.NUnit # NUnit adapter
Documentation by Level
Level 1: Start Here
| Topic | Description |
|---|---|
| Learning Path | Recommended beginner to advanced journey |
| Getting Started | Installation, prerequisites, first container |
| Containers | Core lifecycle, ports, env vars, waits |
| Docker Compose | First multi-service workflow |
Level 2: Daily Usage
| Topic | Description |
|---|---|
| Networking | Networks, aliases, static IPs |
| Volumes | Persistence and bind mounts |
| Images | Build image workflows |
| Testing | Testing.Core and adapters |
| Utilities | Helpers and extension methods |
| Error Handling | Exceptions and error codes |
Level 3: Advanced
| Topic | Description |
|---|---|
| Architecture | Kernel/driver internals and async model |
| Driver Extensibility | Driver-aware extension model |
| Migration | Upgrade from v2.x to v3.x |
Architecture
FluentDocker uses a three-layer architecture:
┌─────────────────────────────────┐
│ Fluent API │ Builder pattern
├─────────────────────────────────┤
│ Services Layer │ Container, Network, Volume
├─────────────────────────────────┤
│ Driver Layer │ Docker CLI, API, Podman
└─────────────────────────────────┘
Linux Users
Docker requires sudo by default. Configure via the kernel builder:
using FluentDocker.Model.Common;
using var kernel = await FluentDockerKernel.Create()
.WithDockerCli("docker", d => d
.WithSudo(SudoMechanism.NoPassword)
.AsDefault())
.BuildAsync();
Or avoid sudo entirely: sudo usermod -aG docker $USER
Resources
License
Apache 2.0 - See LICENSE.