[Tracking]: restart policy and auto-start on boot — status of #158, #286, #1201, #1258 and a request for maintainer direction
- Dominant language
- Swift
- Stars
- 49.9k
- Forks
- 1.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 22
Description
### Feature or enhancement request details
This is a **tracking / status issue**, not a new feature request. Everything here is already
requested and, in large part, already implemented — it is spread across two issues and two PRs,
and the work has been blocked on an unanswered maintainer decision since 2026-06-22.
Opening this to put the state in one place and ask for one specific direction call. Happy for a
maintainer to close it as a duplicate if the discussion is better held on one of the existing
threads — but please answer the question in "What we are asking for" first.
#### Current state
| Thread | What it covers | State | Last activity |
|---|---|---|---|
| #158 | Auto-start containers on boot | Open issue, unassigned | 2026-02-07 |
| #286 | `--restart` flag on `run`/`create` | Open issue, unassigned | 2026-02-07 |
| #1201 | PR: `--system-start` flag (@saehejkang) | Open, **draft**, paused pending direction on #1258 | 2026-02-24 |
| #1258 | PR: full restart policy (@JaewonHur) | Open, **ready for review** | 2026-06-22 |
Nothing has merged. As of today the only way to get a container back after a macOS reboot is a
user-maintained `launchd` agent.
#### What is actually blocking this
PR #1258 has a working implementation and an agreed design. It ends with a direct question to
Apple from @stephenlclarke, who maintains a fork with the work already split into three
review-sized branches:
> Would Apple prefer this PR branch to be refreshed into that smaller stacked shape, or would a
> new first PR for only the create-time API/CLI contract be easier to review?
That question has had no maintainer response for roughly two months. Three contributors
(@JaewonHur, @saehejkang, @stephenlclarke) are each holding off to avoid duplicating the others'
work, so the net effect is that a finished feature is idle on a review-logistics decision rather
than on a technical one.
#### What we are asking for
1. **A direction call on #1258**: keep the single PR, or restack it as create-time API/CLI first,
then runtime behavior, then timing controls. Either answer unblocks it — the ambiguity is the
blocker, not the choice.
2. **A semantics decision**, which #1201 is explicitly waiting on: does `--restart always` also
imply start-on-`container system start`, or does boot behavior stay a separate
`--system-start` flag? #1201 is paused until this is settled.
3. **A rough signal on whether this is on the roadmap at all.** If restart policy is deliberately
out of scope for `apple/container`, saying so plainly is a fine outcome — it lets everyone stop
holding branches open and lets downstream tooling commit to the `launchd` approach.
#### Field notes from running the `launchd` workaround
Sharing these because two of them contradict things stated earlier in these threads, and one is a
trap other users will hit.
**1. `container start` on an already-running container is a clean no-op in 1.2.2.**
The workaround in #158 carries a known-issues note that starting a running container "will stop it
and throw an error." I could not reproduce that on `container` 1.2.2 (Homebrew): it exits 0 and
leaves the container running. Whatever caused that appears to have been fixed. Worth knowing,
because it means a boot script does not strictly need a running/stopped filter.
**2. `brew services start container` is actively harmful — do not recommend it.**
Homebrew's plist sets `KeepAlive` on `container system start`. That command registers the services
and exits immediately, so `launchd` treats every exit as a crash and relaunches it in a loop.
Symptom: `/opt/homebrew/var/log/container.log` fills with repeated `Launching container-apiserver…`
lines while `brew services list` still reports the service as `stopped`. This looks like a
plausible auto-start solution and silently is not one.
**3. Detecting whether the system is up needs an exact field match.**
`container system status` prints `apiserver is not running and not registered with launchd` on
failure — a substring that contains `running`. Scripts doing `container system status | grep -q running`
get a false positive and skip the start. Matching the status field exactly avoids this:
```sh
container system status 2>&1 | awk '$1 == "status" && $2 == "running"'
```
**4. A generic agent works, and survives a real reboot.**
Rather than one plist per container (#158) or a label convention requiring `jq` (the follow-up in
#158), this enumerates every container at runtime, so containers created later are covered with no
plist edits and no dependencies beyond `/bin/sh`:
Boot script (POSIX sh, no dependencies)
```sh
#!/bin/sh
CONTAINER_BIN="${CONTAINER_BIN:-/opt/homebrew/bin/container}"
CONTAINER_AUTOSTART_SKIP="${CONTAINER_AUTOSTART_SKIP:-buildkit}"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
[ -x "$CONTAINER_BIN" ] || { log "error: $CONTAINER_BIN not executable"; exit 1; }
log "starting container system services"
"$CONTAINER_BIN" system start --enable-kernel-install --timeout 60 || {
log "error: 'container system start' failed"; exit 1; }
# 'ls -q' lists running containers, 'ls -a -q' lists all of them;
# the difference is what needs starting.
RUNNING=$("$CONTAINER_BIN" ls -q 2>/dev/null)
"$CONTAINER_BIN" ls -a -q 2>/dev/null | while IFS= read -r id; do
[ -n "$id" ] || continue
skip=false
for s in $CONTAINER_AUTOSTART_SKIP; do [ "$id" = "$s" ] && skip=true; done
$skip && { log "skip $id (excluded)"; continue; }
printf '%s\n' "$RUNNING" | grep -qx "$id" && { log "skip $id (already running)"; continue; }
if "$CONTAINER_BIN" start "$id" >/dev/null 2>&1; then log "started $id"; else log "FAILED to start $id"; fi
done
log "done"
```
Driven by a `RunAtLoad=true`, `KeepAlive=false` LaunchAgent in `~/Library/LaunchAgents`.
`buildkit` is skipped by default since `container build` starts it on demand.
Verified across an actual macOS reboot, not just a `launchctl kickstart`: the agent fired ~30s
after boot and brought both application containers back up.
None of this is a substitute for the feature. A `launchd` agent cannot restart a container that
crashes while the machine is up, it has no backoff or `on-failure` semantics, and every user
reinvents it slightly differently — which is precisely what #286 and #1258 exist to fix.
Thanks to @JaewonHur, @saehejkang and @stephenlclarke for the implementation work already done
here, and to the maintainers for the project generally.
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
Contributor guide
Research direction
Read the status of issues #158, #286, #1201, and #1258, especially the open PRs and their pending design questions. Start by reviewing the direction requested for #1258 and the semantics question blocking #1201; this tracking issue is done when maintainers decide the review structure, restart semantics, and roadmap status.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell, swift
- Domain
- cli, devops
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100