Skip to content

About

Docker Compose plugin for Apple's container CLI with Homebrew tap.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

36 stars

Watchers

0 watching

Forks

container-compose

container-compose icon: an octopus overlapping the standard three-row container service panel CI Documentation Homebrew Releases Quality Gate Status Coverage Bugs Code Smells Security Rating Maintainability Rating Duplicated Lines Lines of Code Repo Visitors



container-compose is a standalone plugin that provides Docker Compose v2 workflows for Apple's container CLI. Local files, Git resources, and oci:// Compose project artifacts are normalized with compose-go; image-backed projects can also push service images and publish Compose YAML, env-file layers, and optional image digest override layers or application image indexes as OCI project artifacts. Swift owns orchestration and maps supported Compose behavior to the matched runtime stack.

For Docker-free Dev Containers, the package also provides a separately compiled stock profile. It pins tagged apple/container dependencies, uses the native Container Engine Unix socket for discovery and lifecycle operations, and never falls back to Docker, Docker Compose, or Colima. The enhanced release profile remains the default for the independently installed Compose plugin. See the installation guide.

Current candidate

The latest stable release is the default macOS arm64 lane. The Current release feed contains immutable current-<full-sha> prereleases; the two Current Homebrew formulae atomically select the newest validated matched Container stack. A Current build becomes a semantic release only after the hosted Stable Release Gate, including the supported Docker Compose parity suite, succeeds.

The 15 September 2026 source-bearing Current build at 7a76b0b889c1 completed exact-main CI, signed prebuilt packaging, notarization, release-asset closure, and atomic tap publication. Its exact SonarQube analysis reports 86.7% aggregate coverage, 0.3% duplicated lines, 43,119 lines of code, and zero bugs, vulnerabilities, code smells, or security hotspots, with A reliability, security, and maintainability ratings. Coverage remains below the repository's 90% overall objective and is reported as an open quality gap rather than a passing parity claim.

The active maintenance candidate retains stopped containers and their log histories after foreground up --abort-on-container-exit, --abort-on-container-failure, and --exit-code-from completion. Its matched runtime also recovers interrupted prepared cleanup, preserves short-lived VM exits, keeps known-immediate starts off the speculative prewarm path, and serializes cctl VM-backed integration tests so concurrent validation cannot collide in the per-user runtime namespace.

The current matched stack also preserves Kubernetes control-plane discovery across VM address changes; skips unreadable image-list entries; accepts colons in published host paths; preserves named host identities in machine runs; classifies unreadable build contexts correctly; reaps completed exec state; isolates failed logging consumers; keeps host-only gateways reserved without installing default routes; and preserves authoritative foreground exit status and events. Lower-level fixes cover failed pod-start cleanup, bounded ext4 parsing, registry bearer challenges, terminal restoration, TLS callback configuration identity, re-entrant EOF handling, and certificate-directory parsing.

The 0.14 release line adds explicit isolation and a faster, more memory-responsive runtime:

  • container run --isolation dedicated-vm retains the private-VM default, while explicit shared-vm runs eligible host, none, or built-in bridge workloads in a shared Linux sandbox; Compose projects can select the same modes with the service isolation field;
  • live memory targets can be changed without restarting a container, and an opt-in controller samples usage to reclaim idle memory within a configured floor while restoring the boot-time maximum under sustained pressure;
  • eligible dedicated containers prewarm after creation without starting init, independent VM boots run concurrently under a bounded FIFO admission limit, Containerization pipelines pod and mount preparation, and verified BuildKit contexts skip redundant file transfer; and
  • shared-sandbox networking, root-filesystem privacy, mount materialization, natural exit, Virtualization.framework hot-plug recovery, concurrent netlink sessions, mountpoint creation, console links, tmpfs source projection, external-journal ext recovery, exec IPC namespace entry, optional-certificate TLS stability, and refreshed certificate handling include the release's reliability fixes.

Compose also reuses one control-plane Container client per invocation while keeping attach and exec on independently owned sessions. This reduces repeated XPC setup without allowing session teardown to interrupt unrelated work.

Optimization pull-request provenance

The 0.14 release-line runtime and benchmark claims are backed by these merged support-fork pull requests:

As of 28 August 2026, none of the benchmarked Container, Containerization, builder-shim, or Compose optimization commits has a live pull request in an Apple repository. The stock-Apple upstream/pr-* branches are local submission candidates, not submitted pull requests, and are deliberately not presented as upstream links. The complete distinction between merged fork PRs, Apple submissions, and unsubmitted candidates is recorded in the Apple upstream review.

