38 KiB
🏢 IT Pro Partner — Full Infrastructure Recovery Manual
Author: Sho'Nuff | Audience: Germaine
Last updated: July 9, 2026
Purpose: Recover ANY server, service, Docker container, or piece of ITPP infrastructure without Sho'Nuff.
Supersedes: shark-game-recovery-manual.md — this manual covers everything, including the shark game.
Table of Contents
- Architecture Overview
- Core Server (netcup — 152.53.192.33)
- Hermes Agent (AI Assistant)
- app1-bu Standby (Hetzner — 5.161.114.8)
- Docker Services on Core
- AI Services (ai.itpropartner.com — 178.156.167.181)
- All Other Hetzner Servers
- S3 Backups (Wasabi)
- Routers and Networking
- Shared Credentials
- Quick Reference — Common Commands
- Disaster Scenarios
- Cron Jobs — Complete List
1. Architecture Overview
All Servers at a Glance
| # | Server | IP | Provider | Specs | OS | What It Runs |
|---|---|---|---|---|---|---|
| 1 | Core (Primary) | 152.53.192.33 | netcup RS 2000 | 8C/15G/512G | Debian 13 | Hermes, Caddy, Docker (Twenty, Vaultwarden, Docuseal, SearXNG), Shark Game, Ollama, VPN |
| 2 | app1-bu (Standby) | 5.161.114.8 | Hetzner CPX11 | 2C/2G/40G | Ubuntu 26.04 | Hermes standby, StrongSwan, L2TP |
| 3 | ai.itpropartner.com | 178.156.167.181 | Hetzner CPX41 | 8C/16G/240G | Ubuntu 24.04 | LiteLLM, Open WebUI, Ollama, Qdrant |
| 4 | hudu.itpropartner.com | 178.156.130.130 | Hetzner CPX21 | 3C/4G/80G | Ubuntu 24.04 | Hudu Docs, SWAG, MariaDB |
| 5 | unifi | 178.156.131.57 | Hetzner CPX21 | 3C/4G/80G | Ubuntu 24.04 | UniFi Controller, MongoDB, MariaDB |
| 6 | unms.forefrontwireless.com | 5.161.225.131 | Hetzner CPX21 | 3C/4G/80G | Ubuntu 24.04 | UNMS/UISP, UCRM, PostgreSQL, RabbitMQ |
| 7 | wphost02 | 5.161.62.38 | Hetzner CPX21 | 3C/4G/80G | Ubuntu 24.04 | RunCloud, WordPress (Apex), MariaDB |
| 8 | app1.itpropartner.com | 87.99.144.163 | Hetzner CPX11 | 2C/2G/40G | Ubuntu 24.04 | n8n, PostgreSQL, Nginx |
| 9 | docker | 178.156.168.35 | Hetzner CPX11 | 2C/2G/40G | Ubuntu 24.04 | NPM, RustDesk, Uptime-Kuma, StrongSwan |
| 10 | fleettracker360 | 178.156.149.32 | Hetzner CPX11 | 2C/2G/40G | Ubuntu 24.04 | Traccar, RunCloud, MariaDB |
Domain Map
| Domain | Server | Service |
|---|---|---|
| crm.debtrecoveryexperts.com | Core (152.53.192.33) | Twenty CRM (port 3001) |
| sign.itpropartner.com | Core (152.53.192.33) | DocuSeal (port 3000) |
| app.itpropartner.com | Core (152.53.192.33) | Hermes Assistant PWA (port 8082) |
| core.itpropartner.com | Core (152.53.192.33) | API, static files, health checks |
| portal.debtrecoveryexperts.com | Core (152.53.192.33) | DRE Portal (static) |
| shark.iamgmb.com | Core (152.53.192.33) | Shark Game (port 8083) |
| shark.itpropartner.com | Core (152.53.192.33) | Shark Game (static) |
| ops.itpropartner.com | Core (152.53.192.33) | Ops Portal (static) |
| admin-ai.itpropartner.com | ai (178.156.167.181) | LiteLLM proxy |
| hudu.itpropartner.com | hudu (178.156.130.130) | Hudu documentation |
| unms.forefrontwireless.com | unms (5.161.225.131) | WISP management |
| app1.itpropartner.com | n8n (87.99.144.163) | n8n workflows |
2. Core Server (netcup — 152.53.192.33)
This is the most important server. It runs Hermes (your AI assistant), the web proxy (Caddy), Docker services, the shark game, and VPN services.
| Detail | Value |
|---|---|
| IP | 152.53.192.33 |
| Hostname | core (internal) |
| Provider | netcup RS 2000 G12 |
| SSH Key | itpp-infra (/root/.ssh/itpp-infra) |
| OS | Debian 13 (trixie) |
| Disk | 503 GB (6% used — plenty of room) |
SSH Access
ssh root@152.53.192.33 -i /root/.ssh/itpp-infra
Services Running on Core
| Service | Type | Port | Status Command |
|---|---|---|---|
| Hermes Agent | systemd | 8081 | systemctl status hermes |
| Hermes Browser (Chromium) | systemd | 9222 (localhost) | systemctl status hermes-browser |
| Caddy Web Server | systemd | 80/443 | systemctl status caddy |
| Ollama (LLM) | systemd | 11434 (localhost) | systemctl status ollama |
| Shark Game | systemd | 8083 | systemctl status shark-game |
| MySQL Tunnel | systemd | 33060 (localhost) | systemctl status mysql-tunnel |
| StrongSwan (IPsec VPN) | systemd | 500/4500 UDP | systemctl status strongswan-starter |
| xl2tpd (L2TP VPN) | systemd | 1701 UDP | systemctl status xl2tpd |
| Tailscale | systemd | — | systemctl status tailscaled |
| Twenty CRM | Docker | 3001 | docker ps | grep twenty |
| Vaultwarden | Docker | 8080 | docker ps | grep vaultwarden |
| DocuSeal | Docker | 3000 (localhost) | docker ps | grep docuseal |
| SearXNG | Docker | 8888 (localhost) | docker ps | grep searxng |
Recovery from Full System Failure
If the server is completely dead (won't boot, drive failed, etc.):
-
Order a new netcup RS 2000 from the Server Control Panel:
- https://www.servercontrolpanel.de/SCP/ (Customer #389212)
- Pick the same plan (RS 2000 G12) — Debian 13
-
Set up the basics (after new server is provisioned):
# Add SSH key mkdir -p /root/.ssh && chmod 700 /root/.ssh # Copy your itpp-infra key into /root/.ssh/itpp-infra # (from your own machine or from the standby) # Install essentials apt update && apt install -y curl wget git docker.io docker-compose-v2 -
Restore Hermes (see Section 3)
-
Restore Docker services — each one is documented below in Section 5.
-
Restart Caddy:
source /opt/awscli-venv/bin/activate aws s3 cp s3://itpropartner-system-configs/caddy/Caddyfile /etc/caddy/Caddyfile \ --endpoint-url https://s3.us-east-1.wasabisys.com systemctl restart caddy
Checking System Health
# Disk space
df -h
# Memory
free -h
# Running Docker containers
docker ps
# All systemd services
systemctl list-unit-files --type=service | grep enabled
# Recent system logs
journalctl -xe -n 50
3. Hermes Agent (AI Assistant)
Hermes is the AI assistant running on the Core server. It powers Telegram chat, web search, email, and infrastructure management.
How to Check If Hermes Is Running
systemctl status hermes
Look for: Active: active (running)
How to Restart Hermes
systemctl restart hermes
Then verify: systemctl status hermes
How to View Hermes Logs
# Last 100 lines
journalctl -u hermes -n 100
# Live tail
journalctl -u hermes -n 50 -f
# Today's logs only
journalctl -u hermes --since today
Where Hermes Lives
| Item | Path |
|---|---|
| Config | /root/.hermes/config.yaml |
| Environment/Secrets | /root/.hermes/.env |
| State DB (conversations) | /root/.hermes/state.db |
| Skills | /root/.hermes/skills/ |
| Scripts | /root/.hermes/scripts/ |
| Cron jobs | /root/.hermes/cron/jobs.json |
| Systemd service | /etc/systemd/system/hermes.service |
Hermes Browser (Headless Chromium)
The browser service runs alongside Hermes for web automation:
systemctl status hermes-browser
systemctl restart hermes-browser
It runs Chrome on port 9222 (localhost only).
Restoring Hermes from S3 Backup
Step 1: Stop Hermes (if running)
systemctl stop hermes
Step 2: Restore the state database
source /opt/awscli-venv/bin/activate
aws s3 cp s3://hermes-vps-backups/live/state.db /root/.hermes/data/state.db \
--endpoint-url https://s3.us-east-1.wasabisys.com
Step 3: Restore the full config
aws s3 sync s3://hermes-vps-backups/live/ /root/.hermes/ \
--endpoint-url https://s3.us-east-1.wasabisys.com \
--exclude "audio_cache/*" \
--exclude "image_cache/*" \
--exclude "cache/*" \
--exclude "sandboxes/*"
Step 4: Start Hermes
systemctl start hermes
If Hermes won't start (broken binary or config):
-
Reinstall from the official script:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -
Then restore config from S3 (Step 3 above).
-
Restart:
systemctl restart hermes
4. app1-bu Standby (Hetzner — 5.161.114.8)
What it is: A warm standby server on Hetzner. If the Core server (netcup) dies, this server takes over as Hermes.
Server Details
| Detail | Value |
|---|---|
| IP | 5.161.114.8 |
| Hostname | app1-bu.itpropartner.com |
| Plan | CPX11 (2C/2G/40G) |
| OS | Ubuntu 26.04 |
| SSH Key | itpp-infra |
SSH Access
ssh root@5.161.114.8 -i /root/.ssh/itpp-infra
What Runs on Standby (Normally Dormant)
| Service | Status | Purpose |
|---|---|---|
| hermes-gateway | Disabled (dormant) | Hermes standby |
| hermes-standby | Disabled | Standby restore service |
| strongswan-starter | Active | IPsec VPN (always on) |
| xl2tpd | Active | L2TP tunnel (always on) |
| home-router-vpn | Active | Router VPN tunnel |
| home-router-keepalive | Active | Router watchdog |
How Failover Works (Automatic)
The watchdog script runs every 5 minutes via cron (*/5 * * * * /root/.hermes/scripts/hermes-standby-watchdog.sh):
- Checks if Core server (152.53.192.33) is reachable via ping
- If Core is alive: exits silently (nothing to do)
- If Core is unreachable for ~3.5 minutes: confirms via 4 consecutive ping failures
- Takes over: syncs latest Hermes state from S3, starts Hermes gateway
- Sends alerts via Telegram and email to g@germainebrown.com
How to Manually Promote Standby (Failover)
If you need to manually switch to standby:
ssh root@5.161.114.8 -i /root/.ssh/itpp-infra 'systemctl start hermes-gateway'
How to Demote (Switch Back to Core)
After Core is restored:
ssh root@5.161.114.8 -i /root/.ssh/itpp-infra 'systemctl stop hermes-gateway'
Then make sure Hermes is running on Core:
systemctl restart hermes
Standby Sync
The standby syncs state from S3 every 10 minutes (*/10 * * * * /root/.hermes/scripts/hermes-standby-sync.sh) so it's always ready to take over.
5. Docker Services on Core
All Docker services live under /root/docker/<service>/. Each has its own docker-compose.yml and .env file.
General Docker Commands (Work for Any Service)
# List running containers
docker ps
# Restart a specific service
cd /root/docker/<service> && docker compose --env-file .env down && docker compose --env-file .env up -d
# View logs for a service
docker logs <container-name> -n 50
# Check health
docker ps --filter name=<service> --format '{{.Names}} {{.Status}}'
5.1 Twenty CRM
Purpose: Customer Relationship Management for Debt Recovery Experts
URL: https://crm.debtrecoveryexperts.com
Port: 3001 (maps to container port 3000)
Containers (4 total)
| Container | Image | Purpose |
|---|---|---|
| twenty-server-1 | twentycrm/twenty:latest | NestJS API + frontend |
| twenty-worker-1 | twentycrm/twenty:latest | Background job processor |
| twenty-db-1 | postgres:16 | PostgreSQL database |
| twenty-redis-1 | redis | Queue + cache |
Compose Location
/root/docker/twenty/docker-compose.yml
/root/docker/twenty/.env
Data Locations
- PostgreSQL data: Docker volume (
twenty_pg_dataor similar) - File uploads: Docker volume (
twenty_server-local-dataor similar)
Backup
# Export PostgreSQL database
docker exec twenty-db-1 pg_dump -U postgres default > /root/twenty-backup-$(date +%Y%m%d).sql
Restore from Scratch
cd /root/docker/twenty
docker compose --env-file .env down -v # WARNING: -v removes volumes
docker compose --env-file .env up -d
# Then restore database:
cat /path/to/backup.sql | docker exec -i twenty-db-1 psql -U postgres default
Verify It's Working
curl -sI https://crm.debtrecoveryexperts.com/ | head -3
# Should return HTTP/2 200
5.2 Vaultwarden
Purpose: Password manager (compatible with Bitwarden apps)
URL: https://vaultwarden.tailc2f3b0.ts.net (Tailscale only -- not public internet)
Port: 8080 -> container port 80
Compose Location
/root/docker/vaultwarden/docker-compose.yml
/root/docker/vaultwarden/.env
Data Location
/root/docker/vaultwarden/data/ (bind mount)
Key Config
| Variable | Value |
|---|---|
| DOMAIN | https://vaultwarden.tailc2f3b0.ts.net |
| SIGNUPS_ALLOWED | false |
| INVITATIONS_ALLOWED | true |
| ADMIN_TOKEN | Stored in .env |
Restart
cd /root/docker/vaultwarden && docker compose --env-file .env down && docker compose --env-file .env up -d
Restore from S3
cd /root/docker/vaultwarden
source /opt/awscli-venv/bin/activate
aws s3 sync s3://hermes-vps-backups/live/docker/vaultwarden/ ./ \
--endpoint-url https://s3.us-east-1.wasabisys.com
docker compose --env-file .env up -d
Verify
curl -sI http://127.0.0.1:8080 | head -3
5.3 DocuSeal
Purpose: Document signing (contracts, forms)
URL: https://sign.itpropartner.com
Port: 127.0.0.1:3000 (localhost only -- proxied by Caddy)
Compose Location
/root/docker/docuseal/docker-compose.yml
Data Location
/root/docker/docuseal/data/ (bind mount -- SQLite database)
Restart
cd /root/docker/docuseal && docker compose down && docker compose up -d
Restore from S3
cd /root/docker/docuseal
source /opt/awscli-venv/bin/activate
aws s3 sync s3://hermes-vps-backups/live/docker/docuseal/ ./ \
--endpoint-url https://s3.us-east-1.wasabisys.com
docker compose up -d
Verify
curl -sI https://sign.itpropartner.com | head -3
5.4 SearXNG
Purpose: Private, self-hosted search engine (used by Hermes for web searches)
URL: http://127.0.0.1:8888 (localhost only)
Port: 127.0.0.1:8888
Compose Location
/root/docker/searxng/docker-compose.yml
Data Locations
/root/docker/searxng/searxng-data/-- settings and config/root/docker/searxng/searxng-themes/-- theme overrides
Restart
cd /root/docker/searxng && docker compose down && docker compose up -d
Quick Test
curl -s "http://127.0.0.1:8888/search?q=test&format=json" | head -5
6. AI Services (ai.itpropartner.com)
IMPORTANT: This server hosts admin-ai.itpropartner.com (LiteLLM) which powers Sho'Nuff's deepseek-chat model. If this goes down, Hermes loses its brain.
DISK WARNING: 92% used (199G of 226G) -- needs attention soon.
Server Details
| Detail | Value |
|---|---|
| IP | 178.156.167.181 |
| Hostname | ai |
| Provider | Hetzner CPX41 |
| SSH | ssh root@178.156.167.181 -i /root/.ssh/itpp-infra |
| OS | Ubuntu 24.04 |
| Status | Still on Hetzner (will migrate to netcup Monitor server) |
Docker Containers (6 total)
| Container | Image | Port | Purpose |
|---|---|---|---|
| litellm | ghcr.io/berriai/litellm:v1.84.0 | 4000 | LLM proxy (currently unhealthy but working) |
| litellm_postgres | postgres:16 | 5432 | LiteLLM database |
| openwebui | ghcr.io/open-webui/open-webui:0.9.6 | 8080 | Chat interface at admin-ai.itpropartner.com |
| ollama | ollama/ollama:latest | 11434 | Local LLM inference |
| qdrant | qdrant/qdrant:latest | 6333-6334 | Vector storage for RAG |
| caddy | caddy:latest | 80/443 | Reverse proxy |
Compose Location
/opt/ai/docker-compose.yml
Restart All AI Services
ssh root@178.156.167.181 -i /root/.ssh/itpp-infra
cd /opt/ai && docker compose down && docker compose up -d
Check Health
# LiteLLM health
curl -s https://admin-ai.itpropartner.com/health/liveliness
# Check all containers
docker ps
Restore Open WebUI Database
The WebUI SQLite DB is at /app/backend/data/webui.db inside the container. To restore:
# Find the Open WebUI volume
docker volume inspect ai_open-webui || docker volume ls | grep webui
# To restore from a backup file:
docker run --rm -v ai_open-webui:/data -v /path/to/backup:/backup alpine sh -c \
"cp /backup/webui.db /data/backend/data/webui.db"
Restore LiteLLM PostgreSQL
# Dump current DB
docker exec litellm_postgres pg_dump -U postgres litellm > /root/litellm-backup.sql
# Restore from backup
cat /root/litellm-backup.sql | docker exec -i litellm_postgres psql -U postgres litellm
Key User Accounts
- Open WebUI: admin@itpropartner.com (password in /root/.hermes/.env or ask Sho'Nuff)
- Root user: root via SSH key
7. All Other Hetzner Servers
7.1 Hudu
Purpose: IT documentation and knowledge base
URL: https://hudu.itpropartner.com
Server: 178.156.130.130 (CPX21)
ssh root@178.156.130.130 -i /root/.ssh/itpp-infra
Docker Containers (5)
| Container | Purpose | Port |
|---|---|---|
| hudu2-app-1 | Hudu application | 3000 |
| hudu2-worker-1 | Background worker | -- |
| hudu2-db-1 | PostgreSQL | 5432 |
| hudu2-redis-1 | Cache | 6379 |
| letsencrypt (swag) | Let's Encrypt + Nginx | 80/443 |
Restart Everything
cd /opt/hudu2 && docker compose down && docker compose up -d
Native Services (also running)
- MariaDB 11.4.12 (native, not Docker) -- port 3306
- Postfix mail server -- port 25
- RunCloud agent
7.2 UniFi
Purpose: Ubiquiti network controller -- manages all UniFi devices
URL: https://unifi.itpropartner.com:8443 (or direct IP)
Server: 178.156.131.57 (CPX21)
ssh root@178.156.131.57 -i /root/.ssh/itpp-infra
What Runs on It
| Service | Port | Purpose |
|---|---|---|
| unifi.service | 8080, 8443, 8843, 8880, etc. | UniFi Network Controller (Java) |
| mariadb.service | 3306 | MariaDB database |
| MongoDB | 27117 (localhost) | UniFi internal database |
Restart UniFi Controller
systemctl restart unifi
Check UniFi Status
systemctl status unifi
Data Locations
- UniFi data:
/usr/lib/unifi/data/ - UniFi backups (auto-generated):
/usr/lib/unifi/data/backup/
7.3 UNMS/UISP
Purpose: WISP management -- manages Ubiquiti wireless devices across the network
URL: https://unms.forefrontwireless.com
Server: 5.161.225.131 (CPX21)
ssh root@5.161.225.131 -i /root/.ssh/itpp-infra
Docker Containers (10)
UNMS is a complex stack. The key containers:
| Container | Image | Purpose |
|---|---|---|
| unms-nginx | ubnt/unms-nginx:3.0.140 | Frontend proxy |
| unms-api | ubnt/unms:3.0.140 | API server |
| unms-device-ws-1/2 | ubnt/unms:3.0.140 | Device WebSocket connections |
| unms-postgres | ubnt/unms-postgres:3.0.140 | PostgreSQL database |
| unms-siridb | ubnt/unms-siridb:3.0.140 | Time-series database |
| unms-rabbitmq | rabbitmq:3.7.28-alpine | Message queue |
| unms-fluentd | ubnt/unms-fluentd:3.0.140 | Log collector |
| unms-netflow | ubnt/unms-netflow:3.0.140 | Netflow collector |
| ucrm | ubnt/unms-crm:4.5.31 | Customer management (CRM) |
Restart UNMS
cd /opt/unms && docker compose down && docker compose up -d
Native Services
- MariaDB 11.4.12 (native, port 3306) -- separate from Docker PostgreSQL
- Postfix mail server
Backup
/root/.hermes/scripts/backup-uisp.sh
7.4 wphost02
Purpose: WordPress hosting (Apex Track Experience)
Server: 5.161.62.38 (CPX21)
ssh root@5.161.62.38 -i /root/.ssh/itpp-infra
What Runs on It
| Service | Purpose |
|---|---|
| nginx-rc (RunCloud) | Nginx reverse proxy on 80/443 |
| apache2-rc (RunCloud) | Apache backend on port 81 |
| php81rc-fpm | PHP 8.1 |
| mariadb.service | MariaDB on 3306 |
| postfix | Mail server |
Restart Web Server
systemctl restart nginx-rc
systemctl restart apache2-rc
systemctl restart php81rc-fpm
Restart All
runcloud restart
Data Locations
- WordPress files: managed by RunCloud (see
/home/runcloud/or RunCloud dashboard) - MySQL databases: RunCloud-managed
MySQL Tunnel (from Core)
The Core server connects to this MySQL via AutoSSH tunnel on port 33060 (localhost):
systemctl status mysql-tunnel
7.5 app1.itpropartner.com (n8n)
Purpose: Workflow automation (n8n)
URL: https://app1.itpropartner.com
Server: 87.99.144.163 (CPX11)
ssh root@87.99.144.163 -i /root/.ssh/itpp-infra
Docker Containers (2)
| Container | Purpose | Port |
|---|---|---|
| n8n | Workflow automation | 5678 (localhost) |
| n8n-postgres | PostgreSQL backend | 5432 |
Compose Location
/opt/n8n/docker-compose.yml
Restart n8n
cd /opt/n8n && docker compose down && docker compose up -d
Native Services
- Nginx -- reverse proxy on 80/443 -> 127.0.0.1:5678
- MariaDB -- port 3306
Verify
curl -sI https://app1.itpropartner.com | head -3
7.6 Docker Host (NPM/RustDesk)
Purpose: Nginx Proxy Manager, RustDesk remote desktop, Uptime-Kuma monitoring
Server: 178.156.168.35 (CPX11)
ssh root@178.156.168.35 -i /root/.ssh/itpp-infra
DISK WARNING: 73% used (26G of 38G) -- getting full.
Docker Containers (7+)
| Container | Purpose | Port |
|---|---|---|
| nginx-proxy-manager | Reverse proxy dashboard | 80, 81, 443 |
| uptime-kuma | Status monitoring | 3001 |
| hbbr | RustDesk relay server | 21117, 21119 |
| hbbs | RustDesk signal server | 21114, 21116, 21118 |
| strongswan | IPsec VPN | 500/4500 |
| runcloud_mariadb | RunCloud MariaDB | -- |
| runcloud_php* | RunCloud PHP-FPM | -- |
Restart Nginx Proxy Manager
docker restart nginx-proxy-manager
Restart Uptime-Kuma
docker restart uptime-kuma
Compose Files
Services are at /opt/<name>/docker-compose.yml (not in /root/docker/):
/opt/rustdesk/docker-compose.yml/opt/strongswan/docker-compose.yml/opt/litellm/docker-compose.yml(legacy -- this is now on the AI server)
7.7 fleettracker360 (Traccar)
Purpose: GPS fleet tracking
Server: 178.156.149.32 (CPX11)
ssh root@178.156.149.32 -i /root/.ssh/itpp-infra
What Runs on It
| Service | Port | Purpose |
|---|---|---|
| traccar.service | 5001-5032, 8082 | GPS tracking (Java) |
| nginx-rc (RunCloud) | 80/443 | Web frontend |
| apache2-rc (RunCloud) | 81 | Apache backend |
| mariadb.service | 3306 | MariaDB database |
Restart Traccar
systemctl restart traccar
Check Traccar Status
systemctl status traccar
journalctl -u traccar -n 50
Data Locations
- Traccar data:
/opt/traccar/data/or/opt/traccar/ - Traccar config:
/opt/traccar/conf/traccar.xml
8. S3 Backups (Wasabi)
All infrastructure backups go to Wasabi S3 (us-east-1).
Credentials
- Config file:
/root/.aws/credentials - CLI activation:
source /opt/awscli-venv/bin/activate - Endpoint:
https://s3.us-east-1.wasabisys.com
Buckets
| Bucket | Contents | Backup Frequency |
|---|---|---|
hermes-vps-backups |
Hermes state, config, Docker data, skills, scripts | Every 15 min (live sync), daily (full backup) |
mikrotik-ccr-backups |
Router (CCR) config exports | Daily via wisp-backup |
itpropartner-backups |
Home router config, legacy data | Daily |
Bucket Structure
hermes-vps-backups/
+-- live/ <- 15-min sync (most recent Hermes state)
| +-- state.db <- Conversation history (1.1 GB)
| +-- config.yaml <- Hermes config
| +-- .env <- All secrets/API keys
| +-- docker/ <- Docker service configs & data
| | +-- vaultwarden/
| | +-- docuseal/
| | +-- ...
| +-- skills/ <- All skills
| +-- scripts/ <- All scripts
| +-- cron/ <- Cron job definitions
| +-- ...
+-- live-sync/ <- Alternative sync target
+-- hermes-full-backup/ <- Daily tar.gz archives
| +-- hermes-full-backup-2026-07-05.tar.gz
| +-- hermes-full-backup-2026-07-04.tar.gz
+-- standby/ <- DR scripts and docs
+-- docker/ <- Docker volume backups (when configured)
mikrotik-ccr-backups/
+-- wisp-backups/ <- WISP router configs
itpropartner-backups/
+-- home-router/ <- Home gateway configs
+-- shonuff/ <- Sho'Nuff personal data
Checking Backups
source /opt/awscli-venv/bin/activate
# List Hermes backup folders
aws s3 ls s3://hermes-vps-backups/ --endpoint-url https://s3.us-east-1.wasabisys.com
# List recent Hermes state files
aws s3 ls s3://hermes-vps-backups/live/ --endpoint-url https://s3.us-east-1.wasabisys.com
# List router backups
aws s3 ls s3://mikrotik-ccr-backups/wisp-backups/ --endpoint-url https://s3.us-east-1.wasabisys.com
Sync Commands
# Full Hermes restore
aws s3 sync s3://hermes-vps-backups/live/ /root/.hermes/ \
--endpoint-url https://s3.us-east-1.wasabisys.com
# Restore just the state DB
aws s3 cp s3://hermes-vps-backups/live/state.db /root/.hermes/state.db \
--endpoint-url https://s3.us-east-1.wasabisys.com
Backup Scripts
These scripts run automatically on Core:
| Script | What It Backs Up | When |
|---|---|---|
hermes-live-sync.sh |
Full .hermes directory -> live/ |
Every 15 min |
hermes-backup.sh |
Daily tar.gz archive -> hermes-full-backup/ |
Daily |
hermes-docker-sync.sh |
Docker volumes | Config-based |
hermes-system-config-sync.sh |
Caddyfile and system configs | Config-based |
home-router-backup.sh |
Home gateway CCR config | Daily |
run-wisp-backup.sh |
WISP router configs | Daily |
9. Routers and Networking
Home Gateway (MikroTik CCR)
| Detail | Value |
|---|---|
| Model | MikroTik CCR (or similar) |
| IP | 10.77.0.2 (via WireGuard tunnel) |
| SSH Key | /root/.ssh/wisp_rsa |
| SSH User | admin@10.77.0.2 |
| Connection | WireGuard (preferred) or L2TP/IPsec |
Backup the Router
Manual backup:
cd /root/.hermes/scripts/wisp-backup && python3 wisp-backup.py
Wrapper script (for cron):
bash /root/.hermes/scripts/run-wisp-backup.sh
Output: Backup files go to S3 at s3://mikrotik-ccr-backups/wisp-backups/
Restore Router from Backup
-
SSH into the router:
ssh -i /root/.ssh/wisp_rsa admin@10.77.0.2 -
Download the latest backup from S3:
source /opt/awscli-venv/bin/activate aws s3 ls s3://mikrotik-ccr-backups/wisp-backups/ --endpoint-url https://s3.us-east-1.wasabisys.com aws s3 cp s3://mikrotik-ccr-backups/wisp-backups/<latest-file> /tmp/ \ --endpoint-url https://s3.us-east-1.wasabisys.com -
Upload to router via SCP:
scp -i /root/.ssh/wisp_rsa /tmp/<backup-file> admin@10.77.0.2:/ -
On the router, import the config:
/import file-name=<backup-file>
WireGuard vs L2TP/IPsec
- WireGuard is the preferred connection method -- faster, more reliable, simpler
- L2TP/IPsec (StrongSwan + xl2tpd) is the fallback -- runs on both Core and app1-bu
- If WireGuard goes down, the watchdog scripts automatically try the VPN tunnel
Home Router Watchdog
- Runs on Core via:
/usr/local/bin/home-router-watchdog.sh - Runs on app1-bu via:
/root/.hermes/scripts/wisp-backup/home-router-keepalive.sh - Checks connection to 10.77.0.2 periodically
- Restarts the VPN tunnel if the router is unreachable
10. Shared Credentials
IMPORTANT: These credentials are essential for recovery. Guard them carefully.
| What | Where | Purpose |
|---|---|---|
| All API keys & secrets | /root/.hermes/.env |
Telegram tokens, API keys, database passwords |
| Email password | /root/.config/himalaya/shonuff.pass |
g@germainebrown.com IMAP/SMTP |
| Router SSH key | /root/.ssh/wisp_rsa |
SSH to MikroTik CCR |
| Server SSH key | /root/.ssh/itpp-infra |
SSH to ALL servers |
| S3 access | /root/.aws/credentials |
Wasabi S3 access |
| Himalaya config | /root/.config/himalaya/config.toml |
Email client config |
| netcup admin | https://www.servercontrolpanel.de/SCP/ (Customer #389212) | Order/manage netcup servers |
What to Do If Credentials Are Lost
- S3 credentials -- stored in multiple places (S3 itself can be accessed via the web console at wasabi.com)
- SSH keys -- backed up in
/root/.hermes/which syncs to S3 - Email password -- stored in
/root/.config/himalaya/shonuff.passand in the.envfile - If everything is lost: contact Sho'Nuff for password resets
11. Quick Reference -- Common Commands
Service Management
| What | Command |
|---|---|
| Check Hermes | systemctl status hermes |
| Restart Hermes | systemctl restart hermes |
| Check Caddy | systemctl status caddy |
| Restart Caddy | systemctl reload caddy |
| Check shark game | systemctl status shark-game |
| Restart shark game | systemctl restart shark-game |
| Check all services | systemctl list-unit-files --type=service | grep enabled |
| Check Docker | docker ps |
| Restart all Docker | See each service in Section 5 |
Logs
| What | Command |
|---|---|
| Hermes logs | journalctl -u hermes -n 100 |
| Hermes live log | journalctl -u hermes -n 50 -f |
| Caddy logs | journalctl -u caddy -n 50 |
| Shark game logs | journalctl -u shark-game -n 100 |
| Any service logs | journalctl -u <service> -n 100 |
| Filter for errors | journalctl -u <service> -n 200 | grep -i "error\|traceback\|exception" |
Docker
| What | Command |
|---|---|
| List running containers | docker ps |
| List all containers | docker ps -a |
| View Docker logs | docker logs <container> -n 50 |
| Follow Docker logs | docker logs <container> -n 50 -f |
| Restart a Docker service | cd /root/docker/<name> && docker compose --env-file .env down && docker compose --env-file .env up -d |
System
| What | Command |
|---|---|
| Check disk space | df -h |
| Check memory | free -h |
| Check network ports | ss -tlnp |
| Check cron jobs | crontab -l |
S3 / Backups
| What | Command |
|---|---|
| Activate AWS CLI | source /opt/awscli-venv/bin/activate |
| List backup buckets | aws s3 ls s3://hermes-vps-backups/ --endpoint-url https://s3.us-east-1.wasabisys.com |
| Restore Hermes state | aws s3 cp s3://hermes-vps-backups/live/state.db /root/.hermes/state.db --endpoint-url https://s3.us-east-1.wasabisys.com |
| Backup router | bash /root/.hermes/scripts/run-wisp-backup.sh |
Other
| What | Command |
|---|---|
| SSH to any server | ssh root@<IP> -i /root/.ssh/itpp-infra |
| SSH to router | ssh -i /root/.ssh/wisp_rsa admin@10.77.0.2 |
| Check LiteLLM health | curl -s https://admin-ai.itpropartner.com/health/liveliness |
| Check site response | curl -I https://<domain> |
| netcup SCP (admin panel) | https://www.servercontrolpanel.de/SCP/ |
12. Disaster Scenarios
Scenario A: "Sho'Nuff Is Gone" -- Full Recovery
If Sho'Nuff disappears and you need to recover everything without them:
-
SSH into Core:
ssh root@152.53.192.33 -i /root/.ssh/itpp-infra -
Check what's running:
systemctl list-unit-files --type=service | grep enabled docker ps -
If Core is down, failover to standby (see Scenario B below)
-
Check S3 backups exist:
source /opt/awscli-venv/bin/activate aws s3 ls s3://hermes-vps-backups/ --endpoint-url https://s3.us-east-1.wasabisys.com -
Restore Hermes (if needed):
systemctl stop hermes aws s3 sync s3://hermes-vps-backups/live/ /root/.hermes/ \ --endpoint-url https://s3.us-east-1.wasabisys.com \ --exclude "audio_cache/*" --exclude "image_cache/*" systemctl start hermes -
Restart each Docker service (see Section 5)
-
Verify Caddy is proxying:
systemctl restart caddy curl -I https://core.itpropartner.com -
Back up the router if needed:
bash /root/.hermes/scripts/run-wisp-backup.sh
Scenario B: "Core Server Is Dead" -- Failover to Standby
If 152.53.192.33 is offline and won't come back:
-
Wait for automatic failover -- the watchdog on app1-bu will detect it and promote itself within ~5 minutes.
-
If automatic failover doesn't trigger, do it manually:
ssh root@5.161.114.8 -i /root/.ssh/itpp-infra 'systemctl start hermes-gateway' -
Verify Hermes is running on standby:
ssh root@5.161.114.8 -i /root/.ssh/itpp-infra 'systemctl status hermes-gateway' -
Order a new netcup server:
- Go to https://www.servercontrolpanel.de/SCP/ (Customer #389212)
- Order an RS 2000 G12 with Debian 13
-
When new server arrives, set it up (see Section 2 -- Recovery from Full System Failure)
-
Demote standby and restore Core as primary (see Section 4)
Scenario C: "Database Corruption"
If a database (SQLite or PostgreSQL) has corrupted data:
-
Identify which service is affected from error messages or logs
-
For SQLite-based services (DocuSeal, Hermes state.db):
# Stop the service systemctl stop hermes # or: docker compose down # Check integrity sqlite3 /path/to/database.db "PRAGMA integrity_check;" # Restore from S3 source /opt/awscli-venv/bin/activate aws s3 cp s3://hermes-vps-backups/live/state.db /path/to/database.db \ --endpoint-url https://s3.us-east-1.wasabisys.com # Restart systemctl start hermes -
For PostgreSQL-based services (Twenty CRM, n8n, LiteLLM):
# Find the database container docker ps | grep postgres # Restore from backup cat /path/to/backup.sql | docker exec -i <container> psql -U postgres <database>
Scenario D: "Accidental Deletion" -- Restore from S3 Versioning
Wasabi supports S3-compatible versioning. If a file was accidentally deleted:
source /opt/awscli-venv/bin/activate
# List versions of a deleted file
aws s3api list-object-versions --bucket hermes-vps-backups --prefix live/state.db \
--endpoint-url https://s3.us-east-1.wasabisys.com
# Copy a specific version back
aws s3api get-object --bucket hermes-vps-backups --key live/state.db \
--version-id <version-id> /root/.hermes/state.db \
--endpoint-url https://s3.us-east-1.wasabisys.com
Or just sync from a different backup prefix:
# Try the previous sync
aws s3 sync s3://hermes-vps-backups/live-sync/ /root/.hermes/ \
--endpoint-url https://s3.us-east-1.wasabisys.com
# Or try a daily backup
aws s3 cp s3://hermes-vps-backups/hermes-full-backup/hermes-full-backup-2026-07-05.tar.gz /tmp/
tar xzf /tmp/hermes-full-backup-2026-07-05.tar.gz -C /root/.hermes/
Scenario E: "ai.itpropartner.com Is Down" -- AI Services Unavailable
If the AI server (178.156.167.181) is offline:
-
Check if it's just a Docker issue:
ssh root@178.156.167.181 -i /root/.ssh/itpp-infra docker ps cd /opt/ai && docker compose up -d -
Check disk space (this server is at 92%):
df -h # If full, clean up old Docker images: docker system prune -a -
If the server is completely dead, Hermes loses access to the deepseek-chat model. Sho'Nuff would need to:
- Provision a new server
- Restore LiteLLM PostgreSQL database
- Restore Open WebUI data
- Point DNS to the new server
Scenario F: "The Internet Is Down at Home" -- Router Issues
If the home internet (and therefore the MikroTik router) is unavailable:
-
Check if the router is reachable via WireGuard:
ping -c 3 10.77.0.2 -
If unreachable, check the VPN tunnel:
systemctl status strongswan-starter systemctl status xl2tpd -
If VPN is down but Core is up, the rest of your infrastructure still works -- only home-related services are affected.
-
Restore router from last known good config (see Section 9).
13. Cron Jobs -- Complete List
On Core (152.53.192.33)
TZ=America/New_York
* * * * * /root/.hermes/scripts/dre-mail-poller.py
0 * * * * /root/.hermes/scripts/boys-mail-monitor.py collect 2>&1 | logger -t boys-mail-collect
0 19 * * * /root/.hermes/scripts/boys-mail-monitor.py summary 2>&1 | logger -t boys-mail-summary
0 8 * * * /root/shark-game/scraper/run.sh
*/15 * * * * /root/.hermes/scripts/shark-draft-reminder.sh 2>&1 | logger -t shark-draft-reminder
Hermes internal cron jobs (managed by Hermes itself):
- Various ticker-based tasks defined in
/root/.hermes/cron/jobs.json
On app1-bu (5.161.114.8)
*/5 * * * * /root/.hermes/scripts/hermes-standby-watchdog.sh
*/10 * * * * /root/.hermes/scripts/hermes-standby-sync.sh
On wphost02 (5.161.62.38)
0 3 * * * /usr/local/bin/lynis-scan.sh
To View Cron Jobs
crontab -l # Current user's crontab
cat /root/.hermes/cron/jobs.json # Hermes-managed cron jobs
This manual supersedes
shark-game-recovery-manual.md.
For shark-game-specific details (scoring, push notifications, common player issues), see the legacy manual at/root/.hermes/references/shark-game-recovery-manual.md.
All infrastructure recovery procedures above take precedence.