Files
hobbs-iac/Rongorongo/RONGORONGO_DEPLOY.md
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

323 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```bash
# 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
```bash
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
```bash
# 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
```bash
# 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.
```bash
# 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.
```bash
# 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:
```bash
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:
```bash
docker service rollback rongorongo_rongorongo
docker service ps rongorongo_rongorongo
```
---
## TEARDOWN
To remove the service without destroying data (there is no persistent volume):
```bash
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`.
```bash
# 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:
```bash
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:
```javascript
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:**
```bash
docker service ps rongorongo_rongorongo --no-trunc
docker inspect $(docker ps -q --filter name=rongorongo) 2>/dev/null | grep -A5 '"State"'
```
**Traefik not routing:**
```bash
# 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:**
```bash
# 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:
```bash
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