Which box, in English
How we map API workers, browsers, and local models onto 4 / 8 / 16 GB plans — and why prepaid Hostinger rates are not the same as Hetzner’s hourly cap.
Product
A one-time packet for people who will actually SSH in. It does not provision a server. It tells you which size to buy, how to keep a generic agent process alive in Docker, and how not to lose the disk.
Checkout is not live. There is no payment form on this page and the Polar button does not collect money. When a product URL exists, it will replace the empty polarCheckoutUrl in js/config.js.
Four pieces. The compose file and checklists are also mirrored in the kit/ folder of this static site so you can read them before anyone is paid.
How we map API workers, browsers, and local models onto 4 / 8 / 16 GB plans — and why prepaid Hostinger rates are not the same as Hetzner’s hourly cap.
Caddy + worker + Redis + optional Postgres. Swap the image. No product is the identity of the stack. restart: unless-stopped is the whole trick.
A checklist you can run on Sunday. Snapshots are not backups if they live on the same hypervisor you just wiped.
The fourth piece is the weekly price sheet — the same table as the homepage, frozen into the kit so you have a dated copy.
Start from RAM. vCPU is the second constraint. Disk is rarely the limiter until logs and browser profiles rot.
Use the homepage calculator for a matching pass against this week’s sheet. The $9/mo figure is the neighborhood of Hostinger KVM 2 intro and Hetzner CX33 with IPv4 — the 8 GB band, not a promise.
Copy from here or download kit/docker-compose.yml. Pair with kit/.env.example and kit/Caddyfile.
services:
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports: ["80:80", "443:443"]
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
depends_on: [agent]
agent:
image: ${AGENT_IMAGE:-python:3.12-slim}
restart: unless-stopped
env_file: .env
working_dir: /app
volumes:
- ./agent:/app
- agent_data:/var/lib/agent
command: ["python", "-m", "agent"]
depends_on:
redis: { condition: service_healthy }
db: { condition: service_healthy }
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health')"]
interval: 30s
timeout: 5s
retries: 3
redis:
image: redis:7-alpine
restart: unless-stopped
command: ["redis-server", "--appendonly", "yes"]
volumes: [redis_data:/data]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: agent
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: agent
volumes: [pg_data:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U agent"]
interval: 10s
volumes:
caddy_data:
agent_data:
redis_data:
pg_data:
Replace AGENT_IMAGE and the python -m agent command with your worker. Do not paste API keys into the compose file.
Full text: kit/backup-checklist.md.
.env, the Caddyfile, and any agent workspace directories. If it is not on the list, it will not come back.pg_dump to object storage or another region. Same-host snapshots die with the host..env in a password manager.Same data as the homepage, dated 26 Aug 2026.
| Vendor | Plan | vCPU | RAM | Disk | Transfer | Effective $/mo | Billing |
|---|