Releases: bshk-app/ContainerStack
Release list
ContainerStack 0.6.1
ContainerStack 0.6.0
Apple Container moves to 1.3.1, which closes six security advisories in the layer
that pulls and unpacks images. Updating the app updates the runtime with it:
brew upgrade --cask containerstack pulls both.
Security
- The pinned runtime moves from Apple Container 1.2.2 to 1.3.1. All six advisories
fixed in containerization 0.42.0 covered the 0.40.1 that 1.2.2 carried. Four are
reached by pulling an image from a registry you do not control; one of those,
CVE-2026-65388, could hand your registry credentials to whatever host the
registry names in its authentication challenge — over plain HTTP if it asks, and
on a login that fails, because the client sends them before it stores them.
The other two are reached by creating a container and by loading an image layout. - The Docker bridge was ported to that runtime. A tarball whose index carries one
entry the runtime now refuses to read still loads the images beside it, rather
than failing whole.
Added
- A runtime this build was not tested against is now stated plainly, naming the
version found, the version required, and the command that fixes it. Until now the
helper exited, launchd restarted it every ten seconds, and the app could only say
the helper had exited — the same sentence it shows when a socket never opens.
Changed
- Image pushes and registry inspection now always use
https. Apple Container 1.3.0
removed the scheme detection that downgraded internal hosts to plain HTTP, and
Docker's own default is the same. A registry served over plain HTTP is no longer
reachable through those two paths.
Known limitations
Published ports still require a runtime restart if a bridge-created network's vmnet
helper dies; restarting only the containers does not repair the host route. Running
an image from the Images screen still waits for the container to exit before it
returns.
ContainerStack 0.5.1
A maintenance release about one thing: the app telling the truth about the runtime.
A single dropped connection no longer blanks every list, a runtime that died no longer
leaves its containers on screen, and cstack doctor stops calling a network unroutable
when it simply could not be checked.
Fixed
- One unanswered probe no longer empties the app. The 3-second monitor needs two
consecutive silences before it calls a healthy runtime offline, and the ping it asks
now retries a dropped connection the way every other read already did. Declaring the
runtime dead clears containers, images, volumes and networks and throws away a refresh
in flight, so being wrong once was expensive. Stop still shows its effect immediately:
silence with a known cause does not wait for a second opinion. - The dashboard no longer keeps showing a dead runtime's containers. A runtime that
fails clears the inventory it described, an explicit failure outranks a lingering
"Starting", and a refresh still in flight when the runtime was declared dead can no
longer resurrect what it published. cstack doctortells "nothing publishes a port" apart from "nothing could be
checked". A missing routing table, or a network whose subnet is empty, is reported as
uncheckable rather than NO ROUTE, and only the networks a published port actually
depends on are judged.- Stopping the runtime asks the containers to exit before the service goes down.
- Images Run and
cstack runno longer give up after five seconds while a micro-VM
boots: starting and cleaning up a container get the same 120-second window as every
other VM operation. Run still waits for the container to exit before returning. - The runtime helper no longer runs blind. When it cannot open
~/Library/Logs/ContainerStack/runtime.logit falls back to a temporary file and
records why the first destination failed, instead of returning silently — which left
a crash-looping helper indistinguishable from one that never started. - Editing a Compose file validates through a uniquely named temporary file, so two
saves of the same stack can no longer collide next to your compose file. - An icon that fails to load is now visibly wrong rather than invisible: release builds
draw a placeholder where a missing asset used to render as a control with no icon.
Known limitations
Published ports still require a runtime restart if a bridge-created network's vmnet
helper dies; restarting only the containers does not repair the host route.
Internal
Style gates — swift-format, SwiftLint and the comment-length hook — and the CI wiring
that runs them on every pull request. No user-visible change.
ContainerStack 0.5.0
Containers can be sized now, and a stop that loses the runtime's XPC service no
longer hangs the app with no way out.
Added
- Global CPU and memory defaults in Settings, clamped to this Mac's capacity,
and per-container overrides in the image Run dialog. Apple Container gives
every container its own VM, and until now each one got the runtime's built-in
4 CPUs and 1 GiB. The values travel as Docker'sHostConfig.Memoryand
HostConfig.NanoCpus. Fractional CPUs are deliberately not offered: the
bridge floors them to whole vCPUs, so 0.5 would silently become 1.cstack
keeps its previous behaviour and passes no limits.
Fixed
- Stopping a container no longer hangs on "Stopping…" indefinitely. Measured
cause: Apple Container's API server had lost its XPC service, so both stop and
kill answered HTTP 500 "XPC connection error: Connection interrupted" and
every later ping answered "Connection invalid", while the app waited out the
full lifecycle timeout. Stop now pins the daemon's grace window at five
seconds, bounds its own wait, and treats 304 and 404 as the requested end
state rather than a failure. - A lost connection is repaired once instead of repeatedly. The health monitor
is the only owner of restarts and first proves the API server is really gone
withcontainer system status, so a single transient ping timeout can no
longer cycle a stack that is serving traffic. A recovery that fails ends the
startup window, so the manual restart stays available instead of the sidebar
sitting in a starting state with nothing to click.
Known limitations
Published ports still require a runtime restart if a bridge-created network's
vmnet helper dies; restarting only the containers does not repair the host route.
The per-container micro-VM architecture also remains slower than OrbStack on the
measured M1 system (4.6x container round trip, 3.6x bind-mount writes).
ContainerStack 0.4.2
ContainerStack now owns a Docker socket separate from a standalone Socktainer
installation. Upgrading moves the app and its Docker context without stopping or
removing a bridge you run yourself.
Changed
- The app,
cstack, Docker context, and verification tools now use
~/.containerstack/docker.sockinstead of~/.socktainer/container.sock.
An activecontainerstackDocker context is refreshed during the upgrade. If
you setDOCKER_HOSTyourself, update it to the new path. - The bundled bridge explicitly owns startup housekeeping for the shared Apple
Container runtime. Homebrew cleanup removes only ContainerStack's state and
no longer treats~/.socktaineras app-owned data.
Fixed
- Upgrading retires the old bundled bridge before starting its replacement. The
migration matches both the exact helper path inside ContainerStack.app and the
old argument list, waits for that process to exit, and aborts safely if it
cannot confirm retirement. A standalone Socktainer process is left running.
Known limitations
Published ports still require a runtime restart if a bridge-created network's
vmnet helper dies; restarting only the containers does not repair the host route.
The per-container micro-VM architecture also remains slower than OrbStack on the
measured M1 system (4.6x container round trip, 3.6x bind-mount writes).
ContainerStack 0.4.1
Starting and stopping containers works again on a machine where another Docker
bridge got there first, and one slow container no longer freezes the rest.
Fixed
- Another program listening on the Docker socket is now named instead of adopted.
A bridge from a different build answers every status check while start and stop
hang - measured past 150 seconds against a container the bundled bridge started
in 2 - so the app reported a healthy engine while nothing could be controlled.
It now says which socket is held and what to do, keeps saying it while it is
true, and stops offering the actions that cannot succeed. Listing containers and
reading their logs keep working, since that is what you need at that point. - Acting on one container no longer disables every other one. Stopping can take
the full two-minute timeout, and for that whole time no other container could be
started, stopped, deleted or have its logs opened - and a click on a different
container did nothing at all, without a word. - Quitting no longer leaves runtime commands running. A command the app was
waiting on used to survive the app that started it: eight of them were found on
one machine, the oldest four days old, each wedged and invisible. The Docker
bridge is unaffected and still outlives the app on purpose.
ContainerStack 0.4.0
The app can finally update itself. Beyond that: runtime control is harder to
wedge, destructive actions are harder to trigger by accident, and diagnostics
are more honest.
Added
- In-app updates. Every build since 0.1.0 advertised an update feed and the
signed feed has been live the whole time, but nothing read it: there was no
Sparkle, no menu item, and no way to learn a new version existed. "Check for
Updates…" now sits in the app menu and the menu bar. Checking happens on its
own; installing waits for you, because replacing the app while containers run
is not a decision to make on your behalf. - Docker sections can be hidden from the sidebar through its context menu. Even
with every Docker item hidden, the same menu remains available to restore them. cstack doctorreports the configured memory limits of running containers
against host memory. Unlimited containers and failed inspections are named
separately instead of being counted as zero.- Every icon-only action has a descriptive, resource-specific VoiceOver name.
Fixed
- Releases carry their download again. 0.3.0 was published before its DMG was
built, and GitHub freezes a release's files the moment it is published, so
that version shipped empty and could not be repaired. The installer is now
attached while the release is still a draft, and publishing is the last step. - Every subprocess wait now has an explicit deadline, except the deliberately
supervised socktainer process. A child that hangs — or exits while a descendant
keeps its output pipe open — can no longer wedge monitoring and runtime controls
forever. cstack runtime restartcontinues best-effort recovery after a failed step,
names each failure, and exits non-zero instead of claiming success.- GUI, helper,
cstack runtime, andcstack doctorresolve the Apple Container
binary and its install root through one owner. Environment overrides and the
vendored runtime no longer apply to only part of the system. - The bridge no longer writes an INFO request line for every 3-second poll into
runtime.log; warnings, errors, startup and DNS fallback messages remain. - Deleting a container, image, volume, or network now requires confirmation.
In-use volumes are not force-deleted. - Malformed chunked HTTP sizes return a parse error instead of trapping on
integer overflow or a reversed range. - Image creation time reports unknown when the runtime returns zero, rather than
“56 years ago”. Architecture and OS now come from image inspect, the endpoint
that actually provides them.
Changed
- The expensive missing-app-root diagnostic runs at most every 30 seconds
instead of spawning thecontainerCLI on every 3-second monitor tick. Manual
refresh still probes immediately.
Known limitations
Published ports still require a runtime restart if a bridge-created network's
vmnet helper dies; restarting only the containers does not repair the host route.
The per-container micro-VM architecture also remains slower than OrbStack on the
measured M1 system (4.6x container round trip, 3.6x bind-mount writes).
0.3.0 — never released (use 0.4.0)
Never released.
This release was published before its installer was built, and GitHub freezes a
release's files at publish time - so it has no DMG, and the tag name cannot be
reused. Everything intended for it ships in v0.4.0:
https://github.com/bshk-app/ContainerStack/releases/tag/v0.4.0
ContainerStack 0.2.0
Updates now come from GitHub. Nothing in the app itself changed: no file under
Sources/ differs from 0.1.0, and the only edit to the shipped bundle is the
update feed it points at.
Changed
- Updates are served from a signed feed on GitHub Pages, and the DMG is a GitHub
Release asset. Both used to come from a server that had to be reachable for an
update to be found at all; now the artifact lives where the source does. - The update signing key was rotated as part of the move, so this build trusts a
different key than 0.1.0 did.
Known limitations
Unchanged from 0.1.0, and still the two worth knowing before installing:
published ports stop working until the runtime is restarted when a
bridge-created network's vmnet helper dies, and ContainerStack is slower than
OrbStack on an idle M1/16 GiB — container round trip 4.6x, bind mount writes
3.6x, because Apple Container boots one micro-VM per container.
ContainerStack 0.1.0
First distributed build. Everything below is verified end to end on Apple
Silicon; see docs/ROADMAP.md for what is deliberately not here yet.
Added
- Apple Container 1.2.2 supervised by a bundled runtime helper, with socktainer
shipped as a sidecar inContents/Helpers. - A Docker-compatible socket at
~/.socktainer/container.sock; the app can
register it as thecontainerstackDocker context when the user opts in. dockeranddocker composework unmodified: networks, volumes, published
ports,exec, anddown -v.cstack, covering ps, inspect, logs, start/stop/restart/rm, run, images,
pull, rmi, volumes, networks, df, prune, context, and compose.- App surfaces for overview, containers grouped by Compose project, images with
pull/run/delete, volumes, networks, and a runtime panel with polled state. - A LaunchAgent that keeps the runtime alive without the GUI running.
Known limitations
- Published ports stop working until the runtime is restarted, when a
bridge-created network's vmnet helper dies. Restarting the containers does
not help and loses their addresses; the app andcstack doctorboth say so.
The root cause sits in Apple's daemon, which owns the re-attach. - Slower than OrbStack on an idle M1/16 GiB: container round trip 4.6x, bind
mount writes 3.6x. The gap is architectural — Apple Container boots one
micro-VM per container.