--- title: "Helm" description: "Quick-start guide for installing Site (newt) on Kubernetes using Helm." --- This guide installs and manages Site (newt) in Kubernetes using Helm. See [Version Matrix](https://github.com/fosrl/helm-charts/VERSION_MATRIX.md) for chart and default app version references. ## What the chart supports The Newt chart can deploy one or more Newt instances through `newtInstances[]`. Newt chart `1.4.0` includes support for: - provisioning with `NEWT_PROVISIONING_KEY` and `NEWT_NAME` - legacy credential installs with `NEWT_ID` and `NEWT_SECRET` - existing Kubernetes Secrets for production credentials - writable config persistence with `emptyDir` or an existing PVC - optional metrics, PodMonitor, ServiceMonitor, and PrometheusRule - optional NetworkPolicy - multi-instance deployments with per-instance overrides The chart README lists these features for version `1.4.0`. ## Prerequisites Before installing Newt, you need: - Kubernetes `1.30.14` or newer - Helm 3.x - `kubectl` access to the target cluster - a reachable Pangolin instance - either: - Newt credentials from Pangolin: `NEWT_ID` and `NEWT_SECRET` - or a provisioning key for provisioning installs The chart quickstart lists Kubernetes `>=1.30.14`, Helm 3.x, configured `kubectl`, and Newt credentials from Pangolin as prerequisites. See [Prerequisites](/self-host/manual/kubernetes/prerequisites) for cluster, namespace, storage, networking, and security planning. ## Authentication options Newt chart `1.4.0` supports three credential patterns: | Method | Recommended for | Notes | | --- | --- | --- | | Existing Secret | Production | Credentials are stored in a Kubernetes Secret created outside Helm | | Provisioning key | Provisioning installs | Requires writable config persistence | | Inline values | Local testing only | Credentials may be stored in Helm release history | For production, use `auth.existingSecretName` or a GitOps-safe secret workflow. The chart values explicitly warn that inline credentials can be stored in Helm release history and recommend existing Secrets for production. ## Quick install with existing Secret This is the recommended simple production pattern. ### Step 1: Create the namespace Create the namespace before installing the chart: ```bash kubectl create namespace pangolin ``` If your cluster uses Pod Security Admission labels, namespace labels, or policy annotations, apply them before installing Newt. Example: ```bash kubectl label namespace pangolin \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/warn=restricted ``` The chart can create namespaces through `namespace.create`, but creating the namespace explicitly is recommended when your cluster uses Pod Security Admission, namespace labels, or policy annotations. ### Step 2: Create the Newt Secret Create a Secret with the credentials from Pangolin: ```bash kubectl create secret generic newt-auth \ --namespace pangolin \ --from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \ --from-literal=NEWT_ID= \ --from-literal=NEWT_SECRET= ``` Get the Newt credentials from the Pangolin dashboard for the site you want this Newt instance to connect to. ### Step 3: Create a values file Create `values-newt.yaml`: ```yaml newtInstances: - name: main-tunnel enabled: true auth: existingSecretName: newt-auth replicas: 1 ``` The default Secret keys are: ```yaml PANGOLIN_ENDPOINT NEWT_ID NEWT_SECRET ``` You only need to set `auth.keys.*` if your Secret uses different key names. Example with custom Secret keys: ```yaml newtInstances: - name: main-tunnel enabled: true auth: existingSecretName: newt-auth keys: endpointKey: PANGOLIN_ENDPOINT idKey: NEWT_ID secretKey: NEWT_SECRET replicas: 1 ``` `auth.keys.*` are key names inside the Kubernetes Secret, not the credential values themselves. ([GitHub][2]) ### Step 4: Install Newt Add the Helm repository: ```bash helm repo add fossorial https://charts.fossorial.io helm repo update fossorial ``` Install Newt: ```bash helm upgrade --install newt fossorial/newt \ --namespace pangolin \ --values values-newt.yaml ``` Do not use `--create-namespace` here if you created and labeled the namespace manually. ### Step 5: Verify the deployment Check the Helm release: ```bash helm status newt --namespace pangolin ``` Check the pods: ```bash kubectl get pods --namespace pangolin \ -l app.kubernetes.io/name=newt ``` Check the logs: ```bash kubectl logs --namespace pangolin \ -l app.kubernetes.io/name=newt \ --tail=50 ``` Wait for the Newt pod to become ready: ```bash kubectl wait --for=condition=ready pod \ -l app.kubernetes.io/name=newt \ --namespace pangolin \ --timeout=60s ``` ## Quick install with provisioning key Provisioning-based installs bootstrap credentials from a provisioning key. Provisioning requires writable config persistence so Newt can store the generated configuration. The chart quickstart explicitly notes that provisioning requires a writable `CONFIG_FILE` target and that the chart provides this through `newtInstances[x].configPersistence`. ([GitHub][3]) Create `values-newt.yaml`: ```yaml newtInstances: - name: main-tunnel enabled: true pangolinEndpoint: https://pangolin.example.com provisioningKey: "" newtName: "my-site" configPersistence: enabled: true type: emptyDir mountPath: /var/lib/newt fileName: config.json ``` Install Newt: ```bash helm upgrade --install newt fossorial/newt \ --namespace pangolin \ --values values-newt.yaml ``` `emptyDir` is enough for testing, but it is ephemeral. For durable provisioning state, use `type: persistentVolumeClaim` with an existing PVC. Example with an existing PVC: ```yaml newtInstances: - name: main-tunnel enabled: true pangolinEndpoint: https://pangolin.example.com provisioningKey: "" newtName: "my-site" configPersistence: enabled: true type: persistentVolumeClaim existingClaim: my-newt-config mountPath: /var/lib/newt fileName: config.json ``` The Newt README includes both `emptyDir` and existing PVC provisioning examples. ([GitHub][4]) ## Verifying connectivity Follow the Newt logs: ```bash kubectl logs --namespace pangolin \ -l app.kubernetes.io/name=newt \ --follow ``` In the Pangolin dashboard, verify that the site connected by this Newt instance is online. If the pod is running but the site does not connect, check: * `PANGOLIN_ENDPOINT` * Newt credentials or provisioning key * DNS resolution from inside the cluster * outbound network access from the Newt pod * TLS validity for the Pangolin endpoint ## Upgrade Update the Helm repository: ```bash helm repo update fossorial ``` Upgrade the release: ```bash helm upgrade newt fossorial/newt \ --namespace pangolin \ --values values-newt.yaml ``` Check upgrade status: ```bash helm status newt --namespace pangolin helm history newt --namespace pangolin ``` Rollback to a previous revision if needed: ```bash helm rollback newt --namespace pangolin ``` ## Multiple Newt instances You can deploy multiple Newt instances with one chart release. Example: ```yaml newtInstances: - name: site-a enabled: true auth: existingSecretName: newt-auth-site-a replicas: 1 - name: site-b enabled: true auth: existingSecretName: newt-auth-site-b replicas: 1 ``` Create a separate Secret for each site: ```bash kubectl create secret generic newt-auth-site-a \ --namespace pangolin \ --from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \ --from-literal=NEWT_ID= \ --from-literal=NEWT_SECRET= kubectl create secret generic newt-auth-site-b \ --namespace pangolin \ --from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \ --from-literal=NEWT_ID= \ --from-literal=NEWT_SECRET= ``` ## Architecture notes ### Instance-based deployment * `newtInstances[]` defines the Newt instances rendered by the chart. * Each enabled instance creates its own workload. * Each instance can use its own Secret, provisioning settings, resources, service settings, and network policy settings. * Per-instance namespace and service account overrides require `allowGlobalOverride: true`. The chart values include `newtInstances[]`, per-instance namespace settings, and per-instance service account overrides. ([GitHub][2]) ### RBAC Newt chart `1.4.0` defaults `rbac.create` to `false`. Enable RBAC only when your selected Newt configuration requires Kubernetes API permissions. ```yaml rbac: create: true ``` The chart changelog for `1.4.0` marks this as a breaking change: installations that relied on auto-created RBAC must explicitly enable `rbac.create=true` during upgrade. ([GitHub][1]) ### Helm tests Helm test Jobs are disabled by default. Enable them only when you want to run chart test jobs: ```yaml global: tests: enabled: true ``` The chart quickstart notes that test Jobs are gated behind `global.tests.enabled`, which defaults to `false`. ([GitHub][3]) ## OCI install The Newt chart is also published as an OCI chart in GHCR. Pull the chart: ```bash helm pull oci://ghcr.io/fosrl/helm-charts/newt \ --version 1.4.0 ``` Install from OCI: ```bash helm upgrade --install newt oci://ghcr.io/fosrl/helm-charts/newt \ --version 1.4.0 \ --namespace pangolin \ --values values-newt.yaml ``` OCI changes where Helm pulls the chart from. It does not change the values file or the release behavior. ## References ## Next steps Review all Newt chart options. Debug Newt deployment and connection issues. Install Newt with rendered manifests and Kustomize overlays. Install the Pangolin control plane.