Files
hobbs-iac/Rongorongo/RONGORONGO_DEPLOY.md
T
jeremy 27f6d95bf6 chore: sync accumulated infra changes and docs
Removals: openwebui and netclaw compose + Traefik routes (both decommissioned).
Updates: litellm, n8n, vaultwarden, ai-agents, media, traefik routes, CLAUDE.md
(nodes/ports/known-issues), agent definitions.
Additions: Rongorongo tree, LinkedStorm plan, rename-bart spec, vllm brief,
tls-options and security-headers Traefik config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 11:19:21 -05:00

8.4 KiB
Raw Blame History

RONGORONGO_DEPLOY.md

Rongorongo Decipherment Engine — Claude Code Deployment Guide

Target: hobbs.farm Docker Swarm infrastructure

Subdomain: rongorongo.hobbs.farm


CONTEXT

This document instructs Claude Code to build, push, and deploy the Rongorongo Decipherment Engine as a containerized static web app to the hobbs.farm Swarm.

The app is a single-file HTML/JS application served by nginx. It calls the Anthropic API directly from the browser. No backend, no database. All session state is stored in browser localStorage.

Infrastructure assumptions (from existing hobbs.farm stack):

  • Docker Swarm: nodes hf-pdocker-01, hf-pdocker-02, bart
  • Traefik reverse proxy with wildcard *.hobbs.farm TLS via Cloudflare DNS
  • External overlay network: traefik-public
  • Registry: registry.hobbs.farm (if local) OR use Docker Hub as fallback
  • Portainer CE available for stack management
  • DNS: AdGuard Home with hairpin NAT for *.hobbs.farm

REPOSITORY STRUCTURE

After cloning or creating the project, verify this structure exists:

rongorongo/
├── Dockerfile
├── nginx.conf
├── stack.yml
├── frontend/
│   └── index.html
└── RONGORONGO_DEPLOY.md  (this file)

STEP 1 — VERIFY PREREQUISITES

Run these checks before proceeding. Stop and report any failures.

# Confirm Docker and Swarm context
docker info | grep -E "Swarm:|Manager:|Nodes:"

# Confirm traefik-public network exists
docker network ls | grep traefik-public

# Confirm Traefik is running
docker service ls | grep traefik

# Test registry connectivity (if using local registry)
curl -s https://registry.hobbs.farm/v2/_catalog || echo "Registry unreachable — will use build-and-load method"

# Confirm you are on a Swarm manager node
docker node ls

If registry.hobbs.farm is unreachable, use the ALTERNATIVE DEPLOYMENT method at the bottom of this document.


STEP 2 — BUILD THE IMAGE

cd rongorongo/

# Build image
docker build -t registry.hobbs.farm/rongorongo:latest .

# Verify image was created
docker images | grep rongorongo

Expected output: image tagged registry.hobbs.farm/rongorongo:latest, size should be ~25–40MB (nginx:alpine base + small HTML file).


STEP 3 — PUSH TO REGISTRY

# If registry requires auth:
docker login registry.hobbs.farm

# Push
docker push registry.hobbs.farm/rongorongo:latest

If the push fails due to registry issues, fall through to ALTERNATIVE DEPLOYMENT.


STEP 4 — DEPLOY STACK

# Deploy or update the stack
docker stack deploy -c stack.yml rongorongo --with-registry-auth

# Watch rollout
docker service ps rongorongo_rongorongo --no-trunc

Wait for the service to show Running status. This typically takes 15–30 seconds.

# Confirm healthy
docker service ls | grep rongorongo
curl -s http://localhost/health  # or via container exec

STEP 5 — DNS VERIFICATION

The stack.yml assumes rongorongo.hobbs.farm resolves to the Traefik entrypoint.

# Check AdGuard Home has the record (or wildcard covers it)
nslookup rongorongo.hobbs.farm

# Test internal access
curl -sk https://rongorongo.hobbs.farm/health

If using AdGuard Home for internal DNS and the wildcard *.hobbs.farm is already configured for hairpin NAT, no additional DNS entry is needed.


STEP 6 — SMOKE TEST

Open https://rongorongo.hobbs.farm in a browser and verify:

  1. App loads with "Rongorongo · Decipherment Engine" title
  2. Sidebar navigation works (Image Corpus, Glyph Catalog, etc.)
  3. Enter an Anthropic API key in the sidebar footer input
  4. Upload a test image to the corpus
  5. Navigate to Pattern Analyzer and run an analysis
  6. Confirm AI response appears in the result box

UPDATING THE APP

When index.html is modified:

cd rongorongo/

