Luis-Ruiz

Orin Nano is officially a Razzy worker (v1 connection update)

5/1/2026, 2:04:58 AM

orin-nanorazzytailscalehomelabworker-architecturebuild-in-publicjetson

Razzy (Pi 5) is the parent brain; Orin Nano is a locked-down GPU worker over Tailscale with token auth and safe job endpoints. I got the foundation working, fixed a real systemd/Tailscale startup race, and I’m intentionally not enabling shell execution until file ops + policy + logs are in place.


Quick update

I finally got my Orin Nano out of “random dev box” territory and into something I actually trust as a worker.

The rule is simple: Razzy (Raspberry Pi 5) stays the parent controller. Orin is the worker appliance.

The architecture (simple on purpose)

The mental model I’m enforcing:

  • Razzy owns orchestration + decisions
  • Orin executes approved jobs (GPU-heavy / worker-y tasks)
  • Razzy stores and uses the results

I’m doing it this way because I don’t want two independent agents drifting into two separate brains with two separate memories.

What’s working right now

Right now the Orin worker is reachable only inside my tailnet and it’s intentionally limited:

  • Health checks + capabilities
  • GPU probe
  • Create/list/get jobs
  • Create/list workspaces
  • Append-only job ledger (JSONL for now)

Security-wise, it’s behind:

  • Tailscale private network
  • Bearer token auth for all /v1/* routes
  • Binding only to the Orin’s Tailscale IP (not 0.0.0.0)

The small ops win that made this feel real

I hit a classic startup race:

EADDRNOTAVAIL: address not available 100.86.175.53:8787

Basically, systemd was starting the service before Tailscale had actually brought up the interface/IP.

The fix was an ExecStartPre wait script that blocks until the bind IP exists. Small change, big difference — the worker now restarts cleanly instead of randomly failing at boot.

What I’m not doing yet (on purpose)

No shell execution. No package installs. No “run arbitrary code.”

Not because it’s impossible — because it’s irresponsible until the worker has the boring safeguards:

  • safe workspace file operations
  • explicit allowlists
  • per-job logs
  • timeouts + stdout/stderr capture
  • output size limits

What’s next

Next up is adding safe workspace file operations so Razzy can inspect and manipulate workspace state without jumping straight to command execution:

  • get_workspace
  • delete_workspace
  • list_workspace_files
  • read_workspace_file
  • write_workspace_file

Once file ops + policy + logging are solid, then I’ll consider controlled command execution with strict allowlists.

TL;DR

Razzy can now call the Orin Nano as a private, authenticated worker over Tailscale. It’s limited on purpose, and that constraint is what makes the whole setup sane.

👍 0 | 👎 0

Comments

  • No comments yet.