Vantage Docs
Self-hosting

Deployment prerequisites

What does each platform need before deploying: servers and Nomad, DNS and TLS, object storage, AI keys?

Everything here must exist before the first ansible-playbook run. Consul, Vault, Nomad, Caddy, Docker and (on self-hosted targets) Postgres are installed by the playbooks; you bring machines, names and a few third-party accounts.

Per target

GCP (terraform/gcp)Vultr (terraform/vultr)Your own serversMultipass (scripts/up.sh)
Control plane3 × e2-small3 × vc2-2c-4gb3 nodes3 × 1 vCPU, 1 GB, 6 GB disk
Workers3 × e2-standard-2 (8 GB); e2-standard-4 (16 GB) removes the headroom question3 × vc2-4c-8gb3 nodes, 8 GB or more3 × 3 vCPU, 9 GB, 40 GB disk
Worker data disk50 GB persistent disk each, mounted at /opt/nomad/volumes50 GB high_perf block storage eacha disk per workerVM disk
PostgresCloud SQL, PostgreSQL 18, db-perf-optimized-N-4, regional HA, PITR, private IPa database host, vc2-4c-8gb with 100 GB block storagea database host, or a managed instance (postgres_host)1 VM, 1 vCPU, 2 GB
OSUbuntu 24.04 LTSUbuntu 24.04 LTSUbuntu 24.04 LTSUbuntu 24.04
Vault unsealCloud KMS key from terraform/bootstrapShamir shares in pki/<env>/vault-init.json, or Cloud KMS via a service account key (new clusters only)Shamir, unless you set vault_seal_gcpckmsShamir
FirewallVPC rules: 80/443 public; SSH and the control-plane APIs over IAP only (iap_members)firewall groups: SSH from ssh_allowed_cidrs, 80/443 on workersyours; manage_firewall: true closes the host behind itnone
DNSCloud DNS records createdtofu output -raw dns_records, added at your provideryoursscripts/host-cluster-access.sh
AccountGCP project, Google account for IAPVULTR_API_KEY in the environmentSSH key access as a sudo userMultipass on the host
Inventorywritten to inventory/prod.ymlwritten to inventory/vultr.yml (cluster_env)hand-written from inventory/prod.yml.examplewritten by up.sh

The inventory is the whole porting job: a new target fills in hosts, node_ip, the server and client groups, nomad_volumes per worker and cluster_env_expected, and opts into vault_seal_gcpckms, manage_firewall or starrocks_external_host if it has them.

For every cluster target

ItemDetail
Workstation toolsscripts/prereqs.sh on Ubuntu or Debian: OpenTofu, Ansible (pipx, with psycopg2-binary), the Consul, Vault and Nomad CLIs, Node, jq, Multipass
Terraform stateA private Backblaze B2 bucket vantage-tfstate with versioning and a key scoped to it; B2_KEY_ID and B2_APPLICATION_KEY exported for tofu init
SSH key paired25519; public half in terraform.tfvars, private half where Ansible reads it
DomainA zone you control. Six names under it, each <label>.<domain>: analytics, auth, uploads, storage, monitoring, logs; three more for preview: analytics.preview, auth.preview, uploads.preview. There is no apex form
DNS resolvingEvery name resolves to the workers before the first deploy
TLSingress_tls: acme with ingress_email: Caddy gets Let's Encrypt certificates for each name, so 80 and 443 must reach the workers
Image pullpki/<env>/ghcr-pull.token: a GitHub personal access token with read:packages, owned by GHCR_USER in scripts/deploy.vars, before site.yml runs
Release and first adminscripts/deploy.vars from deploy.vars.example: VERSION_VANTAGE, PLATFORM_ADMIN_EMAIL, PLATFORM_ADMIN_FIRST_NAME, PLATFORM_ADMIN_LAST_NAME; deploy.sh refuses to run without the admin
IdentityNothing to bring: Vantage deploys its own Zitadel at auth.<domain>. Pointing it at your own identity provider is not supported. The issuer is fixed into every token, so pick the domain once

After the deploy, in Vault

These are seeded as placeholders, so the deploy succeeds without them; each is a vault kv patch and a job restart (Deploy and upgrade).

ItemVault pathWithout it
SMTP relay: host, port, user, password, fromsecret/zitadel/smtpInvitations and signup mail do not send
B2 bucket for backups (scripts/b2-buckets.sh creates vantage-backups)secret/vantage/b2-backupsNightly backups stay on the worker and the run fails
Anthropic API key (optional)secret/vantage/anthropicEvery AI feature and the MCP server are hidden
Resend key and sender (optional)secret/vantage/resendThe weekly digest stays in the app
Dodo Payments key, brand, webhook secret (optional)secret/vantage/dodoBilling answers 503 billing_not_configured

Object storage needs nothing: rustfs-bootstrap creates vantage-parquet-staging and its service account on every deploy.

Local compose

ItemDetail
Docker20.10 or newer (for host-gateway), with Compose v2
Sourcethe vantage repository checked out next to vantage-deployment, or VANTAGE_DIR pointing at it
Hostnamevantage.localhost resolving to 127.0.0.1 (systemd-resolved, glibc and macOS do; elsewhere add it to /etc/hosts)
Ports free8186, 3103, 1026, 8026, 5462, 9031, 8031, 8041, 4001, 8201, 6380, 7234, 9021, 4446, 4445, or overridden in compose/env/vantage.env

Limits to plan around

LimitEffect
External StarRocksQueries work; ingest does not, because the dataplane stream-loads straight to the BE and does not follow a managed frontend's redirect
External OIDCNot supported
Apex domainNot supported; every name needs a label
Platform n8nNot deployed; scheduled database syncs need an n8n you run

Next

On this page