K
Koltrix docs

Deployment

Koltrix is designed to run on a single VPS (or scale out later). The recommended target is a 4 vCPU / 8 GB Linux box with at least 80 GB disk.

One-liner installer

From a fresh checkout:

git clone https://github.com/koltrix/koltrix.git && cd koltrix
./scripts/install.sh

The installer:

  1. Verifies Docker and Docker Compose v2 are installed.
  2. Copies .env.example to .env and fills random secrets.
  3. Builds every container.
  4. Starts the stack and waits for /health.
  5. Prints next steps.

Production checklist

  • Point app.koltrix.com, api.koltrix.com, and docs.koltrix.com at the server IP. The wildcard A record makes any tenant subdomain work too.
  • Issue a TLS cert: certbot with the Cloudflare DNS-01 plugin works well for wildcards through Cloudflare proxy.
sudo apt install python3-certbot-dns-cloudflare
echo "dns_cloudflare_api_token = $CF_TOKEN" | sudo tee /root/.secrets/cloudflare.ini
sudo chmod 600 /root/.secrets/cloudflare.ini
sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  --cert-name koltrix.com \
  -d "koltrix.com" -d "*.koltrix.com"
  • Edit /etc/nginx/sites-available/koltrix to use the wildcard cert and reload nginx.
  • Add a PTR record at your hosting provider so reverse-DNS resolves <your-ip>mail.koltrix.com.
  • Set production Clerk + Stripe + AI keys in .env. Restart:
docker compose restart

DNS records

TypeNameContentProxied
Aapp<server IP>
A* (wildcard)<server IP>
Amail<server IP>✗ (DNS only)
MXapexmail.koltrix.com priority 10
TXTapex (SPF)v=spf1 ip4:<server IP> ~all
TXTkoltrix._domainkey (DKIM)public key from Rspamd
TXT_dmarcv=DMARC1; p=quarantine; ...

Backups

  • Postgres: pg_dump nightly to S3/MinIO. We bundle a sample cron job in scripts/backup-db.sh.
  • MinIO: mc mirror to off-site.

Scaling out

When you outgrow one server:

  • Web + API + worker: trivially horizontal — multiple containers behind the nginx upstream. Sessions are JWT; Redis handles queue state.
  • Postfix: stays on a single IP per dedicated tenant for deliverability.
  • Postgres: move to managed (RDS / Neon / Supabase) when ready.
  • Asynq worker: split by queue (we already have critical, default, low) and scale specialized workers independently.

See Architecture for the service map.