The supported release line includes:

  • durable json-file logging plus Syslog, Journald, Fluentd, GELF, Splunk HEC, AWS Logs, Google Cloud Logs, and Docker logging-plugin providers;
  • bounded live log readers, rotation and compression health, provider recovery, and generation-safe logging cutover;
  • network-scoped discovery and aliases, scaled hostnames, bridge mapping, advanced IPAM, IPv6-only networking, and runtime DNS;
  • dependency-aware parallel lifecycle operations, attach-before-start, WebSocket attach and resize, wait, and expanded inspect/info behavior;
  • inherited OCI and image-volume metadata, safer archive/copy behavior, image discovery and mutation, digest resolution, and content-addressed caching; and
  • versioned runtime-capability negotiation plus stricter staging, containment, redaction, cancellation, and bounded-resource controls.

Candidate notes and exact dependency revisions are on the selected current-<full-sha> release. STATUS.md describes the functionality and explicit limitations in the stable baseline and current candidate. Planned compatibility work is kept separately in BACKLOG.md and its linked GitHub issues.

Warning

🤬 This project is a maintenance nightmare. 🤬

What started as a 'fun' implementation due to a real need for Compose functionality on apple/container has turned into a beast. container-compose cannot be maintained in isolation: it depends on runtime and build capabilities not yet available in Apple releases, plus local fixes for upstream defects. Keeping it working means carrying and continuously refreshing a matched four-repository stack. At the 16 September 2026 snapshot, the three support forks are 1305 commits ahead of Apple upstream:

What looks like a local Compose change can therefore require coordinated conflict resolution, pin updates, builds, tests, packaging, and release validation across the entire stack. The pinned revisions must move together.

Apple's #1769 proposal and stated direction are that Docker CLI compatibility is NOT a project objective, because of UX, naming, and maintenance trade-offs; its preferred route is Docker CLI access through Socktainer and a separate API bridge or service plugin. The missing primitives and fixes may therefore remain long-lived fork responsibilities rather than work Apple adopts upstream.

Note

Runtime boundary

ComposeRuntimeSPI is the Compose-owned, runtime-neutral contract layer. It defines requests, summaries, and provider contracts for discovery, lifecycle, execution, copy/export, logs/events, stats/top, images, configs/secrets, and project resources, without importing Apple runtime packages.

ComposeCore depends only on those contracts and other Compose-owned models. The plugin installs ComposeContainerRuntime, the Apple-backed composition root: it translates neutral create plans to Apple DTOs, owns archive and OCI integration, and wires typed ContainerClient providers, explicit CLI bridges, and Compose-owned filesystem external-config and Keychain external-secret defaults. Standalone ComposeCore requires a provider rather than constructing an Apple client. make core-runtime-neutrality prevents Apple package dependencies or imports from returning to Core.

Docker and Compose policy stays above this seam. This is not a general AOP framework: focused decorators can negotiate declared capabilities, while VM, guest, cgroup, mount, archive, device, and builder primitives remain small Apple-shaped runtime slices. New runtime work continues in tested vertical slices without changing Compose-visible behavior outside its documented parity surface.

The resource contract also carries explicit enableIPv6 and IPv6 gateway network intent. An enabled IPv6 pool can select an in-prefix gateway, which the matched macOS 26 vmnet primitive applies as the primary guest route and reports through network inspection. For enable_ipv6: false, Compose preserves the declared IPv6 IPAM pool and gateway in config output, but omits those contradictory values from the effective runtime create request, as Docker Engine does. The matched vmnet primitive then disables NAT66 and router advertisements and reports no IPv6 subnet.

Help color-codes command, subcommand, and option support: green for supported, orange for partially supported, and red for unsupported. Command support and option support are separate signals: a command can still be partially supported when every listed option is green if the remaining Docker Compose gap is tied to operands, output shape, or a runtime primitive instead of a flag. Partially supported commands include a Limitations line that names the remaining gap. Use --ansi never for plain output. Unsupported runtime behavior fails before side effects with an explicit unsupported compose feature message.

For the current candidate, the generated help classifies 40 commands as green and six as orange (attach, events, exec, logs, run, and up); no command is red. It classifies 262 documented long options as green and only exec --privileged as orange; no documented long option is red. Orange command limitations describe the remaining runtime or evidence gap even when every option for that command is green.

The top-level help output is the quickest support overview. Run container compose COMMAND --help for command-specific option support.

Use STATUS.md for the current stable functionality and BACKLOG.md for the remaining 1.0 parity contracts. The live source of backlog state is the cross-repository GitHub hierarchy rooted at [Parity] Container Compose 1.0.0 completion.

The key project goal remains 100% observable Docker Compose v2 parity on macOS with comparable or better performance. The backlog and executable reference comparisons must expose every remaining project-owned difference; they must not become implicit exceptions.

Important

Retained controlled full-suite evidence (30 July 2026)