# Rebuild
docker build -t registry.hobbs.farm/rongorongo:latest .

# Push
docker push registry.hobbs.farm/rongorongo:latest

# Force service update (pull new image)
docker service update --image registry.hobbs.farm/rongorongo:latest --force rongorongo_rongorongo

# Watch update
docker service ps rongorongo_rongorongo

ROLLBACK

If something breaks after an update:

docker service rollback rongorongo_rongorongo
docker service ps rongorongo_rongorongo

TEARDOWN

To remove the service without destroying data (there is no persistent volume):

docker stack rm rongorongo

ALTERNATIVE DEPLOYMENT (no registry)

Use this if registry.hobbs.farm is unavailable. This method builds the image directly on the Swarm manager and uses docker service create instead of stack deploy.

# On the Swarm manager node:
cd rongorongo/

# Build locally
docker build -t rongorongo:latest .

# Create service manually (adjust Traefik labels as needed)
docker service create \
  --name rongorongo_rongorongo \
  --network traefik-public \
  --label "traefik.enable=true" \
  --label "traefik.docker.network=traefik-public" \
  --label "traefik.http.routers.rongorongo.rule=Host(\`rongorongo.hobbs.farm\`)" \
  --label "traefik.http.routers.rongorongo.entrypoints=websecure" \
  --label "traefik.http.routers.rongorongo.tls=true" \
  --label "traefik.http.routers.rongorongo.tls.certresolver=cloudflare" \
  --label "traefik.http.services.rongorongo.loadbalancer.server.port=80" \
  --replicas 1 \
  --restart-condition on-failure \
  rongorongo:latest

# Monitor
docker service ps rongorongo_rongorongo

NOTE: With this method, to update you must rebuild locally and run:

docker service update --image rongorongo:latest --force rongorongo_rongorongo

This only works if your current node is the one running the replica. If you have a multi-node swarm, you should set up the registry to avoid placement issues.


PORTAINER DEPLOYMENT (optional GUI method)

If you prefer Portainer CE:

  1. Navigate to https://portainer.hobbs.farm (or your Portainer URL)
  2. Select the Swarm endpoint
  3. Go to Stacks → Add Stack
  4. Name: rongorongo
  5. Paste the contents of stack.yml into the web editor
  6. Set registry.hobbs.farm/rongorongo:latest as the image (you still need to build and push first)
  7. Click Deploy the stack

ENVIRONMENT NOTES

The app does NOT use environment variables or Docker secrets. The Anthropic API key is entered by the user at runtime and stored in their browser's localStorage. This is intentional — the app is designed to be used by a single user (Jeremy) and no server-side key storage is needed or appropriate.

If you want to pre-populate the API key for convenience (only if the deployment is strictly private/internal), you can inject it at build time by modifying frontend/index.html before building:

Find this line:

function getApiKey() {
  return document.getElementById('apiKeyInput').value.trim()

And prepend a hardcoded fallback (NOT recommended for any externally accessible URL).


TRAEFIK ENTRYPOINT NAMES

The stack.yml assumes:

  • HTTP entrypoint name: web
  • HTTPS entrypoint name: websecure
  • Cert resolver name: cloudflare

These match the standard hobbs.farm Traefik configuration. If your Traefik uses different names, edit the labels in stack.yml before deploying.


TROUBLESHOOTING

Service won't start:

docker service ps rongorongo_rongorongo --no-trunc
docker inspect $(docker ps -q --filter name=rongorongo) 2>/dev/null | grep -A5 '"State"'

Traefik not routing:

# Check Traefik logs for rongorongo
docker service logs traefik_traefik 2>&1 | grep -i rongorongo | tail -20
# Confirm labels are applied
docker service inspect rongorongo_rongorongo | grep -A2 Labels

TLS cert not issuing:

# Wildcard cert should already cover rongorongo.hobbs.farm
# If not, check Cloudflare DNS API token has Zone:Read and DNS:Edit
docker service logs traefik_traefik 2>&1 | grep -i "acme\|certificate\|cloudflare" | tail -20

API calls blocked (CORS/CSP): The nginx.conf includes a Content-Security-Policy header that allows connect-src https://api.anthropic.com. If you see CORS errors in the browser console, verify the CSP header is present:

curl -I https://rongorongo.hobbs.farm/ | grep -i content-security

App loads but AI calls fail:

  • Check API key is entered correctly in the sidebar
  • Anthropic API key must start with sk-ant-
  • Confirm outbound HTTPS to api.anthropic.com is not blocked by firewall rules
  • The app sends anthropic-dangerous-direct-browser-access: true header which is required for direct browser API access

END OF DEPLOYMENT GUIDE