Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Docker: From Versioned Inputs to Typed Observations

The Docker integration exposes container-engine commands and daemon observations. The wrapper exposes generated command types, while reviewed parsers interpret selected JSON formats, transfers and diagnostics.

Docker CLI, Docker daemon API and Buildx/BuildKit can have independent versions. A CLI help snapshot cannot collapse those compatibility axes into one guarantee.

Acquisition and generated surface

The Design entry point discovers docker/cli GitHub tags, uses DockerImagePlanResolver for version-dependent recipes, runs the binary in a container and parses Cobra help. Its current default minimum for collection is 23.0.0.

Cached help can be replayed into docker-<version>.json without image preparation. Existing collected files, rather than the collector's default minimum alone, determine the generated surface.

Contracts receives commands and the environment catalogue through build inputs. The implementation receives generated builders/client and supplies the parser and concrete runner. Historical aliases and command hierarchy can change which generated command type is available at a version; inspect its sampled bounds.

Request event JSON explicitly

The following complete offline example uses a fixture-shaped engine event and the generated DockerEventsCommand. It performs no daemon operation.

using FrenchExDev.Net.BinaryWrapper;
using FrenchExDev.Net.BinaryWrapper.Lib;
using FrenchExDev.Net.BinaryWrapper.Testing;
using FrenchExDev.Net.Docker;

var version = SemanticVersion.Parse("29.0.4");
var binding = new BinaryBinding
{
    Identifier = new BinaryIdentifier("docker"),
    ExecutablePath = "unused",
    DetectedVersion = version,
};
var command = new DockerEventsCommand(version)
{
    Format = "json",
    Environment = new DockerEnvironment { Context = "example" },
};
var line = new OutputLine(
    """{"Type":"container","Action":"start","Actor":{"ID":"abc","Attributes":{"name":"web"}},"time":1767225600}""",
    OutputSource.StdOut);
var executor = new CommandExecutor(new DictionaryBinaryResolver(binding),
    new FakeProcessRunner([line]));
await foreach (var evt in executor.StreamAsync(
    binding.Identifier, command, DockerOutputParsers.Default))
{
    if (evt is DockerContainerStarted started)
        Console.WriteLine($"{started.ContainerName}: {started.ContainerId}");
    if (evt.OutputLine is { } source)
        Console.WriteLine($"{source.Source}: {source.Text}");
    if (evt is DockerCommandExited exited)
        Console.WriteLine($"CLI exit: {exited.ExitCode}");
}

For live events, configure a finite observation window or deliberate cancellation. A follow stream's lifetime belongs to the caller.

Format-aware output

DockerOutputParsers.Default recognizes relevant command paths and requested formats. Supported categories include engine event JSON, container/image/stats formatter JSON, resource inspection arrays, pull/push layers and selected raw JSON build observations.

Equivalent whole-object {{json .}} templates are accepted where supported. Arbitrary Go templates, quiet list modes, container application logs and unrelated output remain raw.

ForFormat can select a decoder when format selection is external. It does not modify the command to request that format. The caller must establish both invocation and parser configuration.

Events and evidence

DockerEngineEventObserved retains engine fields and attributes. Known container actions additionally project records such as DockerContainerStarted, DockerContainerExited and health observations.

A container die event's exit code describes the container. DockerCommandExited describes the Docker CLI process. Those values can differ and have different operational meanings.

Inspection arrays can span logical lines. The parser retains supplying lines and complete JSON evidence, validates required fields and bounds buffered data. Unknown daemon fields remain available without being forced into guessed properties.

A transfer-completed or build vertex observation reports that stage. It does not prove that the surrounding command or desired service configuration succeeded.

Typed Environment

DockerEnvironment includes host/context, certificate/configuration paths, TLS switches, API version, proxy configuration, headers, platform and BuildKit selection.

ApiVersion uses a version converter; headers use a dictionary converter; NoProxy uses a list converter; non-empty switches preserve inheritance versus explicit empty values. Availability is declared per variable, including newer custom-header support.

Docker gives Context precedence over Host inside its own configuration. BinaryWrapper's binding/command merge precedence is a separate layer. Setting both should not be described as “the last property wins” inside Docker.

The catalogue has a Design process reader, but the inspected Docker Program does not assign its returned dictionary to DesignPipelineRunner.Environment. It loads a GitHub token for discovery. This differs from several migrated consumers and limits any claim that this entry point applies all typed runtime environment declarations during help acquisition.

Version boundaries

The built-in semantic output profile covers the reviewed 29.0.4 stable patch, bounded by the next patch's -0 boundary. Command-help coverage is broader. Unknown CLI versions retain raw output and the actual exit.

Daemon schema extensions can still occur within a client version. Buildx is a plugin with its own version; selecting Docker CLI 29.0.4 does not prove a particular BuildKit progress schema. The implementation retains unestablished build data as JSON observations instead of inventing milestones.

Validation and consumption

The consumer tests check named event fields, evidence identity, channel metadata, complete/malformed inspection JSON, profile edges, unknown actions and terminal exit. Generated commands verify that the intended JSON option reaches parser selection.

Those fake-transport checks do not establish daemon connectivity or a live build. Lifecycle events report observed transitions. Supported state queries and actual health evidence answer different questions from a start event or CLI exit.

Source snapshot

Source inspection: 2 October 2026. These implementation paths are relative to Net/FrenchExDev in the local ecosystem checkout. The v2 changes are largely uncommitted; these paths identify inspected code, without claiming that public branch links contain it.

  • Docker/src/FrenchExDev.Net.Docker.Design/Program.cs
  • Docker/src/FrenchExDev.Net.Docker.Contracts/FrenchExDev.Net.Docker.Contracts.csproj
  • Docker/src/FrenchExDev.Net.Docker/FrenchExDev.Net.Docker.csproj
  • Docker/doc/TYPED-OUTPUT.md
  • Docker/test/FrenchExDev.Net.Docker.Tests

Previous: Vagrant · Implementation index · Series index · Next: DockerCompose

⬇ Download