All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Container
KillAsync—IContainerService.KillAsync(signal = "SIGKILL")for fast, forceful teardown of disposable containers without a graceful stop (#267) - Compose
RestartAsync—IComposeService.RestartAsync()andRestartAsync(services)to restart a whole project or individual services (#318) - Builder interactive/entrypoint options —
WithInteractive(),WithTty(), andWithEntrypoint(...)to keep short-lived images alive forExecuteAsyncand to override the entrypoint (#264) - In-place image builds —
DockerfileBuilder.WithBuildContext(...)builds an existing Dockerfile in place via the engine's--file, leaving no generatedDockerfilebehind (#280) - Attach to an existing compose project —
IComposeBuilder.ConnectToExisting()returns a service bound to a running project withoutdocker compose up, plusIComposeService.RefreshStateAsync()to read live state (#305) - Custom container CLI —
IDockerCliDriverBuilder.WithBinary("finch"/"nerdctl", ...)drives docker-compatible engines without aliasing them todocker(best-effort) (#315) - Log source tagging —
IStreamDriver.StreamLogEntriesAsync(...)yieldsLogEntryvalues tagged withLogStreamSource(stdout/stderr); the Docker Engine API driver reports the real source from the multiplexed stream (#326)
ExecuteOnRunning/ExecuteOnDisposingsemantics — each string argument is now executed as a separate command (restoring the v2 contract); Running commands run after wait conditions, exactly once, and command failures now surface instead of being swallowed (#283)
GetConfigurationinspect parsing —NetworkSettings.LinkLocalIPv6PrefixLen,GlobalIPv6PrefixLenandIPPrefixLenare emitted by the engine as JSON numbers; a tolerantstringconverter prevents theDriverException: Failed to inspect containerregression introduced by the System.Text.Json switch (#335)
- Added an "Inspecting Container Info" section showing how to read the created date, image config, environment, exposed ports, labels, and the mapped host port (#197)
- Multi-driver kernel architecture —
FluentDockerKernelmanages multiple driver packs (IDriverPack) viaIDriverRegistrywith async lifecycle - Docker Engine API driver — full REST API driver communicating over Unix socket, named pipe, or TCP+TLS; 8 component drivers (Container, Image, Network, Volume, System, Auth, Stream, Service) with automatic API version negotiation
- Podman CLI driver — complete Podman CLI integration with binary resolution, container/image/network/volume/pod/manifest operations, and machine management
- Fluent builder system —
BuilderwithWithinDriver()entry point and lambda-based sub-builders for containers, networks, volumes, compose, images, and pods - Wait conditions — port, HTTP, process, log, health check, and custom lambda wait conditions with configurable timeouts and poll intervals
- Testing framework —
FluentDocker.Testing.Xunit,FluentDocker.Testing.NUnit,FluentDocker.Testing.MsTestpackages with resource lifecycle management (ContainerResource,ComposeResource,TopologyResource,ImageResource,NetworkResource,VolumeResource) - Orphan cleanup — label-based session tracking (
fluentdocker.session) withOrphanCleanuputility for sweeping leaked containers - Security builder methods —
WithCapAdd,WithCapDrop,WithSecurityOpt,WithReadonlyRootfs,WithShmSize,WithTmpfs,WithDevice,WithPlatform,WithRuntime - Builder validation —
Validate()at build time catches missing images, invalid port mappings, and conflicting options - Volume model expansion —
Mountpoint,Labels,Options,UsageDataproperties - XML documentation file — NuGet package now includes IntelliSense XML docs
- CI/CD — GitHub Actions with OS matrix, scheduled integration tests, pack validation
- Async-first API — all driver and service operations are async with
CancellationTokensupport IDriverPackextendsIDriverInterfaceResolver— eliminates cast patterns; packs directly supportTryResolveandGetSupportedInterfaces- Central package management —
Directory.Packages.propsfor dependency version control - Nullable annotations — enabled across all projects
- .NET 8 + .NET 10 multi-targeting
IService(sync) — useIServiceAsyncinstead; sync methods wrap async with.GetAwaiter().GetResult()which can deadlockFluentDocker.Model.Containers.CommandResponse<T>— useFluentDocker.Model.Drivers.CommandResponse<T>insteadFluentDocker.Services.NetworkCreateConfig— useFluentDocker.Drivers.NetworkCreateConfiginsteadIFeature,FeatureAttribute,FeatureConstants— v2 legacy types, will be removed in v4
- Legacy
Fdstatic helper class - Old Docker Machine command argument structures
FluentDocker.XUnitandFluentDocker.MsTestpackages (replaced byFluentDocker.Testing.*)DriverComponentenum andISysCtl.SysCtl(string, DriverComponent)overload — use genericSysCtl<T>(driverId)orSysCtl(driverId, Type)instead
- Process resource leaks —
Processobjects now properly disposed viausingin CLI driver bases - Process orphaning on cancellation — child processes killed on
CancellationTokencancellation - API version negotiation race — thread-safe one-time negotiation with
SemaphoreSlim - sudo password exposure — password no longer passed as CLI argument; uses stdin redirection
- Registry password on CLI —
--password-stdinis now the default DriverRegistryTOCTOU race — registration uses lock around check-initialize-add sequence- HTTP wait timeout reset — uses remaining time instead of full timeout per iteration
- Docker stream header parsing — operates on raw bytes to handle multi-byte UTF-8 correctly
- Docker CLI logs — now includes stderr output (Docker writes logs to stderr by default)
- Entrypoint quoting — only passes the executable as
--entrypoint; args go toCmd - Env var quoting — values with spaces or metacharacters are now properly quoted
- Stream disposal —
usingon API stream connections prevents leaks on early cancellation FluentDockerKernel.Disposedeadlock — usesTask.Runto avoid sync-context deadlock- Build warnings — eliminated 995 build warnings across all projects (zero-warning build)
- Process output reading: replaced event-based
BeginOutputReadLinewithReadToEndAsyncto fix async flush race conditions - Per-call
HttpClientcreation replaced with shared instance in Docker API driver Stopwatchused for timing instead ofDateTime.UtcNowsubtraction- CLI argument quoting for values containing spaces and shell metacharacters
ContinueWithusage replaced with properawaitpatterns
See GitHub releases for v2.x history.