> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensormesh.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Install with GitOps

> Install the Tensormesh Operator declaratively with Argo CD or Flux.

GitOps tools (Argo CD, Flux) wrap the same Helm chart described in [Install with
Helm](/operator/installation/helm). The values are identical — the only difference is that
the chart is rendered and applied by a controller running in your cluster, with desired
state stored in Git instead of in your local shell.

<Note>
  The chart is distributed through a private registry. Your GitOps controller needs a token
  to pull it — **request an access token from the Tensormesh team** and store it as a
  registry credential your controller references (shown in each example below). When
  authenticating with a token the username field can be any non-empty value.
</Note>

## Argo CD

First register the registry credentials Tensormesh gave you (one-time), then add an
`Application` that pulls the chart over OCI:

```yaml registry-creds.yaml theme={null}
# Argo CD repo-credential for the private registry. Uses the username + token from Tensormesh.
apiVersion: v1
kind: Secret
metadata:
  name: tensormesh-registry
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repo-creds
stringData:
  type: helm
  enableOCI: "true"
  url: ghcr.io/tensormesh-production/charts
  username: tensormesh                  # any non-empty value works with a token
  password: <TOKEN_FROM_TENSORMESH>
```

```yaml application.yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: tensormesh-operator
  namespace: argocd
spec:
  project: default
  source:
    repoURL: ghcr.io/tensormesh-production/charts   # OCI registry host + path
    chart: tensormesh-operator
    targetRevision: 0.1.0                            # pin the chart version
    helm:
      releaseName: tensormesh-operator
      values: |
        operator:
          replicas: 1
        engine:
          enabled: true
          spec:
            l1:
              sizeGB: 60
        openshift:
          enabled: false             # set true on OpenShift clusters
  destination:
    server: https://kubernetes.default.svc
    namespace: tensormesh-operator
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true
    automated:
      prune: true
      selfHeal: true
```

### CRD ordering

The `LMCacheEngine` CRD ships inside the chart's `templates/` directory and is annotated
with Helm's `InstallOrder` so it is applied before any CR. Argo CD respects the same
annotation by default, so a fresh install converges in one sync.

If you split the chart into multiple Applications (for example, CRDs in one, operator in
another), use Argo CD sync waves to enforce ordering:

```yaml theme={null}
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "-1"   # CRD app
```

```yaml theme={null}
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: "0"    # operator + engine app
```

## Flux

Create a registry secret from the Tensormesh credentials, then point an OCI
`HelmRepository` at it:

```bash theme={null}
# One-time: store the credentials Tensormesh gave you as a registry secret.
kubectl create secret docker-registry tensormesh-registry \
  -n flux-system \
  --docker-server=ghcr.io \
  --docker-username='tensormesh' \
  --docker-password='<TOKEN_FROM_TENSORMESH>'
```

```yaml flux.yaml theme={null}
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: tensormesh
  namespace: flux-system
spec:
  type: oci
  interval: 1h
  url: oci://ghcr.io/tensormesh-production/charts
  secretRef:
    name: tensormesh-registry
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: tensormesh-operator
  namespace: tensormesh-operator
spec:
  interval: 10m
  chart:
    spec:
      chart: tensormesh-operator
      version: 0.1.0
      sourceRef:
        kind: HelmRepository
        name: tensormesh
        namespace: flux-system
  install:
    createNamespace: true
  values:
    operator:
      replicas: 1
    engine:
      enabled: true
      spec:
        l1:
          sizeGB: 60
    openshift:
      enabled: false
```

## Multi-cluster

For fleets, use Argo CD ApplicationSets (or Flux Kustomizations) to roll the same release
across many clusters with per-cluster overrides:

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: tensormesh-operator
  namespace: argocd
spec:
  generators:
    - clusters: {}                  # all registered clusters
  template:
    metadata:
      name: 'tensormesh-operator-{{name}}'
    spec:
      project: default
      source:
        repoURL: ghcr.io/tensormesh-production/charts   # requires the repo-creds Secret above
        chart: tensormesh-operator
        targetRevision: 0.1.0
        helm:
          values: |
            engine:
              spec:
                l1:
                  sizeGB: 60
            openshift:
              enabled: {{metadata.labels.openshift}}
      destination:
        server: '{{server}}'
        namespace: tensormesh-operator
      syncPolicy:
        syncOptions: [CreateNamespace=true]
        automated: { prune: true, selfHeal: true }
```

<Tip>
  Label your registered clusters with what they are (`openshift=true`, `gpu=a100`, etc.)
  so the ApplicationSet template can branch on them.
</Tip>

## Verifying a GitOps install

The verification steps in [Install with Helm](/operator/installation/helm#verify) all
apply unchanged — Argo CD and Flux ultimately invoke the same Helm render, so the live
resources look identical to a `helm install`.

## Trade-offs

GitOps is best when:

* Desired state must live in version control (audit, code review on every change).
* The same release needs to roll out to many clusters consistently.
* You want self-healing — drift gets reverted automatically.

Plain `helm install` is faster for one-off clusters, lab environments, and the initial
spike before you formalize a GitOps workflow.

## Next steps

<CardGroup cols={2}>
  <Card title="Helm install reference" icon="ship-wheel" href="/operator/installation/helm">
    Every chart value the GitOps manifests above can override.
  </Card>

  <Card title="OpenShift" icon="circle-nodes" href="/operator/installation/openshift">
    Set `openshift.enabled: true` in your `Application` for OpenShift targets.
  </Card>
</CardGroup>
