Skip to content

feat(z890): NATS leaf node for multi-node Docker networking - #1034

Merged
POWERFULMOVES merged 2 commits into
mainfrom
feat/z890-nats-leaf
Mar 19, 2026
Merged

POWERFULMOVES merged 2 commits into
mainfrom
feat/z890-nats-leaf

Conversation

@POWERFULMOVES

@POWERFULMOVES POWERFULMOVES commented Mar 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add NATS leaf node (nats:2.11.8-alpine) to z890 Docker compose, bridging the Docker bridge network to the 5090 NATS hub via leafnodes protocol
  • Solves Docker Desktop WSL2 limitation where containers cannot route to LAN (192.168.1.x) or Tailscale (100.x) IPs
  • Add idempotent PowerShell host setup script (z890_host_setup.ps1) for netsh port proxy configuration with admin checks and -Verify/-Remove modes

Changes

File Description
pmoves/configs/nats-leaf-z890.conf NATS leaf config: JetStream, auth, upstream leafnode remote
pmoves/docker-compose.z890.yml nats-leaf service + mesh-agent depends_on + volume
pmoves/scripts/z890_host_setup.ps1 Idempotent host network setup (admin-checked)
pmoves/Makefile z890-host-setup/verify/remove targets + LOAD_ENV_Z890

Test plan

  • nats-leaf starts healthy (v2.11.8, JetStream enabled)
  • Leafnodes: 1 (connected to 5090 hub after host portproxy setup)
  • mesh-agent connects to nats-leaf (2 clients on local NATS)
  • make z890-host-verify shows port 7422 proxied
  • 5090 sees z890 mesh-agent announcements on NATS bus

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added Z890 host setup utilities with network configuration and verification capabilities
    • Integrated NATS Leaf node into the Z890 deployment stack
  • Chores

    • Updated Z890 deployment configuration with improved environment management and service orchestration

POWERFULMOVES and others added 2 commits March 19, 2026 17:14
NATS leaf node bridges Docker bridge network to the 5090 hub via the
leafnodes protocol. Solves Docker Desktop WSL2 limitation where
containers cannot route to LAN/Tailscale IPs.

- Add nats-leaf-z890.conf with JetStream, auth, upstream remote
- Add nats-leaf service to docker-compose.z890.yml (nats:2.11.8-alpine)
- Update mesh-agent with depends_on nats-leaf
- Add nats-leaf-data volume for JetStream persistence

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Idempotent PowerShell script configures netsh port proxies for NATS
leafnode upstream connection (Docker → host → 5090 LAN).

- Add z890_host_setup.ps1 with admin check, -Verify, -Remove modes
- Add Make targets: z890-host-setup, z890-host-verify, z890-host-remove
- Update LOAD_ENV_Z890 to source env.z890 for correct variable layering
- Update up-z890/down-z890/ps-z890/logs-z890 to use LOAD_ENV_Z890

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Docker Hardening Validation

Hardening Validation Report

Validated: Thu Mar 19 21:16:45 UTC 2026

Services Checked

PMOVES.AI Docker Hardening Validation

[INFO] Checking: pmoves/docker-compose.hardened.yml

[INFO] Validating: hi-rag-gateway-v2
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: extract-worker
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: langextract
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: presign
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: render-webhook
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: retrieval-eval
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: pdf-ingest
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: jellyfin-bridge
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: invidious-companion-proxy
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: ffmpeg-whisper
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: media-video
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: media-audio
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: hi-rag-gateway-v2-gpu
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: hi-rag-gateway-gpu
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: deepresearch
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: supaserch
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: publisher-discord
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: mesh-agent
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: nats-echo-req
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: nats-echo-res
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: publisher
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: analysis-echo
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: graph-linker
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: comfy-watcher
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: grayjay-plugin-host
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: agent-zero
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: archon
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: channel-monitor
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: pmoves-yt
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: notebook-sync
[PASS] Non-root user: 65532:65532
[PASS] Read-only filesystem
[PASS] All capabilities dropped
[PASS] No-new-privileges enabled
[WARN] No resource limits

[INFO] Validating: supabase_service_role_key
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

[INFO] Validating: supabase_jwt_secret
[WARN] No user directive
[WARN] No read_only directive
[WARN] No cap_drop: ["ALL"]
[WARN] No no-new-privileges
[WARN] No resource limits

======================================
Summary: 120 passed, 40 warnings, 0 errors

@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Adds Z890-specific infrastructure setup including new Makefile targets for host configuration, NATS leaf node service, Docker Compose updates with environment variable precedence, and a PowerShell script for Windows host-side port proxy configuration.

Changes

