Releases: mariotoffia/FluentDocker
Release list
FluentDocker 3.1.0
FluentDocker 3.1.0 builds on the v3 rewrite with a batch of fluent-API additions, a couple of correctness fixes, and expanded engine support. All changes ship with unit tests.
✨ Added
- Container
Kill—IContainerService.KillAsync(signal = "SIGKILL")for fast, forceful teardown of disposable containers without a graceful stop. (#267) - Compose
Restart—IComposeService.RestartAsync()andRestartAsync(services)to restart a whole project or specific services. (#318) - Interactive / TTY / entrypoint —
WithInteractive(),WithTty()andWithEntrypoint(...)on the container builder, so short-lived images (e.g. SDK images) can be kept alive forExecuteAsync. (#264) - In-place image builds —
DockerfileBuilder.WithBuildContext(...)builds an existing Dockerfile in place via the engine's--file, so no generatedDockerfileis left in your working directory. (#280) - Attach to an existing compose project —
IComposeBuilder.ConnectToExisting()returns a service bound to a running project withoutdocker compose up, plusIComposeService.RefreshStateAsync()to read its live state. (#305) - Custom docker-compatible CLI —
IDockerCliDriverBuilder.WithBinary("finch" / "nerdctl", ...)drives 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)
🔧 Changed
ExecuteOnRunning/ExecuteOnDisposingnow execute each string argument as a separate command (restoring the v2 contract). Running commands fire after wait conditions, exactly once, and command failures surface instead of being silently swallowed. (#283)
🐞 Fixed
GetConfigurationinspect parsing — the engine returnsNetworkSettings.LinkLocalIPv6PrefixLen,GlobalIPv6PrefixLenandIPPrefixLenas JSON numbers; a tolerant string converter prevents theDriverException: Failed to inspect containerregression introduced by the move to System.Text.Json. (#335)
📖 Documentation
- Added an "Inspecting Container Info" guide: created date, image config, environment, exposed ports, labels, and the mapped host port. (#197)
Full Changelog: 3.0.1...3.1.0
FluentDocker 3.0.1
A small post-3.0.0 patch with one production bug fix and a release-pipeline rebuild that removes the GitVersion plumbing that caused the 3.0.0 launch trouble.
Fixed
OsExtensions.ToMsysPathno longer throwsIndexOutOfRangeExceptionon empty or short input on Windows. Inputs shorter than<drive>:<sep>are returned unchanged, matching the existing non-Windows passthrough.
Changed
- Release versioning centralised: the NuGet version is now defined once in
Directory.Build.propsas<Version>and inherited by every packable project. GitVersion (and its+semver:-marker /next-version:/prevent-increment-of-merged-branch-versionknobs) has been removed frommaster. Bumping a release is now a one-line edit; CI reads the value viadotnet msbuild -getProperty:Versionand uses it for both NuGet pack and the git tag. Thesupport/2.xbranch retains the old GitVersion-based flow for v2 hotfix releases. ImageBuilderTestsandKernelBuilderTestsare nowCategory=Integrationbecause they build a realFluentDockerKernel.WithDockerCli(...)that resolves the host docker binary. They were running on macOS/Windows CI runners (without Docker) and failing the unit-test matrix.- Windows-specific test assertions repaired:
DockerBinary/PodmanBinaryFqPathtests now build their expected path viaPath.Combine(so they pass with\on Windows);DockerApiConnectionTimeoutTestsaccept eitherHttpRequestException(Linux/macOS) orTaskCanceledException(Windows timing out on an unreachable port). - README restructured: Quick Start is the first content section, a one-line v3.0.0 banner with links to the release notes and migration guide sits above the Features section,
.NETbadge now reflects bothnet8.0andnet10.0, and a "latest release" badge has been added.
Repository housekeeping
support/2.xmaintenance branch was cut from the v2.85.0 master tip during the 3.0.0 release so v2 users can still receive hotfix releases.FluentDocker.Benchmarksis nowIsPackable=false(it was accidentally getting published).- Pages-docs workflow no longer blocks deploys when the auto-generated API reference step fails (XMLDoc2Markdown 5.x can't currently resolve the net10 ref-assembly chain — tracked for a follow-up to swap in docfx or xmldocmd).
Full Changelog: 3.0.0...3.0.1
FluentDocker 3.0.0
Added
- 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
Changed
- 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
Deprecated
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
Removed
- 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
Fixed
- 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
Docker Compose V2 Auto Detection
This release brings three things:
- The CI/CD process is now purely in GitHub (GH Action)
- It ignores any compose version hints (this will be re-enabled when breaking change needs to be done) but uses
docker compose(subcommand) as preferred and reverts todocker-compose(if found). This solves Issue #312 - Nuget Release: netstandard2.0, net6.0, net8.0
I really hope I will have more time to fix and develop new features going forward!
Cheers,
Mario 😊
Docker-compose v2
Support for docker-compose v2 when using "standard" docker daemon. This is due to that docker-compose v2 do not support -H (uses docker context instead).
CVE-2021-39208 fix
Fixed CVE-2021-39208 by upgrading SharpCompress.
This requires to drop the support for netstandard1.6 since SharpCompress did drop it.
Please file an Issue if any problems occur due to this!
Cheers,
Mario :)
Minor enhancement & bugfix
Release notes
Features
Added Feature DeleteIfExist
DeleteIfExists(bool removeVolumes = true, bool force = false, string removeLink = null)It ensures that a container is deleted before creating. Hence the inverse ReuseIfExists().
var name = Guid.NewGuid().ToString();
var container = Fd.UseContainer()
.UseImage("postgres:9.6-alpine")
.WithName($"name-{name}")
.Build();
var id = container.Id;
using (var c = Fd
.UseContainer()
.DeleteIfExists()
.UseImage("postgres:9.6-alpine")
.WithName($"name-{name}")
.Build())
{
// Ids should not be equal - since deleted and then created.
AreNotEqual(id, c.Id);
}Added Created on Container configuration
This exposes the DateTime when the container was created.
Added Compose Project Directory
It is now possible to do UseProjectDirectory() in the CompositeBuilder to specify a project directory. This was implemented in PR #217 and brought up in Issue #216.
Examples
Added a Example solution to start showing some simple solutions instead of, possibly, complex unit test to understand how to use this library.
Notable PRs
PR #171 from Diggzinc/master
Simplified Trace and support for routing to any logging framework. For example, like this.
PR #200 from 0xced
Fixed bug: On macOS, tests running the envtest.sh script would fail with a permission denied exception because the script is not exectuable
PR #201/#204 from 0xced
Allow to PublishAllPortsinstead of explicit portmappings as a shorthand. Added ExposeAllPorts.
PR #202 from 0xced
Hide real exeption when throwOnError in a container export is fixed.
PR #203 from 0xced
Fixes many typos
PR #218 from jgozner
Added a Ductus.FluentDocker.XUnit NuGet package to be used when doing XUnit testing instead of mstest.
Security update for CVE-2018-8292
This is a fix for the CVE-2018-8292. See GitHUB Advisory for more information.
You're strongly advised to update to this release!
Bugfix release
This release fixes the COPY command in the docker file builder that did not double quote filenames in the JSON array.
Talking to custom docker daemon URI without docker-machine
Added a limited support to use the FluentAPI to talk to a remote docker daemon without using docker-machine. This is done either by manually creating a instance of a DockerHostService or use FromUri on HostBuilder.
using(var container = Fd.UseHost().
FromUri(Settings.DockerUri, isWindowsHost: true).
UseContainer().
Build())
{
}The above sample connects to a custom DockerUri from a setting and is a windows container docker daemon.
FromUrithat uses aDockerUrito create aIHostService. This uri is arbitrary. It also support other properties (see below).
public HostBuilder FromUri(
DockerUri uri,
string name = null,
bool isNative = true,
bool stopWhenDisposed = false,
bool isWindowsHost = false,
string certificatePath = null) {/*...*/}It will use "sensible" defaults on all parameters. Most of the case the uri is sufficient. For example if not providing the certificatePath it will try to get it from the environment DOCKER_CERT_PATH. If not found in the environment, it will default to none.
UseHostthat takes a instantiatedIHostServiceimplementation.