- 01.Starting Point
- 02.Attempt 1: Homebrew qemu — CLT too old
- 03.Attempt 2: macOS upgrade — hardware too old
- 04.Attempt 3: Docker Desktop — overlay networking broken
- 05.Attempt 4: MacPorts qemu — success
- 06.Starting Colima — missing firmware
- 07.Tailscale + Swarm Join
- 08.Overlay Verification
- 09.Where We Landed
- 10.Takeaways
Getting a 2017 Intel MacBook Pro into Docker Swarm
PHM Mac (MacBookPro14,3, 2017 15\" MBP, Intel i7, 16GB, macOS 13.7.8 Ventura) needed to join the Docker Swarm as an always-on worker for image-based services. The machine already had Colima 0.9.1 and D
Starting Point
PHM Mac (MacBookPro14,3, 2017 15" MBP, Intel i7, 16GB, macOS 13.7.8 Ventura) needed to join the Docker Swarm as an always-on worker for image-based services. The machine already had Colima 0.9.1 and Docker CLI 29.1.2 installed. Tailscale host was already renamed to joel-phm.
The plan from last session: install qemu (Intel Macs can't use the vz virtualization driver), start Colima, install Tailscale in the VM, join swarm.
Attempt 1: Homebrew qemu — CLT too old
brew install qemu had been running in the background from last session. It failed:
meson.build:1:0: ERROR: Compiler clang cannot compile programs.
The glib dependency (required by qemu) couldn't build from source. Homebrew was trying to compile because there's no pre-built bottle for x86_64 Ventura.
Checked CLT version:
$ pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep version
version: 14.3.1.0.1.1683849156Homebrew wanted CLT 15.2. But softwareupdate --list showed nothing available — Apple no longer provides CLT updates for macOS 13.
Paradoxically, clang itself works fine:
$ echo "int main(){return 0;}" | clang -x c - -o /dev/null
# exit 0 — compiles fine!The issue is Homebrew's sandboxed build environment is stricter than direct compilation. And HOMEBREW_NO_ENV_FILTERING=1 didn't help — Homebrew outright rejects the build as "Tier 2/3 configuration."
Checked for bottles: brew fetch --bottle-tag=ventura glib succeeds, but that's the ARM64 bottle. brew install --force-bottle glib confirms: "glib has no bottle!" (for x86_64 Ventura).
Attempt 2: macOS upgrade — hardware too old
Thought: upgrade to Sonoma (macOS 14) for Tier 1 Homebrew support.
$ system_profiler SPHardwareDataType | grep "Model Identifier"
Model Identifier: MacBookPro14,3MacBookPro14,3 = 2017 MacBook Pro. macOS Sonoma requires 2018+. Confirmed by:
$ softwareupdate --list-full-installers
# Only shows macOS 13 and oldermacOS 13 Ventura is the maximum this hardware supports. Dead end.
Attempt 3: Docker Desktop — overlay networking broken
Docker Desktop manages its own VM, no qemu needed. But the latest (4.53+) requires Sonoma.
$ defaults read /Applications/Docker.app/Contents/Info.plist LSMinimumSystemVersion
14.0Found that Docker Desktop 4.48.0 (build 207573) is the last to support Ventura:
$ curl -L -o /tmp/Docker.dmg "https://desktop.docker.com/mac/main/amd64/207573/Docker.dmg"Installed, launched (had to dismiss a deprecation dialog that was blocking startup — killing the process interrupted the flow, had to restart and use AppleScript). Docker Desktop started successfully with Server Version 28.5.1.
Joined swarm with host's Tailscale IP:
$ docker swarm join --token SWMTKN-... 100.70.190.8:2377 --advertise-addr 100.77.202.35
This node joined a swarm as a worker.Deployed test service, tested from medina:
$ curl -s -H "Host: test-phm.digitalpine.io" http://localhost:80
Bad GatewayRoot cause: Docker Desktop uses vpnkit (userspace networking). Swarm overlay needs VXLAN (UDP 4789) and gossip (TCP/UDP 7946) ports accessible on the advertised IP. Checked:
$ lsof -i :4789 -i :7946 -i :2377
# Only 2377 (management, outbound) — no listeners on 4789 or 7946!Docker Desktop's VM doesn't expose overlay data plane ports to the host network. Management works (outbound connection to leader), but overlay data plane (inbound VXLAN) doesn't reach the VM.
Docker Desktop cannot participate in multi-host swarm overlay networking on macOS. Only useful for local dev.
Attempt 4: MacPorts qemu — success
MacPorts still supports older macOS. Downloaded and installed:
$ curl -L -o /tmp/MacPorts.pkg "https://distfiles.macports.org/MacPorts/MacPorts-2.10.5-13-Ventura.pkg"
$ sudo installer -pkg /tmp/MacPorts.pkg -target /
$ sudo /opt/local/bin/port install qemuMacPorts installed qemu 10.2.0 with pre-built binaries (no compilation needed).
Problem: /opt/local/bin isn't in PATH, and Colima/Lima looks for qemu in standard locations.
Fix: symlink to /usr/local/bin:
$ ln -sf /opt/local/bin/qemu-system-x86_64 /usr/local/bin/qemu-system-x86_64
$ ln -sf /opt/local/bin/qemu-img /usr/local/bin/qemu-imgStarting Colima — missing firmware
$ colima start --cpu 2 --memory 4 --disk 60 --vm-type qemuFailed with:
could not find firmware for "x86_64" (hint: try setting `firmware.legacyBIOS` to `true`)
Lima searches these paths for UEFI firmware:
/Users/joel/.local/share/qemu/edk2-x86_64-code.fd
/usr/local/share/qemu/edk2-x86_64-code.fd
/usr/local/bin/share/edk2-x86_64-code.fd
/usr/share/edk2/x64/OVMF_CODE.4m.fd
...
MacPorts installed firmware at /opt/local/share/qemu/edk2-x86_64-code.fd — not in any of Lima's search paths.
Fix: symlink the firmware:
$ mkdir -p /usr/local/share/qemu
$ ln -sf /opt/local/share/qemu/edk2-x86_64-code.fd /usr/local/share/qemu/edk2-x86_64-code.fdAfter that, Colima started successfully:
[hostagent] Using system firmware ("/usr/local/share/qemu/edk2-x86_64-code.fd")
[hostagent] Starting QEMU (hint: to watch the boot progress, see "/Users/joel/.colima/_lima/colima/serial*.log")
...
done
Tailscale + Swarm Join
Standard procedure from here:
$ colima ssh -- sh -c 'curl -fsSL https://tailscale.com/install.sh | sh'
$ colima ssh -- sudo tailscale up --hostname=joel-phm-colima
# Auth via browser URL
$ colima ssh -- tailscale ip -4
100.65.155.33
$ colima ssh -- docker swarm join --token SWMTKN-... 100.70.190.8:2377 --advertise-addr 100.65.155.33
This node joined a swarm as a worker.Added label: docker node update --label-add host=joel-phm-colima <node-id>
Overlay Verification
Deployed whoami on PHM, tested from medina (GCP edge):
$ curl -s -H "Host: test-phm.digitalpine.io" http://localhost:80
Hostname: 05cb9eae104c
IP: 10.0.1.105
RemoteAddr: 10.0.1.206:33442
...Full public path also works:
$ curl -s https://test-phm.digitalpine.io
Hostname: 05cb9eae104cInternet → Cloudflare → cloudflared (medina) → Traefik (medina) → overlay → PHM Colima VM. End to end.
Where We Landed
PHM is a fully operational swarm worker:
| Node | Tailscale IP | Role | Swarm Label |
|---|---|---|---|
| medina-gcp-edge | 100.70.190.8 | Leader + edge | medina-gcp-edge |
| joel-desktop-wsl | 100.123.211.60 | Manager | nauvoo-bru-home-pc-wsl |
| joel-m3-colima | 100.83.31.128 | Manager | rocinante-bru-m3 |
| joel-phm-colima | 100.65.155.33 | Worker | joel-phm-colima |
Docker Desktop removed from PHM (not useful for swarm).
Takeaways
Docker Desktop cannot do multi-host swarm on macOS. The vpnkit networking layer doesn't expose VXLAN (4789) or gossip (7946) ports to the host. Management traffic works (outbound TCP 2377) but overlay data plane is dead. This isn't documented anywhere obvious — you only discover it when Bad Gateway shows up and you check lsof.
MacPorts is the escape hatch for old macOS + Homebrew failures. When Homebrew can't build (Tier 2/3, missing bottles, old CLT), MacPorts often has pre-built binaries because they support older platforms longer.
Lima firmware search paths don't include /opt/local/share/qemu/. When using MacPorts qemu, you must symlink edk2-x86_64-code.fd to /usr/local/share/qemu/.
2017 MacBook Pros max out at macOS 13. Can't upgrade to Sonoma. Docker Desktop latest requires Sonoma. Homebrew is Tier 2/3 on Ventura Intel. The only viable Docker path is: MacPorts → qemu → Colima → Tailscale in VM.
The complete recipe for Intel Mac (macOS 13) swarm setup:
# 1. Install MacPorts (from .pkg)
sudo installer -pkg MacPorts-2.10.5-13-Ventura.pkg -target /
# 2. Install qemu
sudo /opt/local/bin/port install qemu
# 3. Symlink for Colima/Lima
ln -sf /opt/local/bin/qemu-system-x86_64 /usr/local/bin/qemu-system-x86_64
ln -sf /opt/local/bin/qemu-img /usr/local/bin/qemu-img
mkdir -p /usr/local/share/qemu
ln -sf /opt/local/share/qemu/edk2-x86_64-code.fd /usr/local/share/qemu/edk2-x86_64-code.fd
# 4. Start Colima
colima start --cpu 2 --memory 4 --disk 60 --vm-type qemu
# 5. Tailscale in VM
colima ssh -- sh -c 'curl -fsSL https://tailscale.com/install.sh | sh'
colima ssh -- sudo tailscale up --hostname=joel-phm-colima
# 6. Join swarm
colima ssh -- docker swarm join --token <TOKEN> <MANAGER_IP>:2377 --advertise-addr $(colima ssh -- tailscale ip -4)