00
Hetzner Cloud walkthrough
Hetzner Console · Docker Compose · Caddy · TLS

Hetzner Cloud is the reference deploy target for Archimedes. The maintainers run it there at archimedes.llmtech.net. Pick a server class, paste three values, run each command block, then paste the public URL into your phone.

Live reference: archimedes.llmtech.net runs on a Hetzner Cloud box. Same Docker Compose, same Caddy, same starter files this page hands you.

LLM: copy panel 11 into your assistant. AiMANAC: paste the same into HELM after you have AiMANAC installed. Never paste generated passwords into chat.

01
Pick a server class
Hetzner Cloud · Ubuntu 24.04 LTS

Archimedes runs the server and a desktop+browser sidecar in the same box. Pick the size based on whether you plan to leave the desktop sidecar idle most of the time or drive it hard.

Region: pick the Hetzner location closest to where you actually use HELM from — nbg1 (Nuremberg), fsn1 (Falkenstein), hel1 (Helsinki), ash (Ashburn US-East), hil (Hillsboro US-West), sin (Singapore). IHP-WS latency lives here.

02
Create the server
Hetzner Console · or hcloud CLI

Hetzner Cloud Console (browser)

  1. console.hetzner.cloud

    Sign in → New project (or pick existing) → Add server.

  2. Location + image

    Pick region from 01 → Ubuntu 24.04.

  3. Type

    CX32 recommended (or your choice from 01).

  4. SSH keys

    Upload your laptop's ~/.ssh/id_ed25519.pub (or generate a fresh keypair) before Hetzner creates the box. Password login is fine to skip.

  5. Firewalls (optional)

    Hetzner Firewall: allow inbound 22/tcp, 80/tcp, 443/tcp from any. Block everything else.

  6. Name

    archimedes-prod or similar — purely cosmetic. Click Create & Buy now. Note the public IPv4.

Or: hcloud CLI (one-liner)

Copy block 02 (CLI alternative)

# Install: brew install hcloud  (or https://github.com/hetznercloud/cli)
# One-time: hcloud context create archimedes  (paste API token from console → Security → API tokens)
hcloud server create \
  --name archimedes-prod \
  --type cx32 \
  --location nbg1 \
  --image ubuntu-24.04 \
  --ssh-key "$(whoami)-laptop"
hcloud server ip archimedes-prod   # prints the public IPv4 — copy this into block 03

If hcloud ssh-key list doesn't show your key, run hcloud ssh-key create --name "$(whoami)-laptop" --public-key-from-file ~/.ssh/id_ed25519.pub first.

03
Set your three values
Run once per terminal session — on your laptop
# --- edit these three lines ---
export VPS_IP=<public IPv4 from Hetzner>
export ARCH_HOST=archimedes.yourdomain.com
export DEPLOY_DIR="$HOME/archimedes-deploy"
# -----------------------------

mkdir -p "$DEPLOY_DIR"
cd "$DEPLOY_DIR"

VPS_IP is the IPv4 Hetzner assigned in panel 02. ARCH_HOST is the subdomain you'll point at that IP in panel 04 (DNS is provider-independent; use your registrar — Cloudflare, Namecheap, GoDaddy, etc.).

04
DNS: point ARCH_HOST at VPS_IP
Your DNS provider · TTL 300
  1. A record

    Host archimedes (or whatever subdomain you chose) → Value $VPS_IP → TTL 300.

  2. Cloudflare

    Proxy off (gray cloud) at least through first Caddy boot — the proxy interferes with Let's Encrypt HTTP-01 issuance.

  3. Verify before continuing

    Run the verify in panel 09 first if you want to wait for propagation. Otherwise continue and re-run 09 when you're ready.

05
Download starter files
Into $DEPLOY_DIR (shared with the VPS guide)

These three files are provider-agnostic — the same artifacts the VPS-generic guide hands you. Hetzner doesn't need its own copies.

Copy block 05

cd "$DEPLOY_DIR"
curl -fsSLO "https://aimanac.llmtech.net/apps/archimedes/setup/vps/cloud-init.sh"
curl -fsSLO "https://aimanac.llmtech.net/apps/archimedes/setup/vps/docker-compose.yml"
curl -fsSLO "https://aimanac.llmtech.net/apps/archimedes/setup/vps/Caddyfile"
06
Bootstrap the box
Pipes cloud-init to SSH · safe to re-run

Copy block 06

cd "$DEPLOY_DIR"
ssh root@"$VPS_IP" 'bash -s' < cloud-init.sh

Installs Docker, Caddy, UFW (22/80/443), and the /opt/archimedes/ layout. Re-running the script is idempotent.

07
Generate secrets
Local · never paste into chat

Copy block 07

cd "$DEPLOY_DIR"
mkdir -p secrets
openssl rand -hex 32 > secrets/postgres_password.txt
JWT=$(openssl rand -hex 32)
JWT_REFRESH=$(openssl rand -hex 32)
cat > .env <
  
08
Patch hostname · pull image · start stack
Caddyfile and compose · GHCR pull (no git clone)

Copy block 08a — patch hostnames + pin image tag

