Skip to content

Docker (macOS)

App-name local development runs on Docker Desktop on macOS. Docker is the engine behind the local Supabase stack (supabase start) and lets you build and run the app's own images to mirror production. This page covers installing and configuring Docker Desktop on Apple Silicon, the two local workflows, the architecture caveat (your Macs are arm64, the EC2 hosts are amd64), and macOS-specific troubleshooting.

For the dev loop itself see Local Development; for the local Supabase stack see Supabase (Local); for the production image/compose shapes see Docker & GHCR.

What Docker runs locally

  • The local Supabase stacksupabase start launches Postgres, Auth, Storage, and Studio as Docker containers.
  • App images — you can build and run the backend/frontend images the same way CI does, to reproduce production behaviour locally.

Install Docker Desktop

# Apple Silicon (Homebrew)
brew install --cask docker

Or download the Apple Silicon build from docker.com. Launch Docker Desktop once, approve the privileged-helper prompt, and accept the terms. When the whale icon in the menu bar stops animating, the daemon is running. In Settings → General, enable Start Docker Desktop when you log in.

Docker Desktop licensing

Docker Desktop requires a paid subscription for organisations with more than 250 employees or more than \$10M in annual revenue. Confirm Twycis has the appropriate licence, or switch the team to a free runtime (OrbStack, Colima) — the docker/docker compose commands on this page are identical either way.

Verify the install:

docker --version
docker compose version
docker run --rm hello-world

Configure resources

The Supabase stack plus app containers need headroom. In Settings → Resources:

Setting Recommended minimum
CPUs 4
Memory 8 GB
Disk image size 60 GB

In Settings → General, select VirtioFS for file sharing — it gives the fastest bind-mount I/O on Apple Silicon (important for hot-reload performance). Make sure your repo path is covered by Settings → Resources → File sharing (your home directory is shared by default).

Apple Silicon and image architecture

arm64 locally, amd64 in production

Your Macs are arm64 (Apple Silicon). The EC2 hosts — and the images CI builds and ships to GHCR — are amd64. Most of the time this is invisible, but it matters when you build the app images yourself.

  • Supabase publishes multi-arch images, so supabase start runs natively on arm64. Nothing to do.
  • Building app images to run locally → build for native arm64 (fast):

    docker build -t app-name-backend ./backend
    
  • Building app images to match production exactly → build amd64. It runs under Rosetta emulation (slower), so reserve it for parity checks:

    docker buildx build --platform linux/amd64 -t app-name-backend ./backend
    

Enable Settings → General → Use Rosetta for x86/amd64 emulation so emulated amd64 containers run. A no matching manifest for linux/arm64 or exec format error almost always means an architecture mismatch — see Troubleshooting.

Two local workflows

A. Native app + dockerized Supabase (default)

The everyday loop in Local Development: Docker runs only Supabase, while the app runs natively (uvicorn + Vite). This is the lightest, fastest path and what you'll use day-to-day.

supabase start                                  # Supabase in Docker
cd backend && uvicorn app.main:app --reload --port 5001
cd frontend && npm run dev

B. Full stack in Docker (parity testing)

Build and run the app containers with Compose to reproduce production — same images, nginx, and runtime env injection. Use this to catch container-only issues (build, env, networking) before they reach test or production. The compose shapes are documented in Docker & GHCR.

docker compose build
docker compose up -d --wait
docker compose logs -f app
docker compose down

Reaching local Supabase from app containers

A container can't see localhost:54321 on your Mac — that's the container's own loopback. Use host.docker.internal:54321 (API) and host.docker.internal:54322 (Postgres) in the container's env, or attach the app to the Supabase Docker network.

Common commands

Command Purpose
docker ps / docker ps -a List running / all containers
docker compose up -d / docker compose down Start / stop the compose stack
docker compose logs -f <service> Follow a service's logs
docker compose build Rebuild images from the Dockerfiles
docker exec -it <container> sh Open a shell inside a running container
docker image ls List local images
docker system df Show Docker disk usage
docker system prune -af --volumes Reclaim space — removes stopped containers, unused images, and volumes
docker stats Live CPU/memory per container

macOS troubleshooting

Symptom Cause Fix
Cannot connect to the Docker daemon Docker Desktop isn't running Start Docker Desktop and wait for the whale icon to settle
port is already allocated (5432154323, 5432, 5001) A previous stack or another process holds the port supabase stop; find the holder with lsof -i :54322; stop the conflicting container
no matching manifest for linux/arm64 / exec format error Running an amd64-only image on arm64 (or vice-versa) Rebuild/pull with --platform linux/amd64 and enable Rosetta, or build native arm64
no space left on device Docker disk image is full docker system prune -af --volumes; raise the disk limit in Settings → Resources
Slow hot reload / sluggish file I/O Bind mount on the legacy gRPC FUSE driver Switch to VirtioFS in Settings → General
supabase start hangs or errors Docker not ready, or stale containers Confirm Docker is running; supabase stop --no-backup then supabase start
Beachballs / high memory pressure Resource limits too low (or starving macOS) Tune CPUs/Memory in Settings → Resources

Where things connect

Topic Page
Local Supabase stack, ports, env Supabase (Local)
The local dev loop Local Development
App images, compose, GHCR Docker & GHCR
First-time machine setup Developer Onboarding