Deployment
Lantern splits into a control plane (scheduling, routing, dashboard) and a data plane (microVMs, execution, secrets). The data plane runs in your cloud — agent data never leaves your VPC.
Architecture — the CP/DP split
Deployment options
Fully managed (Lantern Cloud)
Both planes hosted by Lantern. No infrastructure to manage. Everything runs on Lantern infrastructure.
Hybrid (recommended for production)
Control plane hosted by Lantern; data plane in your cloud. Agent data stays in your VPC.
- Deploy the data plane Helm chart into your cluster (see below).
- Register via
POST /v1/data-planesor Settings → Data Planes. This mints a one-time 32-byte bootstrap token — store it immediately. - The data plane dials out to
:50051(gRPC), sends the bootstrap token viaRegisterRPC, and receives a short-lived session JWT (1 h TTL, auto-rotated viaRefreshToken). - The data plane opens a persistent
RunStreambidi RPC. The control plane pushes run assignments; the agent reports status and completion back. Only run metadata crosses the boundary.
Tunnel RPCs
Defined in packages/proto/lantern/v1/dataplane.proto, served on the control plane's :50051 listener.
| RPC | Direction | Purpose |
|---|---|---|
Register | agent → CP | Exchange bootstrap token for session JWT |
Heartbeat | agent → CP | Liveness (every 30 s); learns drain orders |
ReportMetrics | agent → CP | CPU / memory / active-run pressure (every 60 s) |
RefreshToken | agent → CP | Rotate session JWT before 1 h expiry |
RunStream (bidi) | agent ↔ CP | CP pushes assignments; agent reports accepted / completed |
LANTERN_DP_MAX_STREAMS_PER_TENANT concurrent RunStream connections (default 10). Excess connections return gRPC RESOURCE_EXHAUSTED.Fully self-hosted
Both planes in your infrastructure. Full control, full responsibility.
Helm
The repo ships one chart, infra/helm/lantern, with values-dev.yaml, values-staging.yaml and values-prod.yaml. It deploys the gateway, control plane, model router, workflow engine, runtime manager, runtime scheduler, surface gateway and dashboard, with in-cluster Postgres and S3-compatible storage for development and a Redis subchart. The chart defaults LANTERN_ENV=production, so the production startup guards are on.
helm install lantern ./infra/helm/lantern \
--namespace lantern --create-namespace \
--values infra/helm/lantern/values-prod.yamlTop-level values keys: global, gateway, controlPlane, modelRouter, workflowEngine, runtimeManager, runtimeScheduler, surfaceGateway, dashboard, postgresql, redis, minio, ingress, networkPolicy, backup, secrets, serviceAccount. There is no separate data-plane chart yet; for a data plane in another cloud, use the Terraform path below.
Production settings
- Autoscaling and disruption —
<component>.autoscaling.enabledadds a CPU-based HPA (needs metrics-server) for the control plane, gateway, model router, workflow engine and dashboard;values-prod.yamlturns it on. Components with more than one replica get a PodDisruptionBudget. - NetworkPolicy —
networkPolicy.enabled=truedenies all traffic in the release, then allows only the service-to-service flows the platform needs, DNS, and scrapes of/metricsfromnetworkPolicy.metricsFrom. Only the control plane, model router, workflow engine, runtime scheduler, runtime manager, surface gateway and backup job may leave the cluster; usenetworkPolicy.extraEgressfor managed Postgres or Redis on private IPs. Your CNI must enforce policy (Calico, Cilium). - Secrets you must supply —
secrets.jwtSecret,credentialKey,receiptSecret,grpcServiceToken,schedulerNodeToken,appDbPassword, and with managed storespostgresPasswordandminioPassword(the S3 secret key). The control plane also refuses to start in production without its gRPC TLS cert and the runtime-manager mTLS client cert; the chart cannot create these, so mount them withcontrolPlane.extraVolumesandextraEnv. - Backups —
backup.enabled=trueadds a CronJob that writes a gzippedpg_dumptos3://<backup.s3Bucket>/postgres/and prunes dumps older thanbackup.retentionDays. Prove a dump restores withscripts/db-restore-drill.sh <dump.sql.gz>; seedocs/runbooks/db-restore.md. This is a floor; managed Postgres with point-in-time recovery is the recommended production path.
/healthz by default because /readyz stays unready until a runtime-manager node registers.In-cluster dependencies (dev) vs managed (prod)
Lantern needs Postgres with the pgvector extension, an S3-compatible object store and Redis. The chart can run them for you, which is what you want on kind or a laptop, but production should use managed services.
| Dev / kind / evaluation (default) | Production (values-prod.yaml) | |
|---|---|---|
| Postgres | postgresql.enabled=true: one pgvector/pgvector StatefulSet with a PVC. Password is secrets.postgresPassword. | postgresql.enabled=false and externalDatabase.host (plus port, sslmode). User and database names still come from postgresql.auth. Provision pgvector and the lantern_app role yourself. |
| Object store | minio.enabled=true: one SeaweedFS StatefulSet with a PVC, one identity built from minio.auth.rootUser and secrets.minioPassword. Buckets in minio.defaultBuckets are created by a post-install Job. | minio.enabled=false and externalS3.endpoint, accessKeyId, bucket and region (must match the bucket's region); the secret key is secrets.minioPassword. |
| Redis | Bitnami subchart (redis.enabled). | Same subchart for now. |
With the in-cluster stores off, helm template fails unless externalDatabase.host and externalS3.endpoint are set, so a production install cannot silently fall back to a single-pod database.
values.yaml (postgresql.image, minio.image). Earlier versions of the chart used Bitnami subcharts for Postgres and MinIO; those crash-looped on the pgvector image and their MinIO images are no longer published. The new Postgres and object-store StatefulSets keep the old names but use different selectors, which Kubernetes will not patch in place: to move an existing release, take a dump (docs/runbooks/db-restore.md), uninstall, install, and restore.Terraform
lantern infra install --cloud aws|gcp|azure generates Terraform for a data-plane cluster. Flags include --tenant-id (required), --region, --cluster-name, --existing-cluster, --instance-type and --node-count. The modules live in infra/terraform/ and are not published to the Terraform Registry. Review the output, then apply.
lantern infra install --cloud aws --region us-east-1 --tenant-id <tenant-id> # generates terraform/ in the current directory
cd terraform
terraform init
terraform plan
terraform applyNamespace isolation
Each tenant gets its own Kubernetes namespace: lantern-t-<tenant_id>. Provides network isolation, per-tenant resource quotas, and separate service accounts and secrets.
Monitoring
Every service emits OTel traces tagged with tenant_id, run_id, step_id, and agent_version. Compatible with Grafana + Tempo, Datadog, New Relic, Jaeger, and any OTel backend. The control plane also serves Prometheus metrics at :8080/metrics (HTTP request duration by status, run totals, budget blocks), unauthenticated, so scrape it only from inside the cluster. Alert rules and Grafana dashboards live in infra/monitoring/; runbooks in docs/runbooks/. See Observability for details.
Database migrations
The control plane manages its Postgres schema via golang-migrate. Migrations are embedded SQL shipped inside the binary.
- Fresh databases — migration
0001creates the full schema on first boot. - Existing databases —
0001is fullyIF NOT EXISTS; running it records version 1 inschema_migrationswith no DDL changes. - New changes — sequential pairs (
0002_*.up.sql/0002_*.down.sql). Down migrations required after the baseline.