Your Compose files work as they are
Every subcommand, flag, profile, and file format works, because it is Docker Compose. No conversion step, no unsupported keys.
compose up -d
compose logs -f api
compose exec db psql
container.Run your existing compose.yaml files on Apple’s container, unchanged. The plugin adds the Compose that container lacks, running Docker Engine and Docker Compose inside one lightweight Linux machine.
$ brew install RobertDeRose/tap/container-compose-plugin
Free and open source under Apache-2.0. macOS 15 or newer on Apple silicon.
$ compose up -d
[+] Running 5/5
✔ Network my-app_default Created
✔ Container my-app-db-1 Started
✔ Container my-app-cache-1 Started
✔ Container my-app-api-1 Started
✔ Container my-app-web-1 Started
$ curl localhost:8080/health
{"status":"ok"}
The plugin doesn’t reimplement or translate Compose. It runs the real docker compose in a Linux machine managed by container, and handles the parts that make it feel local.
Every subcommand, flag, profile, and file format works, because it is Docker Compose. No conversion step, no unsupported keys.
compose up -d
compose logs -f api
compose exec db psql
TCP ports your services publish appear on 127.0.0.1 and ::1 within seconds, the way Docker Desktop does it. Loopback only, never your LAN.
ports:
- "8080:80" # open localhost:8080
Point the docker CLI, your IDE, or Testcontainers at the Docker Engine inside the machine. Fast enough to run in every new shell, and it doesn’t boot the machine until a tool connects.
export DOCKER_HOST="$(compose --socket-path)"
compose. Images, volumes, networks, and build cache survive compose down and restarts../src:/app just work.containercontainer compose, and bash, zsh, and fish completions are generated without booting anything.A thin client over the public APIs of container. Your first command creates the machine; every later one reuses it.
compose makes sure the plugin is registered with your current container, then hands off to container compose.container finds the plugin and passes it your arguments.compose machine on first use, or verifies the existing one is its own.docker compose inside the machine, relaying input, output, terminal size, and signals.Your Mac
compose upDOCKER_HOSTlocalhost:8080Linux machine compose
Your home folder, mounted at the same path
Docker Desktop and Podman Desktop are full desktop apps that bring their own virtual machine. If you already use Apple’s container, or want the least software running on your Mac, this plugin adds Compose and nothing else.
| Feature | container compose | Docker Desktop | Podman Desktop |
|---|---|---|---|
| Cost | Free for everyone | Paid subscription for larger companies | Free for everyone |
| License | Apache-2.0 | Proprietary | Apache-2.0 |
| What you install | A CLI plugin for container |
A desktop app with background services | A desktop app plus the Podman CLI |
| Virtual machine | Apple’s container machine |
Docker’s own Linux VM | A Podman machine |
| Compose engine | Docker Compose on Docker Engine | Docker Compose on Docker Engine | An external Compose provider against Podman |
| Ports on localhost | TCP | TCP and UDP | TCP and UDP |
| Docker API socket | Yes, opt-in, private to your user | Yes | Yes, Docker-compatible |
| Graphical interface | Optional and customizable | Yes | Yes |
| Kubernetes | Built into container as container k8s |
Built in | Through Kind or Minikube |
| Platforms | macOS on Apple silicon | macOS, Windows, Linux | macOS, Windows, Linux |
container and miss Compose.Pick the route that matches how you installed container. Homebrew and mise also give you the compose command, which re-registers the plugin whenever container is upgraded, so it keeps working.
Installs container too if it’s missing, and adds a shorter compose command that keeps the plugin registered across brew upgrade.
brew install RobertDeRose/tap/container-compose-plugin
container system start
compose --help
Installs container and the plugin with no elevated privileges, and adds the compose command. It registers the plugin with mise’s container on first use, and again after mise upgrade.
mise use -g container 'github:RobertDeRose/container-compose-plugin[bin_path=cli,strip_components=1]'
container system start
compose --help
Apple’s package installs under /usr/local, so the installer asks for your password. Download with gh or curl, not a browser: release builds aren’t notarized.
gh release download --repo RobertDeRose/container-compose-plugin --pattern '*-darwin-arm64.tar.gz*'
shasum -a 256 -c container-compose-plugin-*-darwin-arm64.tar.gz.sha256
tar -xzf container-compose-plugin-*-darwin-arm64.tar.gz
container system start
./compose/install.sh
This route doesn’t add the compose command. Type container compose wherever this page says compose, and run the installer again after upgrading container.
Needs Swift 6.2 or newer.
git clone https://github.com/RobertDeRose/container-compose-plugin.git
cd container-compose-plugin
container system start
make install
This route doesn’t add the compose command. Type container compose wherever this page says compose, and run make install again after upgrading container.
cd ~/projects/my-app
compose up -d
The first run pulls the machine image and boots the machine, so it takes longer. After that, commands start in the already-running machine.
localhost.localhost reaches that app instead. AirPlay Receiver holds 5000 and 7000; pick other ports or turn it off.container machine delete removes all Docker data, including volumes.There’s no built-in GUI, so you choose your own. A web dashboard runs as a Compose project like any other, its page appears on localhost, and Safari’s File → Add to Dock turns it into an app.
Arcane manages containers, images, volumes, networks, and Compose projects, closest to the dashboard in Docker Desktop. Source on GitHub, BSD-3-Clause.
Arcane encrypts what it stores with a key of your own. This creates one, and leaves an existing key alone:
mkdir -p ~/arcane && cd ~/arcane
[ -f .env ] || { key=$(openssl rand -hex 32) && printf 'ARCANE_ENCRYPTION_KEY=%s\n' "$key" > .env; }
Save this as ~/arcane/compose.yaml:
services:
arcane:
image: ghcr.io/getarcaneapp/manager:latest
ports:
- "3552:3552"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- arcane-data:/app/data
environment:
APP_URL: http://localhost:3552
ENCRYPTION_KEY: ${ARCANE_ENCRYPTION_KEY}
ANALYTICS_DISABLED: "true" # Arcane sends usage analytics unless this is set
cgroup: host
restart: unless-stopped
volumes:
arcane-data:
Run compose up -d in ~/arcane, open localhost:3552, and sign in as arcane with password arcane-admin. Arcane asks you to change it, and has no setting to skip signing in. Keep ~/arcane/.env with any backup of Arcane’s data: its key decrypts the credentials Arcane stores. For a projects folder on your Mac, more users, or single sign-on, see Arcane’s docs.
Dockge focuses on Compose stacks: write, start, stop, and update them, with live logs and a terminal. Each stack stays a plain folder with a compose.yaml, so compose in that folder sees the same project. MIT licensed.
mkdir -p ~/dockge/stacks && cd ~/dockge
Save this as ~/dockge/compose.yaml:
services:
dockge:
image: louislam/dockge:1
ports:
- "5001:5001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
- ${HOME}/dockge/stacks:${HOME}/dockge/stacks
environment:
DOCKGE_STACKS_DIR: ${HOME}/dockge/stacks
restart: unless-stopped
Run compose up -d in ~/dockge, open localhost:5001, and create your admin account. Dockge is reachable only from this Mac, so if you’d rather not sign in, turn it off under Settings → Security → Disable Auth. For everything else, see Dockge’s README.
Anything that speaks the Docker API can manage your Compose projects, through the Docker socket the plugin provides.
Apps on your Mac, such as the docker CLI, lazydocker, VS Code’s Container Tools, JetBrains IDEs, and Testcontainers, connect through DOCKER_HOST. Add this to your shell profile:
export DOCKER_HOST="$(compose --socket-path)"
For an app that has its own Docker connection setting, paste the address compose --socket-path prints. The socket listens once any compose command has run since you logged in, and your shell profile takes care of that.
Web dashboards, such as Portainer or the log viewer Dozzle, run like Arcane and Dockge above: mount /var/run/docker.sock in their compose.yaml and publish their port.
A running dashboard keeps the machine on
If you’ve turned on idle shutdown with idle-shutdown-seconds, a dashboard counts as activity, so the machine never powers off while it runs. Run compose down in the dashboard’s folder when you’re done with it.