Skip to main content

Try free on Pangolin Cloud

Fastest way to get started with Pangolin using the hosted control plane. No credit card required.
Flux is a declarative GitOps tool that uses Kubernetes-native Custom Resources to manage deployments. This guide covers installing Pangolin and Newt using Flux.

Flux prerequisites

  • Kubernetes 1.25+
  • flux CLI installed: Flux install guide
  • Git repository for configuration (optional, can use built-in sources)
  • GitHub, GitLab, or other Git provider account (optional)
Install Flux CLI:
# macOS/Linux with brew
brew install flux

# or curl
curl -s https://fluxcd.io/install.sh | sudo bash

# Verify
flux --version

Install Flux on your cluster

Option 1: Bootstrap Flux from GitHub

Flux bootstrap automatically installs Flux and configures Git sync:
flux bootstrap github \
  --owner=my-org \
  --repo=infrastructure \
  --personal \
  --path=clusters/production
This creates the Git repository structure and installs Flux components.

Option 2: Manual Flux installation

# Create flux-system namespace and install Flux
flux install --namespace=flux-system --network-policy=true

Install Pangolin with Flux using HelmRelease

Step 1: Create HelmRepository

Define the Fossorial Helm chart repository:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
  name: fossorial
  namespace: flux-system
spec:
  interval: 5m
  url: https://charts.fossorial.io
Apply:
kubectl apply -f helmrepo.yaml

# Verify
kubectl get helmrepo -n flux-system

Step 2: Create Pangolin HelmRelease

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: pangolin
  namespace: pangolin
spec:
  interval: 10m
  chart:
    spec:
      chart: pangolin
      version: 0.1.0-alpha.0  # or use ~0.1.0 for auto-upgrades
      sourceRef:
        kind: HelmRepository
        name: fossorial
        namespace: flux-system
  
  install:
    crds: Create
  upgrade:
    crds: CreateReplace
  
  values:
    deployment:
      type: controller
      mode: multi

    database:
      mode: cloudnativepg

    pangolin:
      config:
        app:
          dashboard_url: https://pangolin.example.com
        domains:
          domain1:
            base_domain: example.com
        gerbil:
          base_endpoint: vpn.example.com

    ingress:
      enabled: true
      className: traefik
      hosts:
        - host: pangolin.example.com
          paths:
            - path: /
              pathType: Prefix
      tls:
        - secretName: pangolin-tls
          hosts:
            - pangolin.example.com
Create namespace:
kubectl create namespace pangolin
Apply:
kubectl apply -f pangolin-helmrelease.yaml

Step 3: Monitor reconciliation

# Check HelmRelease status
kubectl get helmrelease -n pangolin

# Watch live
kubectl get helmrelease -n pangolin -w

# Describe for details
kubectl describe helmrelease pangolin -n pangolin

# Check Flux logs
flux logs --all-namespaces --follow

Install Newt with Flux using HelmRelease

Step 1: Create Newt auth secret

kubectl create secret generic newt-auth \
  -n pangolin \
  --from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
  --from-literal=NEWT_ID=<your-newt-id> \
  --from-literal=NEWT_SECRET=<your-newt-secret>

Step 2: Create Newt HelmRelease

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: newt
  namespace: pangolin
spec:
  interval: 10m
  chart:
    spec:
      chart: newt
      version: 1.4.0
      sourceRef:
        kind: HelmRepository
        name: fossorial
        namespace: flux-system
  
  values:
    newtInstances:
      - name: main-tunnel
        enabled: true
        auth:
          existingSecretName: newt-auth
Apply:
kubectl apply -f newt-helmrelease.yaml

Step 3: Verify

kubectl get helmrelease -n pangolin
kubectl describe helmrelease newt -n pangolin

Using Flux with Git repository (GitOps)

Store Flux configuration in Git and have Flux automatically reconcile changes:

Repository structure

infrastructure/
├── clusters/
│   └── production/
│       ├── flux-system/
│       │   └── gotk-components.yaml (auto-generated)
│       ├── pangolin/
│       │   ├── helmrepo.yaml
│       │   ├── pangolin-helmrelease.yaml
│       │   └── newt-helmrelease.yaml
│       └── kustomization.yaml
└── apps/
    ├── pangolin/
    │   └── values.yaml
    └── newt/
        └── values.yaml

