This repository contains a complete Kubernetes GitOps setup for Immich, including:
- Immich application
- Postgres (with SealedSecrets for credentials)
- Redis (standalone with authentication via SealedSecrets)
- NFS-based persistent storage
- GPU scheduling for ML pods
- Traefik ingress with self-signed TLS via cert-manager
- Staging & Production environments
- FluxCD and ArgoCD GitOps manifests
- Optional pure Kustomize deployment
kubectl apply -n argocd kubectl apply -n argocd \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yamlCert Manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.2/cert-manager.yaml kubectl create secret generic immich-postgres-user \
--from-literal=username=jetri \
--from-literal=password=Angels03! \
--namespace immich-production \
--dry-run=client -o yaml \
| kubeseal --controller-namespace=sealed-secrets --controller-name=sealed-secrets -o yaml > environments/staging/sealed/db-sealed.yamlimmich-gitops/
├── charts/immich-stack/ # All-in-one Helm chart
├── environments/
│ ├── staging/ # Staging namespace, values, certs, sealed secrets
│ └── production/ # Production namespace, values, certs, sealed secrets
├── flux/ # FluxCD HelmRelease and source configs
├── argocd/ # ArgoCD Application definitions
└── README.md # This file
- Install FluxCD:
curl -s https://fluxcd.io/install.sh | sudo bash
flux install- Add this repo as a Flux Git source:
flux create source git immich-gitops \
--url=https://github.com/YOUR_USER/immich-gitops \
--branch=main- Apply the environment:
kubectl apply -f environments/staging/kustomization.yaml
kubectl apply -f flux/- Install ArgoCD:
kubectl create namespace argocd
kubectl apply -n argocd \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml- Apply the Application manifest:
kubectl apply -f argocd/app-staging.yaml- Sync in the ArgoCD UI.
For quick manual deploys without GitOps:
kubectl apply -k environments/staging
helm upgrade --install immich charts/immich-stack \
--namespace immich-staging \
-f environments/staging/values-staging.yamlAll DB and Redis credentials are stored as SealedSecrets Encrypted using your provided SealedSecrets controller public key
To rotate credentials:
kubectl create secret generic immich-postgres-user \
--from-literal=username=newuser \
--from-literal=password=newpass \
--namespace immich-staging \
--dry-run=client -o yaml \
| kubeseal --controller-namespace=sealed-secrets --controller-name=sealed-secrets -o yaml > environments/staging/sealed/db-sealed.yaml- NFS server: 192.168.18.96
- Export path: /mnt/cluster/nfs
- PVCs: immich-library-pvc, immich-mlcache-pvc
ML pods run only on GPU nodes:
nodeSelector:
gpu: "true"- Using self-signed TLS via cert-manager ClusterIssuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-cluster-issuer
spec:
selfSigned: {}- Check pods:
kubectl get pods -n immich-staging- Describe ingress:
kubectl describe ingress immich -n immich-staging- Logs:
kubectl logs deploy/immich -n immich-staging✅ With this, your repo is 100% complete — you can now create it locally by copying the files I’ve given into immich-gitops/ and running:
zip -r immich-gitops.zip immich-gitops/