Deployment
Components
svitrio-api— the main Go API (:8080):/admin/*,/auth/*, public content, sitemap,/healthz. A static distroless binary (pure-Go SQLite).svitrio-portal-api— an isolated customer-portal API (:8081,/portal/*). A separate process on purpose: operator routes are never mounted, so a customer principal can’t reach them. Shares the same DB.admin SPA — the SvelteKit operator console, built static and served by nginx, pointed at the API via
VITE_SVITRIO_APIat build time.database — SQLite by default (a file on a volume); Turso built-in; Postgres/Neon via a plugin build.
Build note: the API depends on a sibling gate-go/ repo, so the Docker build context is the parent dir holding both svitrio/ and gate-go/.
cd /path/to/repos # holds svitrio/ and gate-go/
docker build -f svitrio/deploy/Dockerfile.api -t <registry>/svitrio-api .Bare-metal
cd api && go build -o bin/svitrio-api ./cmd/svitrio-api
cd ../admin && pnpm install && pnpm build # pnpm, not npm
export SVITRIO_JWT_SECRET=$(openssl rand -hex 32)
export SVITRIO_SECRETS_KEY=$(openssl rand -base64 32)
export SVITRIO_DB=/var/lib/svitrio/svitrio.db
./bin/svitrio-api # migrations run automatically on bootServe the admin SPA and the API behind a reverse proxy on separate hosts (admin. and api.).
Kubernetes
Apply deploy/k8s/* in order: namespace → secret (created imperatively, never from placeholders) → config/PVC/deployments/ingress. TLS via cert-manager (a letsencrypt ClusterIssuer; DNS-01 for a wildcart). The API stays at 1 replica with a Recreate strategy while on SQLite (an RWO volume can’t be held by two pods).
Svitrio also ships a per-tenant SaaS model (deploy/tenant/provision.sh) that stamps out a dedicated namespaced instance per customer sized by plan — reuse the pattern, swap the images/hosts/registry for your own.
First operator
There is no seed script: deploy, open the admin, request a magic link for your email and follow it — the first registered user is auto-promoted to seed + operator. Then register a passkey. Upgrades are rebuild-and-restart; migrations are forward-only and idempotent, but back up the database first.