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>
8.4 KiB
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:
- App loads with "Rongorongo · Decipherment Engine" title
- Sidebar navigation works (Image Corpus, Glyph Catalog, etc.)
- Enter an Anthropic API key in the sidebar footer input
- Upload a test image to the corpus
- Navigate to Pattern Analyzer and run an analysis
- 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:
- Navigate to https://portainer.hobbs.farm (or your Portainer URL)
- Select the Swarm endpoint
- Go to Stacks → Add Stack
- Name:
rongorongo - Paste the contents of stack.yml into the web editor
- Set
registry.hobbs.farm/rongorongo:latestas the image (you still need to build and push first) - 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: trueheader which is required for direct browser API access