GitRepository for configuration

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: infrastructure
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/my-org/infrastructure
  ref:
    branch: main

Kustomization for syncing

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: production
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: infrastructure
  path: ./clusters/production
  prune: true
  wait: true
Flux watches clusters/production in Git and auto-applies all resources.

Using Flux with Kustomize overlays

Manage environment-specific overlays with Flux:

Repository structure

overlays/
├── dev/
│   ├── kustomization.yaml
│   └── pangolin-patch.yaml
├── staging/
│   └── kustomization.yaml
└── prod/
    ├── kustomization.yaml
    └── pangolin-patch.yaml

Kustomization resource

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: pangolin-prod
  namespace: flux-system
spec:
  interval: 10m
  sourceRef:
    kind: GitRepository
    name: infrastructure
  path: ./overlays/prod
  prune: true
  wait: true
Flux builds and applies the Kustomize overlay automatically.

Using Flux with OCI Helm charts

If Helm charts are available in an OCI registry:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
  name: fossorial-oci
  namespace: flux-system
spec:
  interval: 5m
  url: oci://registry.example.com/fossorial

---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: pangolin
  namespace: pangolin
spec:
  interval: 10m
  chart:
    spec:
      chart: pangolin
      version: 0.1.0-alpha.0
      sourceRef:
        kind: OCIRepository
        name: fossorial-oci
        namespace: flux-system
  values:
    # ... values ...

Advanced: Dependency ordering

Order HelmReleases to install dependencies first:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: cert-manager
  namespace: cert-manager
spec:
  interval: 10m
  chart:
    spec:
      chart: cert-manager
      # ...

---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: pangolin
  namespace: pangolin
spec:
  interval: 10m
  dependsOn:
    - name: cert-manager
      namespace: cert-manager
  chart:
    spec:
      chart: pangolin
      # ...
Flux ensures cert-manager reconciles before pangolin.

Advanced: valuesFrom ConfigMap/Secret

Store values in ConfigMaps or Secrets, referenced from HelmRelease:
apiVersion: v1
kind: ConfigMap
metadata:
  name: pangolin-values
  namespace: pangolin
data:
  values.yaml: |
    deployment:
      type: controller
      mode: multi

---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: pangolin
  namespace: pangolin
spec:
  interval: 10m
  chart:
    spec:
      chart: pangolin
      # ...
  valuesFrom:
    - kind: ConfigMap
      name: pangolin-values
Flux extracts values from the ConfigMap and applies them to the HelmRelease.

Troubleshooting Flux

Check Flux components

kubectl get deployments -n flux-system
flux check --all-namespaces

Check HelmRelease status

kubectl get helmrelease -n pangolin
kubectl describe helmrelease pangolin -n pangolin
kubectl get helmrelease pangolin -n pangolin -o yaml

View reconciliation logs

flux logs --all-namespaces --follow

# Specific resource
kubectl logs -n pangolin deployment/helm-operator -f

Manual reconciliation

flux reconcile helmrelease pangolin -n pangolin
flux reconcile kustomization production -n flux-system

Suspend reconciliation

flux suspend helmrelease pangolin -n pangolin

Resume reconciliation

flux resume helmrelease pangolin -n pangolin

Multi-environment example

Bootstrap multiple clusters

# Production cluster
flux bootstrap github \
  --owner=my-org \
  --repo=infrastructure \
  --personal \
  --path=clusters/production

# Staging cluster (from different checkout)
flux bootstrap github \
  --owner=my-org \
  --repo=infrastructure \
  --personal \
  --path=clusters/staging
Each cluster reconciles its own clusters/*/ directory.

Repository structure

clusters/
├── production/
│   ├── kustomization.yaml
│   └── pangolin/
│       ├── helmrepo.yaml
│       └── helmrelease.yaml (prod values)
├── staging/
│   ├── kustomization.yaml
│   └── pangolin/
│       ├── helmrepo.yaml
│       └── helmrelease.yaml (staging values)
└── dev/
    ├── kustomization.yaml
    └── pangolin/
        └── helmrelease.yaml (dev values)
Each environment’s HelmRelease uses environment-specific values.

Next steps

GitOps Overview

Argo CD

Pangolin Configuration

Troubleshooting