Status: unsupported experimental. These surfaces are source-available but outside the supported v3 product contract. They are hidden from default
hack --help(seehack help --all) and print a warning when invoked.
This is a beta workflow.
Start with Core docs if you are new to hack, and use Beta workflows
for the rest of the remote path.
Use the published node-runtime container to spin up a remote node with minimal host setup.
Beta: multi-node execution is still being validated and is not part of the core local-dev path.
Recommended public image:
hackdance/hack:latest
Companion portable base image for managed containers:
hackdance/hack:slim
The container bundles:
hackCLI binarydockerCLI +docker composeplugin- bootstrap entrypoint that can initialize a project, enable gateway, and emit an enrollment bundle
The slim image keeps only the portable baseline (hack, Bun, Git/SSH/curl, and slim-mode defaults)
for Codex, CI, and other managed container workflows. It is not a remote-node replacement.
- Start the runtime container on the remote host:
docker run -d \
--name hack-node \
--restart unless-stopped \
-p 7788:7788 \
-v hack-node-home:/var/lib/hack \
-v /var/run/docker.sock:/var/run/docker.sock \
-e HACK_NODE_NAME="aws-node-1" \
-e HACK_NODE_ENDPOINT="https://node.example.com" \
-e HACK_NODE_GIT_REPO="git@github.com:<org>/<repo>.git" \
-e HACK_NODE_LABELS="aws,ec2,linux" \
-e HACK_NODE_ENROLL_PATH="/var/lib/hack/enrollment/node.bundle.json" \
hackdance/hack:latest- Fetch enrollment bundle from the remote host:
ssh <remote-host> 'docker exec hack-node cat /var/lib/hack/enrollment/node.bundle.json' > node.bundle.json- Register node on controller:
hack node add --bundle node.bundle.json --default
hack node status --watchWhen HACK_NODE_GIT_REPO points to a private repo, credentials must be available inside the container.
Common approaches:
- SSH deploy key:
- mount key material into the container (
-v ~/.ssh:/root/.ssh:ro) and pre-populateknown_hosts.
- mount key material into the container (
- HTTPS token:
- provide a credential helper/config in the image or mount git credential files.
If credentials are missing, workspace bootstrap clone fails and dispatch cannot prepare branch workspaces.
Container entrypoint behavior (default):
- Creates node workspace directory.
- Optionally clones repo (
HACK_NODE_GIT_REPO). - Initializes project via
hack init --auto --no-discoverywhen.hack/is missing. - Enables project gateway and global gateway extension.
- Applies gateway bind/port/allowWrites config from env vars.
- Optionally writes enrollment bundle (
HACK_NODE_ENROLL_PATH). - Clears daemon pid/socket state in persisted home volumes.
- Starts
hack daemon start --foreground.
| Variable | Default | Purpose |
|---|---|---|
HACK_NODE_WORKDIR |
/workspace |
Base workspace root in container |
HACK_NODE_PROJECT_DIR |
/workspace/node-project |
Project directory used for node bootstrap |
HACK_NODE_PROJECT_NAME |
hack-node |
Project name passed to hack init |
HACK_NODE_AUTO_INIT |
1 |
Auto-run hack init when missing |
HACK_NODE_GIT_REPO |
- | Optional repo URL to clone into project dir |
HACK_NODE_GIT_BRANCH |
- | Optional clone branch |
HACK_NODE_GIT_DEPTH |
1 |
Clone depth |
HACK_NODE_GATEWAY_ENABLE |
1 |
Enable gateway config during bootstrap |
HACK_NODE_GATEWAY_BIND |
0.0.0.0 |
Gateway bind address |
HACK_NODE_GATEWAY_PORT |
${PORT} when present, else 7788 |
Gateway port override |
HACK_NODE_GATEWAY_ALLOW_WRITES |
1 |
Set controlPlane.gateway.allowWrites |
HACK_NODE_NAME |
host hostname | Name used for hack node init bundle |
HACK_NODE_ENDPOINT |
http://127.0.0.1:<port> |
Reachable endpoint included in bundle |
HACK_NODE_LABELS |
- | Comma-separated labels in bundle |
HACK_NODE_ENROLL_PATH |
- | Path to write enrollment bundle JSON |
HACK_NODE_ENROLL_FORCE |
0 |
Overwrite existing enrollment bundle |
HACK_DAEMON_DISABLE_DOCKER_EVENTS |
auto (1 when no /var/run/docker.sock) |
Disable Docker event stream loop on non-Docker hosts |
HACK_TAILSCALE_ENABLE |
0 |
Enable embedded Tailscale bootstrap in container |
TS_AUTHKEY |
- | Tailscale auth key used for non-interactive tailscale up |
HACK_TAILSCALE_HOSTNAME |
- | Optional tailnet hostname override |
HACK_TAILSCALE_ADVERTISE_TAGS |
- | Optional advertised tags (for example tag:hack-node) |
HACK_TAILSCALE_SSH |
0 |
Enable Tailscale SSH during bootstrap |
HACK_TAILSCALE_SERVE |
1 when enabled |
Publish gateway over tailnet using tailscale serve |
HACK_TAILSCALE_SERVE_TARGET |
127.0.0.1:<gateway-port> |
Serve target forwarded to tailnet |
HACK_TAILSCALE_SOCKET |
/tmp/tailscaled.sock |
Local tailscaled socket path |
HACK_TAILSCALE_STATE_DIR |
/var/lib/hack/tailscale |
Tailscale state directory |
- Branch-scoped dispatch expects a git workspace. For containerized nodes, set
HACK_NODE_GIT_REPO(recommended) or initialize git manually in the project dir. - Reusing
hack-node-homeacross container restarts is supported; startup clears stale daemon pid/socket files before launchinghackd.
Local image build:
bun run build:node-runtime-image --tag hack-node-runtime:devbuild:node-runtime-image compiles the hack binary inside a Linux Docker build stage, so the image is portable even when built from macOS hosts.
Publish multi-arch image:
bun run build:node-runtime-image \
--push \
--platform linux/amd64,linux/arm64 \
--tag hackdance/hack:latestBuild the slim managed-container image locally:
bun run build:slim-runtime-image --tag hack-slim-runtime:devPublish the slim image:
bun run build:slim-runtime-image \
--push \
--platform linux/amd64,linux/arm64 \
--tag hackdance/hack:slimGitHub Actions workflow:
.github/workflows/release-node-runtime-image.yml