The complete maintained 62-target Docker Compose comparison suite passed in one uninterrupted 1,152.03-second run against Docker Compose 5.3.1 and Docker Engine 29.2.1 on a Mac17,9 running macOS 26.5.2. Its three-sample warm-image bridge comparator measured up at 0.153s for Docker Compose and 1.228s for container-compose (8.01×), while down measured 10.178s and 5.916s respectively (0.58×). Named-network service discovery, aliases, one-off aliases, recreate behavior, and source-scoped links all passed their live Docker oracles. Exact revisions, timing tables, fingerprints, and interpretation are retained in the macOS Compose parity and performance review.

This retained run predates the current candidate and is not a claim that the project goal is complete. Its lifecycle matrix covers warm-image 1/10/50-service detached startup and teardown, but its 31 July one-repetition debug diagnostic was slower than Docker at 10 and 50 services and is not release-grade evidence. That run did not include the later logging performance lanes; cold-resource collection, develop.watch sync, and build-context transfer remain open, and every partial surface in the current ledger remains open.

Note

CodeQL is release-only. Current and stable package publication analyzes the exact Go normalizer source after the fail-fast Homebrew preflight and before native package construction. The standalone workflow recovers an already published release only. This does not claim Swift CodeQL coverage, and a missing or failed release analysis is not a pass.

On macOS, container-compose honors the active pull policy, prepares missing default-pull images when needed, then reads image metadata before up, create, and one-off run. It creates deterministic implicit Dockerfile-declared volumes and seeds an empty local volume from the selected image path for both declared and ordinary local volume mounts (including inherited external volumes), preserving the selected directory's ownership and mode on the volume root. volume.nocopy: true, a pre-existing volume.subpath, and a mount at a missing image path remain empty; populated volumes are preserved across down/up, matching Docker. Service pre_start helpers inherit service runtime context and gate startup, while post_start and pre_stop cover detached, foreground, and interactive one-off lifecycle paths with Docker-compatible detach and exit-status behavior. Foreground up --exit-code-from SERVICE returns the selected service's terminal status even when teardown closes attached log streams. The matched runtime encodes foreground attach signals by Linux-resolvable name, returns complete long records at backward-read tail boundaries, and keeps persistent log capture alive after an attached client disconnects; the committed signal/log reliability fixture verifies all three behaviors against Docker Compose V2.

Use container system version to see the running container runtime source, branch lane, commit, compiled containerization ref, and builder image metadata. Use container compose version to see the installed plugin lane, embedded compose-go version, and package/runtime compatibility metadata.

See It Work

Representative terminal recording: starting, inspecting, reusing, and tearing down the monitoring stack

The archived representative recording is a complete matched-runtime execution of the portable nginx and Alertmanager service slice in the real examples/monitoring-stack/docker-compose.yaml. It visibly types container system start, confirms the running service, starts that two-service slice, shows stats --no-stream and ps, queries nginx /healthz and Alertmanager readiness from their running services, writes and reads data in the named nginx_cache volume across a retained-volume shutdown, and finally removes the project with down --volumes --remove-orphans. The focused slice keeps the recorded startup deterministic while the full macOS-safe monitoring stack remains covered by the Docker Compose v2 parity suite. Each displayed result is the live output of the command that was just typed; the tape has no transcript replay or marker helper. A separate Current Demo workflow records exact-SHA sessions on the hardware-virtualization-capable runner after the signed Current packages and Homebrew formulae are available, retaining each result as a bounded workflow artifact. Recording failure cannot block package, attestation, release, or tap publication, and the workflow never mutates an immutable release.

Install And Project Map

Use INSTALL.md for install, upgrade, verification, and uninstall commands. The supported Homebrew install uses the matched stephenlclarke runtime stack; BUILD.md covers repository roles, branch policy, and deterministic release promotion.

From a clean source checkout, make builds the complete local Container-family stack, automatically consumes exact upstream pins, and retains recoverable native caches and timing evidence. Use make local-build for a quick Compose-only build, make stack-status to verify retained pins, and make release-version to preview the Conventional Commit semantic-version decision. Transient workspaces and build scratch live on /Volumes/SSD; verified artifacts, receipts, and reusable evidence live under ~/Library/Application Support/ContainerFamily/retained and survive transient cleanup. Use make release-status VERSION=X.Y.Z or make release-recovery-plan VERSION=X.Y.Z to inspect recovery state without building, dispatching, or changing a published release. The complete build, test, Actions, recovery, and release diagrams are in Recoverable Container-family builds.

Plugin Recognition

When installed correctly, container help lists compose under PLUGINS.

container help output showing the compose plugin recognised

Documentation

INSTALL.md, BUILD.md, STATUS.md, BACKLOG.md, and CONTRIBUTING.md are the maintained sources of truth for operation and planned parity work. The coherent architecture and development cycle describe the approved future design and process.

The Apple-facing drafts under docs/upstream/ are current handoff records for unresolved or Apple-shaped work; they are not install, release, support, or Apple-submission runbooks.

License

This project uses the Apache License, Version 2.0, matching the license used by apple/container.

About

Docker Compose plugin for Apple's container CLI with Homebrew tap.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

36 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages