Test server (10.1.1.20) and pptx-remediate recovery
Server split
| Server | Role | Notes |
|---|---|---|
test (10.1.1.20) | Ephemeral test/staging β Supabase, LocalStack, MinIO, Caddy, deployed apps under test | 4 vCPU / 15 GB / 98 GB. Safe to reset any service. |
staging (10.1.1.17) | Shared observability + future production | 4 vCPU / 31 GB / 937 GB. Hosts pptx-remediate and the Loki/Grafana/Kuma stack. Donβt wipe. |
Naming is historical: .17 is called βstagingβ in DNS but is not the staging box anymore β .20 (alias test) is. The .17 box is shared infrastructure.
How I use the test server
Deploying an app for a test release
From the root of any app repo:
-
Add a
.staging-deploymanifest:APP_NAME=foo # becomes foo.test.lanAPP_PORT=3000 # the port your container listens onDOCKERFILE=Dockerfile # defaultENV_FILE=.env.staging # optional -
Add
"stage": "deploy-to-staging"topackage.json. -
Run
npm run stage. The CLI (installed at/usr/local/bin/deploy-to-stagingfrom~/Projects/staging-server-setup) builds the image locally, streams it totestover SSH, writes a Caddy route, and brings the container up. The app is live athttps://foo.test.lan.
The CLI defaults to SSH alias test and domain test.lan. Override with --host, --domain, or env vars STAGING_SSH / STAGING_DOMAIN.
Accessing services
All TLS-trusted via the mkcert CA (already in the Mac System keychain):
https://studio.test.lanβ Supabase Studiohttps://supabase.test.lanβ Supabase REST / Auth / Konghttps://localstack.test.lanβ LocalStack edge (AWS API emulation)https://minio.test.lanβ MinIO S3 APIhttps://minio-console.test.lanβ MinIO web UIhttps://grafana.test.lanβ Grafana (runs on.17, proxied through.20βs Caddy). Login:admin/adminβ change it.https://kuma.test.lanβ Uptime Kuma (runs on.17, proxied through.20βs Caddy)
SSH: ssh test (passwordless, uses ~/.ssh/id_ed25519).
Resetting a service on the test box
# Reset LocalStack to pristine statessh test 'cd /srv/staging/localstack && docker compose down && sudo rm -rf data/* && docker compose up -d'
# Reset Supabase (wipes the DB)ssh test 'cd /srv/staging/supabase && docker compose down -v && docker compose up -d'
# Restart MinIOssh test 'cd /srv/staging/minio && docker compose restart'
# Restart the test app (replace foo)ssh test 'cd /srv/staging/apps/foo && docker compose restart'Log flow
Promtail on .20 ships container logs to Loki on http://10.1.1.17:3100. View them at https://grafana.test.lan β Explore β Loki β {container=~".+"}. Logs from .17βs own containers (including pptx-remediate) are also in the same Loki instance β one dashboard, all servers.
Bringing up a fresh test box
If .20 is rebuilt from scratch:
# On the Macrsync -az --delete ~/Projects/staging-server-setup/ test:~/staging-server-setup/
# On the serverssh testcd ~/staging-server-setup# Edit staging.env β set STAGING_DOMAIN=test.lan, confirm LAN_CIDR# Skip stage 07-backup.sh unless B2 creds are setsudo -E bash install.sh
# On the Mac, after install finishesscp test:/srv/staging/caddy/ca/rootCA.pem /tmp/test-rootCA.pemsudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/test-rootCA.pemecho "10.1.1.20 localstack.test.lan supabase.test.lan studio.test.lan grafana.test.lan kuma.test.lan minio.test.lan minio-console.test.lan apps.test.lan" | sudo tee -a /etc/hostsThen fix the two known install quirks:
- The Caddyfile is templated with
staging.lanhardcoded βsed -i 's/\.staging\.lan/.test.lan/g' /srv/staging/caddy/Caddyfile && docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile - Rewrite
/srv/staging/observability/docker-compose.ymlto drop the Loki/Grafana/Kuma/Redis services (they live on.17), leaving only the Promtail shipper. Update/srv/staging/observability/promtail-config.ymlto push tohttp://10.1.1.17:3100/loki/api/v1/push. Update/srv/staging/caddy/Caddyfilesografana.test.lanandkuma.test.lanreverse_proxy 10.1.1.17:3000and10.1.1.17:3001respectively.
pptx-remediate recovery (on .17)
Where it lives
- Source of truth:
services/pptx-remediate/in theaccessiblemonorepo (tracked in git). Not atapps/remediate/β that path is taken by a separate Next.js frontend (@accessible-pdf/remediate-app). - Deployed copy on
.17:~/services/pptx-remediate/β a detached snapshot, not a git checkout. Matches the monorepo contents. - Declarative compose (on
.17):~/services/pptx-remediate/docker-compose.yml - Image tarball backup (on
.17):~/services/pptx-remediate/pptx-remediate-image.tar.gz(~4 GB) - Port:
5003(bound to0.0.0.0on the host) - Restart policy:
unless-stopped - Consumers: API nodes on
10.1.1.4reach it viaPPTX_REMEDIATE_URL=http://10.1.1.17:5003
Health check
curl -sI http://10.1.1.17:5003/ | head -1 # expect 404 (app up, no / route)ssh 10.1.1.17 'docker ps --filter name=pptx-remediate --format "{{.Status}}"'Recovery scenarios
Container stopped / crashed:
ssh 10.1.1.17 'cd ~/services/pptx-remediate && docker compose up -d'Container + image deleted (image still in local Docker cache? no):
ssh 10.1.1.17 'cd ~/services/pptx-remediate && docker load < pptx-remediate-image.tar.gz && docker compose up -d'Everything deleted including the tarball:
# Rebuild from source β Dockerfile and Python code are still in ~/services/pptx-remediate/ssh 10.1.1.17 'cd ~/services/pptx-remediate && docker build -t pptx-remediate:latest . && docker compose up -d'# Then re-snapshot for future recovery:ssh 10.1.1.17 'docker save pptx-remediate:latest | gzip > ~/services/pptx-remediate/pptx-remediate-image.tar.gz'Entire .17 server rebuilt from scratch:
- Clone the monorepo (or rsync from a Mac checkout) and copy the service tree to the new host:
Then add a
Terminal window rsync -az ~/Projects/accessible/services/pptx-remediate/ 10.1.1.17:~/services/pptx-remediate/docker-compose.ymlnext to it (see contents inreference_server_layout.mdmemory, or just copy the existing one from the Mac). ssh 10.1.1.17 'cd ~/services/pptx-remediate && docker build -t pptx-remediate:latest . && docker compose up -d'- If the service uses API keys (Gemini / Anthropic / Deepgram / HuggingFace), populate
~/services/pptx-remediate/.env. The.envfile seeded during this migration is empty β match whatever values were live before, from password manager or prior.envbackup.
API keys note
docker inspect pptx-remediate shows GEMINI_API_KEY=, ANTHROPIC_API_KEY=, DEEPGRAM_API_KEY=, HF_TOKEN= with empty values in the running container as of 2026-04-23. Either the service doesnβt use them, or they were supposed to be set and never were. If features start failing, populate ~/services/pptx-remediate/.env with real values and docker compose up -d to pick them up.
Before pptx-remediate goes to production
- Wire up proper deploy from the monorepo: add a
.staging-deploymanifest inservices/pptx-remediate/. Since this is a Python service with nopackage.json, invoke the deploy CLI directly:cd services/pptx-remediate && deploy-to-staging. That rebuilds the image from the Dockerfile and redeploys to.17(adjust--hostif production needs a different target), replacing the current detached-snapshot workflow. - Add the service to the nightly backup on
.3(see~/.claude/scripts/server-backup.shon10.1.1.3). - Add a Caddy route (
pptx.anglinai.internalor similar) with TLS rather than exposing:5003directly. - Add an Uptime Kuma monitor hitting a real health endpoint (not
/). - Point real API keys in via
.env.