cd "$DEPLOY_DIR"
export ARCH_IMAGE_TAG=rust-cutover-20260520-ghcr-pipeline
sed -i.bak "s/archimedes.example.com/$ARCH_HOST/g" Caddyfile docker-compose.yml
grep -E "BACKEND_PUBLIC_URL|$ARCH_HOST" docker-compose.yml Caddyfile

Copy block 08b — pull public image on the box

ssh root@"$VPS_IP" "export ARCH_IMAGE_TAG=$ARCH_IMAGE_TAG && docker pull ghcr.io/everplay-tech/archimedes-server:\$ARCH_IMAGE_TAG"

Copy block 08c — upload compose, env, Caddy · start

cd "$DEPLOY_DIR"
scp docker-compose.yml root@"$VPS_IP":/opt/archimedes/
scp .env root@"$VPS_IP":/opt/archimedes/
scp secrets/postgres_password.txt root@"$VPS_IP":/opt/archimedes/secrets/
scp Caddyfile root@"$VPS_IP":/etc/caddy/Caddyfile
ssh root@"$VPS_IP" "export ARCH_IMAGE_TAG=$ARCH_IMAGE_TAG && chmod 700 /opt/archimedes/secrets && systemctl reload caddy && cd /opt/archimedes && docker compose pull && docker compose up -d"

First docker pull may take a few minutes; no Rust compile on your VPS.

09
Verify — run before opening the app
Copy each curl; all must pass

Copy block 09

dig +short "$ARCH_HOST"
# Expect: $VPS_IP

export ARCH_URL="https://$ARCH_HOST"
curl -fsSI "$ARCH_URL/health" | head -1
curl -fsSI "$ARCH_URL/ready" | head -1
curl -fsSI -H "Connection: Upgrade" -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \
  "$ARCH_URL/ihp-ws" | head -1
ssh root@"$VPS_IP" 'docker compose -f /opt/archimedes/docker-compose.yml ps'

/health and /readyHTTP/2 200. WebSocket route → 101 or 426. Containers → server + postgres Up. If TLS is stuck: Cloudflare proxy off, port 80 open in Hetzner Firewall.

10
Paste URL into Archimedes
Phone first · AiMANAC Connections later

Your backend URL (copy this line)

https://$ARCH_HOST
  1. Archimedes app

    First boot → paste https://$ARCH_HOST (no trailing path) → Sign in with Apple.

  2. AiMANAC + HELM

    Settings → Connections → Add Backend with the same URL once you orchestrate from AiMANAC.

11
Paste into your LLM (full walkthrough)
Self-contained — do not include .env contents

Select everything in the box below and paste into ChatGPT, Claude, or HELM. The assistant should run blocks 03–09 in order on your machine; you type secrets locally only.

I am deploying Archimedes on Hetzner Cloud. Help me run these steps on my laptop (macOS or Linux). I will provision the Hetzner box, set VPS_IP, ARCH_HOST, and DEPLOY_DIR myself, and will NOT paste JWT or database passwords into this chat.

1) Hetzner Cloud Console → Add server → Ubuntu 24.04 → CX32 (or CX22 minimum) → upload my SSH key → create. Note the public IPv4.

2) export VPS_IP=<public IPv4>
   export ARCH_HOST=archimedes.<my-domain>
   export DEPLOY_DIR=$HOME/archimedes-deploy
   mkdir -p "$DEPLOY_DIR" && cd "$DEPLOY_DIR"

3) DNS: A record ARCH_HOST → VPS_IP, TTL 300. Cloudflare proxy OFF.

4) curl cloud-init.sh, docker-compose.yml, Caddyfile from https://aimanac.llmtech.net/apps/archimedes/setup/vps/

5) ssh root@$VPS_IP 'bash -s' < cloud-init.sh   (bootstrap)

6) In DEPLOY_DIR: openssl rand for postgres_password.txt; build .env with POSTGRES_PASSWORD, JWT_SECRET, JWT_REFRESH_SECRET, RUST_LOG=info; chmod 600.

7) sed -i.bak "s/archimedes.example.com/$ARCH_HOST/g" Caddyfile docker-compose.yml

8) export ARCH_IMAGE_TAG=rust-cutover-20260520-ghcr-pipeline; docker pull ghcr.io/everplay-tech/archimedes-server:$ARCH_IMAGE_TAG on the VPS. No git clone.

9) scp compose, .env, postgres secret, Caddyfile; ssh reload caddy; cd /opt/archimedes && docker compose pull && docker compose up -d (no --build).

10) dig +short ARCH_HOST must return VPS_IP.

11) Verify: curl -I https://ARCH_HOST/health and /ready (200); WebSocket probe on /ihp-ws; docker compose ps shows server and postgres Up.

12) I will paste https://ARCH_HOST into Archimedes iOS FirstBoot.

Canonical page: https://aimanac.llmtech.net/apps/archimedes/setup/hetzner/
Ask me for VPS_IP and ARCH_HOST when you need them; never ask me to paste .env.
12
Quick fixes · ops · why Hetzner
Diagnostics you can paste

Logs

ssh root@"$VPS_IP" 'cd /opt/archimedes && docker compose logs -f --tail=80 archimedes-server'

Restart app

ssh root@"$VPS_IP" 'cd /opt/archimedes && docker compose restart archimedes-server'

Hetzner snapshot before risky change

hcloud server create-image archimedes-prod --type snapshot --description "pre-upgrade-$(date +%Y%m%d)"