Skip to content

Podman and Dev Containers on macOS (Podman 6.x)

INFO

Guide for Podman 6.x (Homebrew, Apple Silicon, krunkit 1.2.x+).
Legacy guide for Podman 5.8: Podman and Dev Containers (Legacy)

These steps extend DDEV and Devcontainer — Devcontainer (Podman) when you work on macOS (Apple Silicon) with Podman and Dev Containers.

Podman 6.x (Homebrew) can use libkrun via krunkit. You need krunkit 1.2.x+ from the libkrun/krun tap, and you must set CONTAINERS_MACHINE_PROVIDER=libkrun (Homebrew’s default provider is still applehv). The older slp/krunkit tap (krunkit 1.1.x) is deprecated and causes Error: krunkit exited unexpectedly with exit code 2 with Podman 6.0. Homebrew may still redirect slp/krunlibkrun/krun; use libkrun/krun directly to avoid duplicate-tap conflicts.

All-in-one (copy-paste)

Run from the repository root in zsh. You will be prompted for your macOS password (sudo for podman-mac-helper). Adjust --memory if needed.

bash
setopt NULL_GLOB && (podman machine stop 2>/dev/null || true) && (podman machine rm -f 2>/dev/null || true) && rm -rf ~/.config/containers ~/.local/share/containers ~/.cache/containers ~/Library/Containers/io.podman* ~/Library/Application\ Support/Podman* ~/Library/Preferences/io.podman* && (brew uninstall -f podman podman-desktop 2>/dev/null || true) && brew cleanup && (brew list --full-name 2>/dev/null | grep "^slp/krunkit/" | xargs brew uninstall 2>/dev/null || true) && (brew untap slp/krunkit 2>/dev/null || true) && (brew untap slp/krun 2>/dev/null || true) && brew tap libkrun/krun && brew trust libkrun/krun && brew install libkrun/krun/krunkit && brew install podman && brew install --cask podman-desktop && export CONTAINERS_MACHINE_PROVIDER=libkrun && (grep -q 'CONTAINERS_MACHINE_PROVIDER=libkrun' ~/.zshrc || echo 'export CONTAINERS_MACHINE_PROVIDER=libkrun' >> ~/.zshrc) && (grep -q 'CONTAINERS_MACHINE_PROVIDER=libkrun' ~/.bashrc 2>/dev/null || echo 'export CONTAINERS_MACHINE_PROVIDER=libkrun' >> ~/.bashrc) && podman machine init --cpus 4 --memory 4096 --disk-size 100 && sudo "$(brew --prefix podman)/bin/podman-mac-helper" install && (podman machine stop 2>/dev/null || true) && podman machine start && (grep -q 'DOCKER_HOST=unix:///var/run/docker.sock' ~/.zshrc || echo 'export DOCKER_HOST=unix:///var/run/docker.sock' >> ~/.zshrc) && (grep -q 'DOCKER_HOST=unix:///var/run/docker.sock' ~/.bashrc 2>/dev/null || echo 'export DOCKER_HOST=unix:///var/run/docker.sock' >> ~/.bashrc) && export DOCKER_HOST=unix:///var/run/docker.sock && podman machine list && podman ps && (command -v devcontainer >/dev/null || npm install -g @devcontainers/cli) && devcontainer up --workspace-folder .

Step-by-step breakdown of the same flow:

1. Stop and remove any Podman machines

bash
podman machine stop 2>/dev/null && podman machine rm -f 2>/dev/null

2. Delete all Podman configuration and VM data

bash
# NULL_GLOB: zsh otherwise errors with "no matches found" when paths are absent
setopt NULL_GLOB
rm -rf ~/.config/containers ~/.local/share/containers ~/.cache/containers
rm -rf ~/Library/Containers/io.podman*
rm -rf ~/Library/Application\ Support/Podman*
rm -rf ~/Library/Preferences/io.podman*

3. Uninstall Homebrew Podman and Podman Desktop

