Getting Started with DynoCap

Install DynoCap on an Apple Silicon Mac, prepare one project, and run a command inside an isolated Linux guest.

You will:

  1. Install the CLI with Homebrew, or with curl.
  2. Check your setup with dynocap doctor.
  3. Repair it with dynocap doctor --fix.
  4. Launch a raw sandbox and execute commands over vsock.
  5. Safely destroy the sandbox.

Prerequisites

  • Hardware: Apple Silicon Mac (M1 or newer). Intel Macs are refused by the installers.
  • Operating System: macOS 13 (Ventura) or newer.
  • Homebrew, for the primary install. The formula also installs e2fsprogs, which provides mke2fs. That formula is keg-only; DynoCap finds it at /opt/homebrew/opt/e2fsprogs/sbin/mke2fs.
  • Go 1.22+ (brew install go) the first time a runtime is prepared. The guest image ships in the release archive, so a Homebrew or curl install does not need Go to copy it. Swift and Node are for a source build and for this repository’s TypeScript packages.

Step 1: Install

DynoCap uses Apple’s Virtualization.framework, which requires the com.apple.security.virtualization entitlement. There is no Apple Developer ID signature. Both installers re-sign the CLI on your Mac with codesign --sign - and the bundled entitlement. Neither installer uses a Homebrew bottle, because a poured bottle would skip that re-sign.

Homebrew

Shell
brew install baires/tap/dynocap

That installs the formula from baires/homebrew-tap. On Homebrew 6, this fully qualified name trusts that formula.

Trust it explicitly when you want later commands to use the short name dynocap, such as brew upgrade dynocap:

Shell
brew trust --formula baires/tap/dynocap

The formula downloads the versioned release archive, checks its sha256, and re-signs dynocap. Then run doctor in your project, which the formula also prints as a caveat:

Shell
dynocap doctor --fix

Curl

Shell
curl -fsSL https://dynocap.dev/install.sh | sh

The site serves scripts/install.sh. The script downloads dynocap-darwin-arm64.tar.gz from the latest GitHub release, checks its sha256, installs it under ~/.local/dynocap, and symlinks ~/.local/bin/dynocap. The checksum catches a truncated download. When gh is installed and logged in, the script also requires a build attestation from baires/dynocap. Its last step is dynocap doctor --fix. If mke2fs is missing, it tells you to run brew install e2fsprogs. If ~/.local/bin is not on PATH, it tells you to add it.

From source

A checkout has no bundled guest image. Building needs Xcode Command Line Tools (Swift 5.9+), Go 1.22+, and mke2fs (brew install e2fsprogs).

Shell
./scripts/build-macos.sh
export PATH="$PWD/.build/release:$PATH"

Re-run ./scripts/build-macos.sh after every rebuild so the binary stays signed. npm ci is for the repository’s TypeScript packages, not for the CLI.


Step 2: Check Your Setup

Go to your project and run dynocap doctor. It checks the platform, code signing, companion binaries, guest image, runtime, and daemon, and changes nothing:

Shell
cd ~/code/my-app
dynocap doctor

Doctor reads your project’s files to pick its runtime, the same way clone does:

File at the project root Runtime
package.json node:24
pyproject.toml, uv.lock, requirements.txt, setup.py, Pipfile python:3.14
go.mod go:1.27

On a fresh source build, the guest image and runtime are not built yet. A Homebrew or curl install already contains the guest image, and --fix copies it into your home. Each failure says what is wrong and what to run:

Text
ERROR   images             The guest image for aarch64 has not been built yet.
                           Next: Run dynocap doctor --fix to build the guest image (downloads pinned Alpine files; needs Go).
ERROR   runtime            Runtime python:3.14 is not prepared for aarch64 yet. This project's pyproject.toml needs it.
                           Next: Run dynocap doctor --fix to prepare python:3.14 (downloads verified inputs; takes a few minutes).

2 required checks failed. Run dynocap doctor --fix to repair them.

To prepare a different runtime, pass --runtime, for example dynocap doctor --fix --runtime node:22. Run outside a project, doctor requires no runtime. It lists the prepared ones instead, because raw sandboxes need none.


Step 3: Repair It with doctor --fix

Shell
dynocap doctor --fix

--fix copies a bundled guest image when the install has one, and builds it otherwise. It prepares your project’s runtime and restarts a daemon left over from an older build. Every download is pinned and verified. It then runs the checks again and ends with Required checks passed.

Doctor finds that prefix from the dynocap binary, whether it is a source checkout or a Homebrew or curl install, so you can run it in any directory. You can also name the project instead of changing directory: dynocap doctor --fix ~/code/my-app.

Tip: After you rebuild dynocap, run dynocap doctor --fix again. It restarts the daemon so it runs the new build.


Step 4: Boot a Raw Sandbox

A raw sandbox boots the minimal Alpine Linux image without importing a project workspace.

Start a sandbox named my-first-box:

Shell
dynocap run --name my-first-box

Output:

Text
running my-first-box

Behind the scenes:

  1. The dynocap CLI launched the per-user background daemon (~/.dynocap/daemon.sock).
  2. The daemon booted a Linux virtual machine with 1 vCPU and 1024 MB RAM via Virtualization.framework.
  3. The guest booted its initramfs in under 200ms and launched the internal Go dynocap-agent.
  4. The agent connected back over virtio-vsock (guest port 5252).

Verify the sandbox status:

Shell
dynocap ps

You will see:

Text
NAME/ID       KIND     PHASE    RUNTIME  NETWORK  TTL    RETENTION
my-first-box  sandbox  running  minimal  none     29m    -

Notice that NETWORK is none. The sandbox is completely offline. No network interface exists inside the guest.


Step 5: Execute Commands Inside the Sandbox

Run commands inside your guest with dynocap exec:

Shell
dynocap exec my-first-box -- uname -a

Output:

Text
Linux dynocap 6.18.62-0-virt #1-Alpine SMP PREEMPT_DYNAMIC aarch64 Linux

Test running an isolated shell command:

Shell
dynocap exec my-first-box -- sh -c "echo 'Hello from DynoCap' && id"

Output:

Text
Hello from DynoCap
uid=0(root) gid=0(root) groups=0(root)

DynoCap streams stdout and stderr separately, and exits with the exact status code returned by the guest command.


Step 6: Destroy the Sandbox

When your work is done, remove the sandbox:

Shell
dynocap rm my-first-box --force

Output:

Text
removed my-first-box

Because my-first-box was actively running, --force explicitly confirms discarding running processes. The daemon terminates the virtual machine and cleans up runtime descriptors.


Next Steps

Now that the CLI is installed and a raw sandbox runs, proceed to:

This page is also plain Markdown, for agents and for you.