How to Build a Mac-Within-a-Mac Toolbox?
A persistent Linux box on your Mac for installing things you do not entirely trust, running services that start at login, and keeping the mess out of your real machine.
Ingredients
- A Mac — Apple Silicon ideally; Tahoe (26), Sequoia (15), or Sonoma (14) all work
- OrbStack — free for personal use
- About 15 GB of free disk
- An empty folder for the shared bridge
- A vague idea of what you want to install in there
Why a toolbox?
Every developer’s Mac slowly turns into a museum: a half-finished
Postgres install from a project two years ago, a Homebrew tap that
won’t upgrade, three Pythons fighting over /usr/local,
an npm CLI from a Hacker News thread that probably did
something on its way through your home directory.
A toolbox is a Linux machine on your Mac with three rules:
- One shared folder. Files cross the boundary one way: through a folder you choose. Nothing else is reachable.
- Disposable. If it gets weird, you delete it and rebuild in a minute. The Mac never noticed it was there.
- Always on. It starts when you log in, its services come up with it, and apps on the Mac talk to it as if it were localhost.
Concretely, this is where you should be installing:
- That random
curl … | bashinstaller you do not want to read all the way through. - The CLI from a forum post that has 4 GitHub stars and a screenshot of it doing exactly the thing you need.
- A self-hosted service you want running 24/7 — SearXNG, n8n, a small Postgres, a syncthing relay, an MCP server, an LLM gateway.
- Anything written in a language whose package manager downloads ten thousand transitive dependencies on first run.
- Whole-system experiments — pin a kernel version, try a new shell as PID 1, install conflicting versions of the same tool side by side.
This recipe is a different shape from the
per-workload Apple container approach:
there each task gets its own micro-VM that dies when it exits; here
one Linux box lives across reboots, holds state, and runs services.
Different problem, different tool. Both are useful; you may well end
up with both installed.
1 Install OrbStack
brew install orbstack
Open the OrbStack app once so it can install its virtualisation helpers. When the first-run wizard asks what you want, pick Linux machines (the container side is not needed for this recipe; you can turn it on later).
2 Cap resources
In OrbStack → Settings → System:
- Memory limit: 4 GB (raise if you run hungry services)
- CPU limit: 4 cores
- Disk size: 20 GB — sparse, so it only consumes what is actually used
3 Create the toolbox
orb create ubuntu:24.04 toolbox
Drop into it:
orb shell -m toolbox
You are now inside a fresh Ubuntu 24.04 install with systemd
running as PID 1, your Mac username as the default user, and
passwordless sudo. This is the playground.
4 Pick exactly one shared folder
By default OrbStack auto-mounts your entire Mac home directory at
/mnt/mac inside the VM. For a toolbox that is the
opposite of what you want — the whole point is that
things installed in here cannot see ~/Documents,
~/Downloads, or your SSH keys.
Turn the broad mount off in Settings → File Sharing (uncheck “Mount user home directory”), and add one explicit mapping:
- Mac path:
~/toolbox-share - Linux path:
/share - Mode: read & write
mkdir -p ~/toolbox-share
From inside the VM, verify:
ls -la /share
touch /share/hello.txt
# the file appears on the Mac immediately
5 Install things without fear
Inside the toolbox, install whatever you like. A reasonable starter kit:
sudo apt update
sudo apt install -y build-essential curl git tmux htop jq \
sqlite3 ripgrep fd-find unzip
# Your own Python
curl https://pyenv.run | bash
# Your own Node
curl -fsSL https://fnm.vercel.app/install | bash
# Linuxbrew, if you want a second package manager
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
None of this touches your Mac. pip install --user
very-suspicious-package, npm i -g something-shady,
curl … | sudo bash — whatever happens
happens inside this 20 GB box and nowhere else.
~/toolbox-share. That is usually what you want. If you
also want network isolation, add an iptables egress
rule inside the VM — OrbStack does not police outbound
traffic for you.
6 Run services inside the toolbox
Ubuntu 24.04 in OrbStack runs real systemd. Anything
you install that ships a system service can be enabled the normal
way:
sudo apt install -y postgresql
sudo systemctl enable --now postgresql
sudo systemctl status postgresql
For your own apps, write a tiny user service so you do not need
sudo for it:
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/my-app.service <<'EOF'
[Unit]
Description=My App
After=network-online.target
[Service]
ExecStart=/home/me/.local/bin/my-app --port 8080
Restart=on-failure
RestartSec=3
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable --now my-app
# so user services start at VM boot, not at login
sudo loginctl enable-linger $USER
That last command — loginctl enable-linger —
is the one most tutorials skip. Without it your user services only
run while you have an active shell in the VM, and die the moment
the SSH connection drops.
7 Reach the services from the Mac
OrbStack auto-publishes anything the VM listens on. If
my-app binds to port 8080 inside the toolbox, on the
Mac you can hit it at:
# by machine name (preferred — no port conflicts)
curl http://toolbox.orb.local:8080/
# or by localhost, if no Mac app is using that port
curl http://localhost:8080/
Mac apps see these as ordinary network services — your browser,
psql, a desktop database GUI, all work without
configuration. Conversely, services on the Mac are reachable from
inside the VM at host.orb.internal.
8 Start at login
Two switches, both off by default:
- OrbStack itself starts at login. Open OrbStack → Settings → General, and turn on “Start at login”.
- The toolbox machine starts when OrbStack starts. On the Linux machines page, right-click toolbox → “Start on launch”.
That is enough for normal use: you log in, OrbStack comes up, the
toolbox boots, systemd inside it brings up Postgres
and your services, and ports are immediately reachable from Mac
apps.
9 Belt-and-braces with launchd
If the toolbox is hosting something you really do not want to be
down — say a sync service or a self-hosted dashboard you keep
open all day — back the OrbStack auto-start up with a
launchd agent. Even if OrbStack crashes or quits, this
will bring it (and the machine) back.
Save as ~/Library/LaunchAgents/dev.howto.toolbox.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>dev.howto.toolbox</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/orb</string>
<string>start</string>
<string>toolbox</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<key>ThrottleInterval</key>
<integer>30</integer>
<key>StandardOutPath</key>
<string>/tmp/orb-toolbox.log</string>
<key>StandardErrorPath</key>
<string>/tmp/orb-toolbox.err</string>
</dict>
</plist>
Load it:
launchctl load -w ~/Library/LaunchAgents/dev.howto.toolbox.plist
Now launchd will start the toolbox at login and
restart orb start toolbox within 30 seconds if it ever
exits non-zero. To disable:
launchctl unload -w ~/Library/LaunchAgents/dev.howto.toolbox.plist
/opt/homebrew/bin/orb, the Apple Silicon Homebrew
location. On Intel Macs change it to /usr/local/bin/orb.
Run which orb if unsure.
Backups
The toolbox is supposed to be disposable, but the data in
~/toolbox-share is on your Mac and gets swept up by
Time Machine like anything else — no extra work. For
VM-internal state worth keeping (databases, dotfiles), the cheapest
backup is to tar them into the shared folder on a
cron:
# inside the toolbox
crontab -e
# nightly snapshot of Postgres to the Mac side
0 3 * * * /usr/bin/pg_dumpall -U postgres | gzip > /share/backups/pg-$(date +\%F).sql.gz
Burn it down, rebuild in a minute
Anything in here gone wrong? The reset is unceremonious:
orb delete toolbox
orb create ubuntu:24.04 toolbox
~/toolbox-share on the Mac is not touched. If you
anticipate doing this often, keep a small bootstrap script in the
shared folder (/share/bootstrap.sh) that re-installs
your preferred set of tools — one command and you are back.
What you end up with
A real Linux machine on your Mac, capped at 4 cores / 4 GB / 20 GB,
that boots when you log in, brings its services up via
systemd, and is reachable from Mac apps on
toolbox.orb.local. The only path between it and
your real machine is one folder. Anything you install in here
— trustworthy or not — cannot escape the box, and
if it ever misbehaves you delete the whole thing and recreate
it in under a minute.
Other runtimes that fit the shape
OrbStack is the smoothest path, but the same idea works with other VM runtimes. The trade-offs are mostly about ergonomics:
- Multipass — Canonical’s pure Ubuntu VM. Same persistent-machine model, slower file sharing (SSHFS), no GUI.
- Colima — command-line only, MIT-licensed. Best when you want zero GUI surface area and you are happy editing YAML.
-
Apple
container— a different shape: per-workload micro-VMs, not a persistent box. Worth knowing about, not what you want here.