bash
brew uninstall -f podman podman-desktop 2>/dev/null && brew cleanup

4. Install krunkit (Podman 6.x)

Podman 6.x expects krunkit 1.2.x+ with --timesync support. Install from the libkrun/krun tap (not the deprecated slp/krunkit tap). Do not also tap slp/krun — Homebrew redirects it to libkrun/krun, which creates duplicate formulae (gvproxy, etc.) and breaks the install.

bash
# Remove old / duplicate taps if present
brew list --full-name 2>/dev/null | grep "^slp/krunkit/" | xargs brew uninstall 2>/dev/null
brew untap slp/krunkit 2>/dev/null
brew untap slp/krun 2>/dev/null

brew tap libkrun/krun
brew trust libkrun/krun
brew install libkrun/krun/krunkit
krunkit --version   # should show 1.2.x or newer

If Homebrew rejects the tap as untrusted, run brew trust libkrun/krun and retry.

5. Install Podman CLI and Podman Desktop

bash
brew install podman && brew install --cask podman-desktop

6. Initialize a new Podman machine (example: 4 GB RAM)

On Apple Silicon, use the libkrun provider (not the default applehv/vfkit). Set the provider before init, and keep it in your shell profile so later start/stop use the same backend:

bash
export CONTAINERS_MACHINE_PROVIDER=libkrun
echo 'export CONTAINERS_MACHINE_PROVIDER=libkrun' >> ~/.zshrc
echo 'export CONTAINERS_MACHINE_PROVIDER=libkrun' >> ~/.bashrc

# Adjust --memory to your available RAM (4096 MB is a good starting point on a 16 GB host)
podman machine init --cpus 4 --memory 4096 --disk-size 100

podman machine list should show VM TYPE as libkrun. If you previously created an applehv machine, remove it first (podman machine rm -f) and init again with the provider set.

7. Set up a Docker-compatible socket for Dev Containers

export DOCKER_HOST=unix:///var/run/docker.sock only works if Podman provides that socket. Install the macOS helper first:

bash
sudo $(brew --prefix podman)/bin/podman-mac-helper install
podman machine stop && podman machine start

Then add to ~/.zshrc and ~/.bashrc (or export in the current shell only):

bash
echo 'export DOCKER_HOST=unix:///var/run/docker.sock' >> ~/.zshrc
echo 'export DOCKER_HOST=unix:///var/run/docker.sock' >> ~/.bashrc
source ~/.zshrc

Alternative without the helper: Point at Podman's socket via TMPDIR (works with the separate docker CLI that devcontainer invokes):

bash
echo 'export DOCKER_HOST="unix://${TMPDIR}podman/podman-machine-default-api.sock"' >> ~/.zshrc
echo 'export DOCKER_HOST="unix://${TMPDIR}podman/podman-machine-default-api.sock"' >> ~/.bashrc
source ~/.zshrc
docker ps   # should succeed

8. Start the VM and verify

bash
podman machine start && podman machine list && podman ps

9. Install the Dev Container CLI

If devcontainer is not available yet:

bash
npm install -g @devcontainers/cli

10. Start the project

From the repository root:

bash
devcontainer up --workspace-folder .

Troubleshooting

SymptomCauseFix
krunkit exited unexpectedly with exit code 2krunkit 1.1.x with Podman 6.xUpgrade krunkit via libkrun/krun to 1.2.x+ (step 4)
Formulae found in multiple taps (gvproxy)Both slp/krun and libkrun/krun tappedbrew untap slp/krun, then install from libkrun/krun
Refusing to load formula ... from untrusted tapTap trust missingbrew trust libkrun/krun
Cannot connect to Podman / connection refusedVM not running or wrong socketpodman machine start; check DOCKER_HOST (step 7)
Ignition emergency mode / applehv VM stuckDefault applehv provider, or stale VMpodman machine rm -f, set CONTAINERS_MACHINE_PROVIDER=libkrun, re-init (step 6)
devcontainer: command not foundCLI not installedStep 9