This guide is a practical runbook for deploying NodeTool end-to-end with the unified server entrypoint (nodetool serve).
It covers two production scenarios:
- Local / desktop runtime (no remote auth)
- Supabase-backed server (multi-user auth)
What Runs in Production
The server entrypoint is:
nodetool serve --host 0.0.0.0 --port 7777
nodetool serve accepts only --host and --port. Use environment variables to control auth and runtime behavior.
Important runtime behavior:
- Auth is enabled automatically when both
SUPABASE_URLandSUPABASE_KEYare set; otherwise the server uses a local auth provider. There is noAUTH_PROVIDERswitch read byserve. - Production mode is selected by
NODETOOL_ENV=production(the container also setsNODE_ENV=production). In production,SECRETS_MASTER_KEYis required. /healthand/readyrequire no authentication.
Prerequisites
- NodeTool CLI installed (
@nodetool-ai/cli). - Container runtime:
- Docker or
- Podman
- Image build for local deployment tests:
docker build -t nodetool:local .
If you use Podman:
podman build -t nodetool:local .
1) Local / Desktop Runtime (no remote auth)
Use this for local runtime where the app talks to a local API server. With no
SUPABASE_* vars set, the server uses the local auth provider.
export DB_PATH=/path/to/workspace/nodetool.db
export HF_HOME=/path/to/hf-cache
nodetool serve --host 127.0.0.1 --port 7777
Verify:
curl -s http://127.0.0.1:7777/health
curl -s http://127.0.0.1:7777/ready
2) Supabase-Backed Server
Use this for internet-facing deployments where user auth is Supabase-backed.
Setting both SUPABASE_URL and SUPABASE_KEY enables and enforces Supabase auth.
export NODETOOL_ENV=production
export SUPABASE_URL=https://<project>.supabase.co
export SUPABASE_KEY=<service-role-or-server-key>
export SECRETS_MASTER_KEY=<strong-random-secret>
export DB_PATH=/workspace/nodetool.db
export HF_HOME=/hf-cache
nodetool serve --host 0.0.0.0 --port 7777
Verify:
curl -i http://<host>:7777/health
curl -i http://<host>:7777/api/workflows
Expected:
/healthreturns200(no auth required)./api/workflowswithout auth returns401/403.
Containerized End-to-End Run
Docker
docker run --rm -p 7777:7777 \
-e NODETOOL_ENV=production \
-e SECRETS_MASTER_KEY=<secret> \
-e DB_PATH=/workspace/nodetool.db \
-e HF_HOME=/hf-cache \
-v $(pwd)/workspace:/workspace \
-v $(pwd)/hf-cache:/hf-cache \
nodetool:local
To enable Supabase auth, add -e SUPABASE_URL=… -e SUPABASE_KEY=….
Podman
podman run --rm -p 7777:7777 \
-e NODETOOL_ENV=production \
-e SECRETS_MASTER_KEY=<secret> \
-e DB_PATH=/workspace/nodetool.db \
-e HF_HOME=/hf-cache \
-v $(pwd)/workspace:/workspace \
-v $(pwd)/hf-cache:/hf-cache \
nodetool:local
Workflow Sync to a Deployed Server
Create deployment config (~/.config/nodetool/deployment.yaml) with the target host and auth token, then sync:
nodetool deploy workflows sync <deployment-name> <workflow-id>
List remote workflows:
nodetool deploy workflows list <deployment-name>
Run synced workflow via REST:
curl -s -X POST http://<host>:7777/api/workflows/<workflow-id>/run \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{}'
Production Checklist
NODETOOL_ENV=productionSECRETS_MASTER_KEYset- Supabase auth (
SUPABASE_URL+SUPABASE_KEY) configured if you need remote auth /healthand/readyare green- Unauthorized access to protected endpoints returns
401/403 - Workflow sync and workflow run both succeed
Troubleshooting
Server exits on startup in production
Check SECRETS_MASTER_KEY:
openssl rand -base64 32
E2E tests skip with “image not found”
Validate image in active runtime context:
docker image ls | grep nodetool
podman image ls | grep nodetool
Then rebuild/tag in that same runtime context.