VPS
A VPS gives FitGuard a persistent filesystem and predictable networking. This guide uses Ubuntu and works on a DigitalOcean Droplet, Microsoft Azure VM, or AWS EC2 instance.
Create the server
Choose Ubuntu 24.04, attach an SSH key, and allow inbound TCP 80 and 443. Restrict SSH to your administration IP. On AWS, use an EBS-backed instance; on DigitalOcean, use the boot disk or a Block Storage volume; on Azure, use the VM's managed disk.
Use each provider's current image and size identifiers. They change by region, so select them in the provider console rather than copying a stale identifier from this page.
Install FitGuard
fitguard binary and your config both get copied up by hand (below). Nothing about that config file is special or expected by name, config.production.yaml below is just what this guide calls it; name it anything. Nothing here is committed to git first: you build/download the binary and write the config on your own machine, then scp them directly to the server. fitguard.db is never copied for a fresh install; it's created automatically on first run; see Move local data to production only if you're bringing existing history over.Build or download the Linux binary on a trusted machine, then copy it and your config to the server:
scp fitguard config.production.yaml ubuntu@<server-ip>:/tmp/ ssh ubuntu@<server-ip> sudo useradd --system --home /var/lib/fitguard --shell /usr/sbin/nologin fitguard sudo install -d -o fitguard -g fitguard -m 750 /var/lib/fitguard sudo install -d -m 750 /etc/fitguard sudo install -m 755 /tmp/fitguard /usr/local/bin/fitguard sudo install -m 600 /tmp/config.production.yaml /etc/fitguard/config.yaml sudo chown fitguard:fitguard /var/lib/fitguard
The useradd command is run on the server; skip it if the account already exists. Set data_dir: /var/lib/fitguard so the SQLite file is on the persistent disk.
Run it with systemd
Create the environment file first. EnvironmentFile is not optional in the unit below, so systemd refuses to start the service if this file does not exist:
sudo tee /etc/fitguard/fitguard.env >/dev/null <<'EOF' OPENAI_API_KEY=sk-... # REDIS_URL=rediss://... EOF sudo chmod 600 /etc/fitguard/fitguard.env
systemd reads this file as root before dropping to the fitguard user, so it does not need to be readable by that account.
sudo tee /etc/systemd/system/fitguard.service >/dev/null <<'EOF' [Unit] Description=FitGuard AI gateway After=network-online.target Wants=network-online.target [Service] User=fitguard Group=fitguard WorkingDirectory=/var/lib/fitguard ExecStart=/usr/local/bin/fitguard run --config /etc/fitguard/config.yaml EnvironmentFile=/etc/fitguard/fitguard.env Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now fitguard curl -fsS http://127.0.0.1:8787/healthz
Store provider keys and REDIS_URL in a root-readable environment file or secret manager, not in the repository. Keep the systemd unit itself free of secrets.
Add HTTPS
Point a DNS record at the server and put Caddy or nginx in front of FitGuard. Proxy / to 127.0.0.1:8787, disable proxy buffering for the dashboard's SSE stream, and set trusted_proxies to the proxy address.
Confirm it actually worked
In order, on the server (or against your domain once HTTPS is up):
sudo systemctl status fitguard:active (running), notfailedcurl -fsS http://127.0.0.1:8787/healthz(orhttps://your-domain/healthz) returns ok- Log in to
/dashboardin a browser - Send one real request through
/v1/chat/completionswith a virtual key - Confirm that request shows up on the dashboard's Requests page
- Restart the service (
sudo systemctl restart fitguard) and confirm that request is still there. This provesdata_diris actually on the persistent disk, not the wrong path