Codync
A free, open-source 1:1 alternative to Grok Bot and Muse. Message Claude Code, Codex, Cursor and 40+ coding agents as persistent bots from your iPhone, Mac or Linux desktop. Group chats, threads, appr
Apple’s container starts one container at a time — no compose file, no dependency order, no name-based service discovery. opossum runs the compose.yaml you already have on it, with no Docker…
Developer toolsGitHub @suruseasOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
A Docker Compose-like orchestrator for Apple's container runtime on macOS 26+
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Apple's container starts one container at a time — no compose file, no
dependency order, no name-based service discovery. opossum runs the
compose.yaml you already have on it, with no Docker Desktop and no daemon.
It reads Docker Compose files (docker-compose.yml) and implements a subset of
the open Compose specification: services start in
dependency order on a shared per-project network, so they reach each other by
name. Requires macOS 26 or later and Apple's
container.
Measured on 156 real-world compose projects: 50 (32%) ran completely as written,
86 (55%) with --from-docker-compose, and 0 were made worse — see measured
compatibility for the method and the breakdown of what is
still in the way.
Using opossum from an AI agent? Point it at
AGENTS.md— a high-density, facts-only reference (command surface, the supported/ignored/ rejected compose fields, and failure-signature→fix table) meant to drop into an agent's context window. The human quickstart below still applies. New to Docker Compose and building from an empty directory rather than an existing file? AGENTS.md's "Starting from nothing" section is written for exactly that — hand it to an AI agent and describe what you want running.
Why this works now: container-to-container networking and name resolution rely on features in macOS 26. On macOS 15 containers are network-isolated, so this kind of orchestration isn't possible.
containerreached 1.0 in June 2026.
Three things, with the measurement behind each.
1. Real compose files, measured. 156 self-hosting projects from
Compose-Examples, run unmodified:
50 (32%) came up completely as written, 86 (55%) with --from-docker-compose, and
0 were made worse. Each failure opossum can diagnose is reported with a diagnostic
code and a suggested fix rather than a raw runtime error.
Method, corpus and the full breakdown →
2. It fixes the incompatibilities for you. opossum up --from-docker-compose
writes a compose.opossum.yaml beside your file with the adjustments Apple
container needs — a database data directory that has to be a named volume,
Postgres's PGDATA moved into a subdirectory — and starts the project with them
merged. Your compose file is never modified. That is where the 32% → 55% comes
from, and nothing else does it.
3. Nothing runs when nothing is running. Docker Desktop keeps one always-on
Linux VM; Apple container gives each container its own and keeps none at rest.
Measured on one Mac (macOS 26, Apple silicon; container 1.4.1 vs Docker Engine
29.7.2, 2026-09-09):
| Docker Desktop | Apple container (opossum) | |
|---|---|---|
| Memory at idle | ~470 MB host procs + ~8.2 GB provisioned always-on Linux VM | ~65 MB helpers, no always-on VM (the builder VM, once used, stays until container builder stop) |
| Single-container start | ~0.15 s | ~0.84 s |
| Isolation | shared VM kernel | per-container VM |
| License | paid subscription for larger orgs | open source, none |
Docker starts an individual container faster — its VM is already warm. opossum is the lighter thing to leave installed. Full method and caveats →
container installed, started
(container system start), and on PATH — verified against container 1.6.1brew install suruseas/opossum/opossum
This installs a pre-built binary — no Go toolchain or local build — and pulls in
Apple's container runtime as a dependency. Since v0.24.2 the tap ships opossum
as a cask; the install command is unchanged, and the binary arrives without a
quarantine flag, so there is no Gatekeeper prompt on first run. (Published with
each tagged release; darwin/arm64 only, since the runtime requires macOS 26 on
Apple silicon.)
brew update
brew upgrade --cask suruseas/opossum/opossum
(Casks, which opossum has been since v0.24.2, are upgraded with --cask; see
the next heading for an install that is still the old formula.) You do not need
to stop a running project first. A project brought up by an earlier version is
recognised by the new one as its own, and the data in its named volumes is
still there after the upgrade. This was measured from v0.24.2, v0.43.0 and
v0.47.1 to v0.48.0; other pairs of versions were not tried. A service with
restart: keeps the supervisor the earlier version started, which carries on
until opossum down stops it. An image the earlier version built under another
name (v0.24.2 named the image of a service with both build: and image:
<project>-<service>) is not found by the new one, so the first up after the
upgrade recreates that container; what is in its volumes stays.
The formula does not turn into the cask by itself. Third-party casks sit behind
Homebrew's trust gate (Homebrew 5.1.15 and later), so brew update announces
the migration but stops at a warning instead of installing. Complete it with:
brew update
brew uninstall --formula --force opossum # frees /opt/homebrew/bin/opossum for the cask
brew trust --cask suruseas/opossum/opossum
brew install --cask suruseas/opossum/opossum
The uninstall comes first because the cask will not put its link where
something already sits — and when that something is the formula's own link, it
says so only in a warning (skipping link) and still reports
successfully installed, so nothing tells you the binary was never placed.
(Between the two commands opossum is briefly absent from your PATH; the
install at the end brings it back.) After that, which opossum points into
the Caskroom and opossum --version reports the current release.
If opossum is not found after migrating — an earlier version of this
guide ran the uninstall last, which could remove the only binary — the formula
is already gone and only the cask step is missing:
brew trust --cask suruseas/opossum/opossum
brew reinstall --cask suruseas/opossum/opossum # `install` if brew says it is not installed
opossum --version
If that stops with already a Binary at /opt/homebrew/bin/opossum, something
Homebrew doesn't own still sits there — check it with
ls -l /opt/homebrew/bin/opossum and move it aside before retrying.
make build # builds ./opossum with the version stamped in
# or, without make (a plain `go build` reports a dev version):
go build -ldflags "-X main.version=$(git describe --tags --always | sed 's/^v//')" -o opossum ./cmd/opossum
# then move it onto your PATH, e.g.
mv opossum /usr/local/bin/
Service discovery needs a local DNS domain registered with the system. Create it once — this persists across reboots:
sudo container system dns create opossum
Use a different name with --dns-domain <name> (and create that name instead).
Remove it later with sudo container system dns delete opossum.
If you run opossum up (or opossum doctor --fix, or opossum run, which starts
the services a one-off needs the way up does) at a terminal before that, it
tells you the domain is missing and asks whether to run the command for you:
Create it now? This runs: sudo container system dns create opossum [y/N]. Only
y or yes runs it, with sudo asking for your password itself; Enter, anything
else, or a run that is not at a terminal (CI, a pipe, an agent) runs nothing and
leaves the warning with the command to type. There is no setting that answers for
you.
If you have never used docker compose, or you are starting from an empty
directory rather than an existing file, read
Getting started: it takes you from a ready machine to
a web server and a database running together, and stopped again with its containers, network and data removed. To have
an AI agent do it for you, hand it AGENTS.md and describe what you
want running — its "Starting from nothing"
section is written for exactly that.
docker compose)opossum reads your existing compose.yaml / docker-compose.yml as-is — no
conversion, no new file. If you're switching from Docker Desktop you almost
certainly already have your images built, so the quickest way in is to reuse
those builds and skip Apple's (cold-starting) builder:
# One-time: start Apple container and register a local DNS domain so services
# can resolve each other by name
container system start
sudo container system dns create opossum
cd path/to/your-project
docker compose build # if you haven't already (or the images are already there)
opossum up --from-docker-compose # import each built image from Docker, then start
opossum names a built image just like docker compose (the service's image:
if it has one, <project>-<service> if not), and takes the project's name from
the same places (-p, COMPOSE_PROJECT_NAME, the file's name:, the directory)
— so the import lines up. If your directory name contains _ or
. the two tools normalize it differently, and opossum rewrites those
characters in a -p value as well (-p my_app is my-app to opossum and
my_app to docker compose), so pass both commands the same -p <name>, in
lowercase with neither character in it (docker compose refuses a -p with
capitals; opossum lowercases it without a word).
Plain opossum up builds a service whose image it does not have; where Docker
holds an image of that name, it says so first, with how long ago Docker built it
and the command that takes it (opossum import <service>), and builds all the
same — it never imports on its own.
That's it — the same project, running on Apple container. Work with it using
the verbs you already know:
opossum ps # services / IP / ports / status
opossum stats # live CPU / memory / net / I/O per service
opossum logs web --follow # follow a service's logs
opossum exec -it web sh
opossum down # stop + remove (add -v to also drop named volumes)
Prefer to build with Apple's builder? Drop --from-docker-compose and run
opossum up — opossum builds any build: service itself (a heavy build can be
slow; see Troubleshooting builds). Either way, run
opossum config first to preview the resolved configuration and any fields
opossum ignores (dns_search, container_name, …).
If a service doesn't come up, opossum warns about the usual causes at up
time and names the fix — an unregistered DNS domain, Postgres data on a volume
opossum didn't create, a host port already taken (on macOS a busy 5000/7000 is often AirPlay
Receiver).
Each one, and what to do →
Trying something new should be reversible. Teardown comes in three widths:
opossum down # daily: stop + remove containers and the network
opossum destroy # this project, gone: containers, volumes, images, generated state
opossum destroy --dry-run # see exactly what that would remove, and remove nothing
destroy removes everything opossum created for the project — containers
(including orphans), the project network, named volumes, images it built or
pulled, the restart supervisor, the .opossum/ state directory and the generated
compose.opossum.yaml. It asks first, and lists what it will remove; --force
skips the question for scripts and agents.
Your files are never touched — the compose file, .env and your sources are
left exactly as they are. Neither is anything shared: volumes declared
external: true, other projects' containers, and two machine-wide things that
destroy reports rather than removes, since one needs sudo and the other would
slow down every unrelated project:
sudo container system dns delete opossum # the local DNS domain
container builder delete --force && container image prune -a # build cache + unused images
opossum up # build + start everything (detached)
opossum up web # start only web and its dependencies
opossum up web --foreground # run a single service attached in the foreground
opossum ps # show service / container / IP / ports / status
opossum port web 3000 # print the host address:port a published port landed on
opossum ls # list the opossum projects on this machine (-a to include stopped ones)
opossum volumes # list the volumes the services mount that exist on the runtime
opossum logs # show logs for all services
opossum logs web --follow # follow one service's logs (-n N to tail)
opossum stats # live CPU/memory/net/IO per service (--no-stream for one snapshot)
opossum exec web ls -la # run a command in a running service
opossum exec -it web sh # interactive shell in a service
opossum run --rm web sh # one-off throwaway container for a service
opossum stop [service...] # stop services without removing them
opossum restart [service…] # stop then start services in place
opossum down # stop + remove services and the network
opossum -f path/to/compose.yaml up # custom compose file
opossum -p myproj up # override the project name
With no -f and no COMPOSE_FILE (read from the shell or the .env, as docker
compose reads it), opossum discovers a compose file in the working directory,
using docker-compose's precedence: compose.yaml, compose.yml,
docker-compose.yaml, then docker-compose.yml — so an existing
docker-compose.yml runs as-is.
Try the examples in the repository — a build-free hello.yaml and a full-feature
compose.yaml. See examples/README.md for a walkthrough
of every subcommand. They are not part of the Homebrew install or the release
tarball, so clone the repository first:
git clone https://github.com/suruseas/opossum && cd opossum
cd examples
opossum -f hello.yaml up
opossum -f hello.yaml ps
The example's web service prints the resolved IPs of db and cache on
startup, demonstrating name-based discovery.
Point the agent at AGENTS.md and ask it your question. It is a
facts-only reference written for a context window: the command surface, every
compose field opossum acts on / ignores / refuses, and a table mapping failure
signatures to fixes. The detailed compatibility questions — "will this field
work?", "why did this fail?" — are answered better by an agent that has read that
file than by a section of this README.
| Compatibility | The measurement and its method; every compose field and command; where behaviour differs from docker compose; reusing images you built with Docker |
| Compatibility promise | What a script, a CI job or a compose file can rely on across 1.x, and what it can't |
| Networking model | How services find each other, running several projects at once, reaching a service from the host |
| Troubleshooting | Build failures on container, and the limits worth knowing before you hit them |
| Benchmarks | Idle cost, start-up time, and what stats --host measures |
| vs Docker Desktop | A measured side-by-side: idle footprint, throwaway-container speed, build, disk, and the daily-operation gaps |
| MCP servers | Give an agent a tool server in its own VM |
| Agent sandboxes | Run something untrusted with no route out |
AGENTS.md | The same facts, for an AI agent |
| · |
Honestly, and in one place: opossum needs macOS 26 (container-to-container
networking depends on it — on macOS 15 this kind of orchestration isn't possible).
It implements a subset of the Compose specification, and refuses rather than
guesses when a field would change what your project means. A docker.sock mount
is a separate matter: the runtime refuses any bind whose source is a symlink to a
socket, whoever owns it. up warns about the rest, because nothing here answers
on that path about these containers. A named volume
can only be attached to one running container at a time, which is Apple
container's constraint, not a
choice. Swarm/deploy beyond resources.limits is ignored, and
opossum config tells you which fields in your file were skipped; extends:
— naming a service of the same file or of another file, in a chain — is read
as docker compose reads it.
The details, and what to do about each →
See CONTRIBUTING.md for setting up, running the tests
(against a fake runtime, so no Apple container is needed) and sending a pull
request. Changes that users would notice are listed in
CHANGELOG.md.
OPOSSUM_CONTAINER_BIN overrides which binary is invoked as the runtime. The
fake shim's output is kept in sync with the real CLI (see
testdata/real-cli-output.md).
opossum is developed primarily by autonomous AI coding agents, which plan, implement and test changes and review them independently before they land. A human maintainer sets direction, merges every pull request and decides when to release.
opossum is released under the MIT License.
opossum is not affiliated with, endorsed by, or sponsored by Docker, Inc. Docker and the Docker logo are trademarks or registered trademarks of Docker, Inc. in the United States and/or other countries.
CHANGELOG.md| History, and a walkthrough of every subcommand |