Cohort / File(s) Summary
Makefile Z890 Targets
pmoves/Makefile
Added LOAD_ENV_Z890 variable to load Z890-specific environment overrides after shared configuration. Added three new phony targets (z890-host-setup, z890-host-verify, z890-host-remove) invoking PowerShell host setup script. Updated existing targets (up-z890, down-z890, ps-z890, logs-z890) to use LOAD_ENV_Z890 and added --force-recreate flag to up-z890.
Z890 Configuration
pmoves/configs/nats-leaf-z890.conf
New NATS leaf node configuration defining z890-leaf server with JetStream enabled, persistent storage at /data/jetstream, client auth (username: nats, password: pmoves), and upstream connection to NATS hub at host.docker.internal:7422.
Docker Compose Z890 Stack
pmoves/docker-compose.z890.yml
Added nats-leaf service (NATS 2.11.8 Alpine) with persistent volume and health checks. Added nats-leaf-data volume. Updated pmoves-ollama and mesh-agent to include env.z890 in environment file list. Removed explicit NATS_URL and HIRAG_URL from mesh-agent and added service dependency on healthy nats-leaf startup.
Host Setup Script
pmoves/scripts/z890_host_setup.ps1
New PowerShell script for configuring Windows port proxy rules (0.0.0.0:7422 → upstream IP :7422). Supports three modes: default (add rule if missing), -Verify (check rule exists), -Remove (delete rule if present). Includes upstream connectivity testing, idempotent operations, and Administrator privilege enforcement.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A Z890 node takes shape with care,
NATS leaves whisper through network air,
Port proxies dance on Windows bright,
Environment variables stack just right,
Docker composes—all systems go!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes a summary of changes and a detailed changes table, but is missing required sections: Testing (with commands/output), Required Checks, and Review Coordination sections from the template. Add the Testing section with actual test commands and output, complete the Required Checks checklist, and include Review Coordination details as specified in the repository template.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: introducing a NATS leaf node for multi-node Docker networking in the Z890 setup, which is the primary objective of this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/z890-nats-leaf
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 24fed2ca2a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +35 to +36
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8222/varz || exit 1"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail fast when the leaf never reaches the 5090 hub

This health check only probes the local admin endpoint, so nats-leaf becomes healthy even when the upstream leafnode connection is still down (for example, the host portproxy was not created or 5090 is not listening on :7422). Because mesh-agent now depends on this health status, make up-z890 can start a fully green-looking stack that publishes mesh.node.announce.* into an isolated local broker and never forwards those announcements to 5090—the exact failure mode this change is meant to eliminate.

Useful? React with 👍 / 👎.

Comment on lines +21 to +24
Param(
[switch]$Remove,
[switch]$Verify,
[string]$UpstreamIP = "192.168.1.65"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the LAN-specific default from the host proxy helper

make z890-host-setup invokes this script with its defaults, which means the generated netsh interface portproxy always targets 192.168.1.65. On any installation where the 5090 hub uses a different LAN address or must be reached over Tailscale, the advertised setup path writes a proxy to the wrong host and the leaf can never connect upstream. Since the Make target does not pass an override, this breaks the out-of-the-box flow for every non-matching network.

Useful? React with 👍 / 👎.

@POWERFULMOVES
POWERFULMOVES merged commit 8f7ad8f into main Mar 19, 2026
17 of 19 checks passed
@POWERFULMOVES

Copy link
Copy Markdown
Owner Author

🌿 PR Trim — Thread Classification

# File Issue Classification Action
1 docker-compose.z890.yml:36 Health check only probes local admin, not upstream leaf connection 📋 Noted Needs NATS leafnode-aware healthcheck — tracked for infra sprint
2 z890_host_setup.ps1:24 Hardcoded 192.168.1.65 LAN address 📋 Noted Make target should accept param; tracked for infra sprint

Summary: Both threads are valid infrastructure improvements but require careful testing against the actual Z890 → 5090 network path. Tracked for the next infrastructure sprint rather than a quick follow-up commit.

@POWERFULMOVES

Copy link
Copy Markdown
Owner Author

✅ Follow-up Fixes Applied

All 3 noted infrastructure items addressed in commit bdcc18a4:

Item Fix File
B1: Leaf health check Parses /leafz for num_remotes — unhealthy when no upstream connection docker-compose.z890.yml
B2: Hardcoded LAN IP Auto-detection chain: param → env → Tailscale DNS → default with warning z890_host_setup.ps1
B3: Makefile params make z890-host-setup UPSTREAM_IP=<tailscale-hostname> now works Makefile

POWERFULMOVES added a commit that referenced this pull request Mar 20, 2026
Workstream B — Z890 infrastructure (PR #1034 follow-up):
- docker-compose.z890.yml: NATS leaf health check now verifies upstream
  leaf connection via /leafz num_remotes (not just local /varz)
- z890_host_setup.ps1: upstream IP auto-detection chain (explicit param
  → PMOVES_5090_IP env → Tailscale DNS → hardcoded default with warning)
- Makefile: z890-host-setup/verify/remove targets accept UPSTREAM_IP param

Workstream A — DoX submodule pointer updated to e03ad5d:
- TLS fail-closed, credential redaction, cert mount separation
- Healthcheck readiness gate, NATS monitoring localhost binding
- Shared nats_tls.py utility for consistent TLS across services

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@POWERFULMOVES
POWERFULMOVES deleted the feat/z890-nats-leaf branch March 21, 2026 03:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant