Skip to main content
This guide deploys Vantage 3.0 self-hosted on a Kubernetes cluster that you provision and operate. It defines the interfaces Vantage requires from the cluster and uses Linkerd, Traefik, and External Secrets with HashiCorp Vault as examples. You can use equivalent components that satisfy the same requirements. This guide starts with a running Kubernetes cluster. It does not install Kubernetes, the service mesh, ingress controller, secret-management system, databases, storage, or registries for you.
The vantage-operator and vantage-selfhosted charts must use the same version. The examples on this page use version 0.70.13 for both charts.

Reference architecture

For supported and tested component versions, see Compatibility. For the complete infrastructure inventory and sizing baseline, see Prerequisites.

Before you begin

Have the following values and resources ready: You also need:
  • A DNS record for $your_vantage_hostname that resolves to your ingress entry point.
  • A valid TLS certificate for that hostname.
  • Kubernetes registry pull Secrets when your registry requires authentication.
  • Every application Secret listed under Secret aliases.
  • A distinct logical database name for each database alias. Each service’s migrator creates its database on first run.
  • Nodes labeled for TechCore workers.

Prepare the cluster

Configure ArgoCD

Install ArgoCD and enable ApplicationSet Progressive Syncs. ArgoCD also needs an OCI repository connection that can pull the Vantage component charts from your destination registry. Register the destination registry as an OCI Helm repository by following the ArgoCD private repository documentation. Keep the registry credential in your existing secret-management system rather than placing credentials directly in an ArgoCD Application manifest.

Configure the service mesh

Vantage requires mTLS between its workloads. Install and operate a supported service mesh, then enable mesh injection for $install_namespace before installing Vantage. For example, with Linkerd:
Confirm that newly created test pods in the namespace receive the mesh sidecar before continuing. If you use another mesh, follow its namespace- or workload-injection procedure.

Configure TechCore worker nodes

TechCore worker workloads select nodes with the following label:
Without at least one matching node, TechCore pods remain Pending. For training-worker isolation and the sizing baseline, see Kubernetes node requirements.

Configure persistent storage

Create or select a StorageClass before installing Vantage. The storage implementation must meet your production availability, durability, capacity, expansion, backup, and recovery requirements. Reference it in the Vantage values:
The StorageClass name is Kubernetes-distribution-neutral. Do not copy a development cluster’s local storage class into production without evaluating the loss and failover characteristics. Vantage provisions its own PersistentVolumeClaims on the class you name. Two requirements apply to any StorageClass:
  • Provisioned volumes must be writable by a non-root user. Vantage services run as non-root. If a volume’s mount directory is root-owned and not writable by the container user (for example, mode 0755), the blobstorage service fails its startup file-system check, host initialization aborts, and every service that depends on storage goes Degraded.
  • A PVC’s storageClassName is immutable. To move an existing installation to a different StorageClass, delete and recreate the operator’s PVCs on the new class.
A node-local class binds each PVC to a single node’s disk. For storage shared across nodes, the tested example is NFS through csi-driver-nfs, which provides an nfs StorageClass. The driver’s node plugin bundles the NFS mount utilities, so cluster nodes need no additional NFS packages.
When using csi-driver-nfs:
  • The driver requires an existing and already configured NFSv3 or NFSv4 server. Vantage does not ship or manage the driver or the server; you install and operate both.
  • Set mountPermissions: "0777" on the StorageClass. The provisioner creates each volume’s subdirectory owned by root, and a 0755 directory is not writable by the Vantage service user.
  • The NFS server must be reachable from every node and export its share with rw,sync,all_squash,insecure,no_subtree_check,anonuid=65532,anongid=65532. The all_squash mapping with anonuid/anongid presents every client, including the CSI driver, as uid/gid 65532, matching the Vantage pod security context. insecure permits connections from the unprivileged ports that containerized NFS clients use; without it, the server rejects those connections silently and storage writes fail with no visible error.
  • The export root directory must be owned by 65532:65532 with mode 0755. After changing /etc/exports or ownership on a running server, re-export with exportfs -ra.

Prepare databases

Vantage supports SQL Server and PostgreSQL. Set the provider exactly as shown; the value is case-sensitive:
Valid values are SqlServer and PostgreSQL. A value such as Postgresql or PostgreSql can fail at runtime because it does not match the application data-provider name. Every Vantage service must use a distinct logical database. Services run their own migrations, and pointing multiple services at one database causes their migration state to collide. Use the database inventory under Database aliases to plan the database names and connection strings. You do not need to create the databases by hand: each service’s migrator creates its database on first run.
Reporting is available only with SQL Server. When using PostgreSQL, leave vantage.reportingEnabled set to false.
PostgreSQL connection strings must be a single line without leading, trailing, or embedded newline characters.

Prepare Kubernetes Secrets

The Kubernetes secrets provider reads native Kubernetes Secret resources from $install_namespace. Vantage does not connect directly to Vault or another external secret store. If you use External Secrets Operator, a CSI driver, or another synchronization tool, configure it to materialize the required Kubernetes Secrets before installing Vantage. Select the Kubernetes provider:
By default, Vantage uses its documented Secret names. Use objects to map an alias to a different Secret:
The two auth keypairs sign application tokens. They are separate from the certificate that terminates public HTTPS at the ingress controller. See Certificate aliases for their required keys and formats. When several services consume the generic Database__ConnectionString key, create a separate Secret for each service and map each database alias through vantage.secrets.kubernetes.objects. Your secret-management system can derive these Secrets from a common connection-string template, but every resulting connection string must name a different database.
The operator validates the secrets configuration during preflight. The matched vantage-operator and vantage-selfhosted charts grant the operator read access to Secrets through a ClusterRole that is bound only in the Vantage release namespace. If you customize the operator namespace or controller ServiceAccount, make the corresponding operator values in the Vantage chart match that installation. A custom resourceNames restriction must include every Secret referenced by the Kubernetes provider.

Configure registry access

Registry access has three separate consumers: Create registry Secrets in the namespace where each consumer runs. Do not put plaintext registry passwords in your values file. For OCI migration, reference source and destination credential Secrets:
Add the destination registry pull Secret to the imagePullSecrets of the ServiceAccount named by vantage.serviceAccountName, the default ServiceAccount for Vantage workloads.
If a component pod runs under another ServiceAccount, that ServiceAccount also needs registry pull access. Check the pod’s spec.serviceAccountName before changing the namespace’s default ServiceAccount.

Configure autoscaling and metrics

KEDA support is optional and recommended. Use KEDA 2.17.3: KEDA 2.18 and later removed a scaler field used by the current Vantage workload charts and cannot create the required HPAs. Some Vantage ScaledObject resources query Prometheus at this fixed address:
Before enabling KEDA:
  1. Install KEDA 2.17.3.
  2. Install Prometheus Operator and a Prometheus instance in the observability namespace.
  3. Confirm its governing Service is named prometheus-operated and exposes port 9090.
  4. Configure Prometheus to discover the Vantage ServiceMonitor.
Enable KEDA on the Vantage resource and enable the chart’s ServiceMonitor through the separate top-level observability stanza:
observability is a top-level key; do not nest it under vantage. For trigger strategies, verification, and capacity planning, see Autoscaling with KEDA. For mesh-specific scraping configuration, see Monitoring with Prometheus.

Configure ingress and TLS

The chart’s built-in ingress is for Istio. When using Traefik or another ingress controller, disable it:
Your ingress configuration must:
  • Terminate HTTPS for vantage.dnsRecord with a trusted certificate.
  • Route the Vantage UI, API, authentication, help, SCIM, URL-shortener, workspace, verification, and Try Any Skill paths to their corresponding Services.
  • Apply the /api/vN/ to /publicapi/vN/, /api/, SCIM, and heartbeat rewrites used by Vantage.
  • Match more-specific routes before the UI catch-all route.
  • Forward the original host and scheme, including X-Forwarded-Proto: https when TLS terminates at the ingress controller.
Traefik implements these requirements with an IngressRoute and ordered Middleware resources. Treat the route manifest as versioned Vantage configuration: parameterize the hostname, namespace, certificate Secret, and generated Service names for your release rather than copying values from another environment.

Route contract

Resolve the generated Kubernetes Service names in $install_namespace, then implement these routes in the listed order. Regex and exact routes must take precedence over prefix and catch-all routes. The chart’s built-in Istio ingress also blocks /api/status and /api/status/config, which expose internal status information that clients do not need. Blocking these paths is recommended but not required for Vantage to run. If your ingress controller cannot return a direct denial response, you can route them to a dedicated deny backend before the general /api rule.

Forwarded HTTPS scheme

When TLS terminates at an ingress controller and the backend connection is HTTP, the Vantage authentication services must honor X-Forwarded-Proto. Ensure the following environment variable is present on the application containers for auth-identity, auth-adminapi2, api-gateway, and api-registry:
If the current workload charts do not expose an environment-variable override, use your standard admission mutation mechanism, such as Kyverno or an equivalent mutating webhook. Apply the mutation before creating the Vantage pods. Without it, the OIDC discovery document can advertise http:// endpoints and browser sign-in fails.

Install the operator

Install one operator instance in the cluster:
When the operator registry requires a pull Secret, add this option to the command before --wait:

Install Vantage

Create a values file that combines the configuration prepared above. This abbreviated example shows the self-managed-specific values; add the complete Secret mappings and registry credentials for your environment:
Install the matching vantage-selfhosted chart:
After the operator creates the workload Services, apply your ingress-controller configuration and verify that the TLS certificate is ready.

Monitor installation

Wait for the custom resource to report Ready:
Then verify the generated ArgoCD applications and workloads. Do not rely on Ready alone:
When OCI migration is enabled, monitor it separately:
Skill installation runs in a separate job and can continue after Vantage reports Ready:
Finally, confirm that:
  • Every generated ArgoCD application is Synced and Healthy.
  • Vantage pods are running and mesh-injected.
  • Prometheus reports Vantage /metrics-text targets as UP.
  • KEDA ScaledObject resources are Ready and HPA metric values are not <unknown>.
  • The OIDC discovery document and browser redirects use https:// URLs.
  • Vantage is available at https://$your_vantage_hostname.

What’s next

Secrets

Kubernetes Secret aliases, auth keypairs, and database connection strings.

Monitoring

Configure Prometheus to scrape Vantage through the service mesh.

Troubleshooting

Diagnose operator, database, registry, ingress, and autoscaling failures.

Upgrading

Upgrade the operator and Vantage charts together.