Kubernetes (Helm) Deployment
For a long-running Luna DevOps installation on Kubernetes, use Helm. The chart deploys API, Worker, PostgreSQL, and Redis together, and it can also connect to existing external database services.
These commands target standard Kubernetes. K3s and other distributions are supported when they meet the compatibility requirements; distribution-specific storage, Ingress, and security policies remain the cluster administrator's responsibility.
Before You Start
You need:
- A Kubernetes or K3s cluster.
kubectlandhelmconfigured locally.- Network access from the cluster to pull DockerHub images.
- A default StorageClass for PostgreSQL and Redis data.
Install
For a fresh database, first store the initial administrator configuration in a Kubernetes Secret. Keep the following file readable only by its owner and remove it securely after creating the Secret. The name and language keys may be omitted; API falls back to the email and zh-CN:
Then run this from the repository root:
API, Worker, PostgreSQL, and Redis are installed by default. The administrator Secret is injected only into API; API creates the account only in a fresh database and never overwrites it during upgrades or restarts. A database with an active administrator can omit api.initialAdmin, and the chart still installs or upgrades normally. The AI assistant is disabled; enable it with ai.enabled=true and provide a stable ai-internal-secret through ai.existingSecret.
After confirming that sign-in works, detach API from the initialization Secret and remove it:
All four Secret key references are optional. When existingSecret is empty, the chart neither creates nor references an initial administrator Secret. The initial password can only be provided through an external Secret, so it never enters Helm values or release history.
Open The Console
Forward the API Service:
Then visit:
Use A Fixed Version
Access the Console Through a Public Domain
When exposing the console with Ingress, set app.publicBaseUrl to the real browser-facing URL:
app.publicBaseUrl affects OIDC callbacks, webhook callbacks, and browser origin checks. Do not set it to an internal Service address. The example 10.42.0.0/16 only represents a dedicated Ingress or reverse-proxy source subnet; replace it with the sources actually seen by API and the proxy egress ranges in the trusted forwarding chain. Use a whole Pod CIDR only when network isolation prevents every other Pod from reaching API directly. The chart refuses to render an enabled Ingress without this boundary and always rejects 0.0.0.0/0 and ::/0.
Use External PostgreSQL Or Redis
The built-in services are convenient for getting started. If production already has managed PostgreSQL or Redis, disable the matching built-in component:
External Redis can use a connection URI or an existing Secret; use rediss:// for TLS. In production, provide credentials through Kubernetes Secrets instead of committing passwords to a values file.
Then install:
Configure Browser Trace Relay Authentication
API relays browser traces. If that relay uses different authentication from the Collector shared by API, Worker, and Agent, first store the complete OTEL_EXPORTER_OTLP_TRACES_HEADERS value in a separate Kubernetes Secret. Keep the local file below readable only by its owner and remove it securely after creating the Secret. URL-encode spaces and other special characters, such as %20:
Store only the Secret and key names in production values, never the Header credential. A dedicated relay endpoint is not secret and can use API-scoped extraEnv; when it is omitted, browser traces still use the shared OTLP endpoint with the API-only authentication configured here:
When browser traces use the same authentication as the shared Collector, leave api.browserTrace.existingSecret empty and API keeps falling back to observability.existingSecret. The dedicated Secret is injected only into API, never Worker or Agent. The chart also rejects plaintext credentials supplied through api.extraEnv.OTEL_EXPORTER_OTLP_TRACES_HEADERS.
Configure The Agent Network Policy
The chart enables API-to-Agent ingress isolation by default but does not restrict Agent egress by default. The Agent must reach its model Provider, OpenTelemetry Collector, and PostgreSQL; native Kubernetes NetworkPolicy cannot reliably express destinations backed by dynamic DNS records.
Enable egress isolation only after listing every real destination, for example:
For model Providers with dynamic addresses, use a CNI that supports FQDN policies or a stable egress proxy. A deny-all rule that omits real destinations is not a working configuration. The non-root user, read-only Agent root filesystem, and disabled ServiceAccount token remain enforced independently.
Common Values
Uninstall
PVCs are retained by default to prevent accidental data loss. Remove them manually only after confirming the data is no longer needed: