Homelab GitOps
Argo CD is the only component that deploys the resources in this repository. Application CI publishes immutable container images and then commits the selected image tag here; it never receives Kubernetes credentials.
Repository layout
apps/immich-sync/is the desired Kubernetes state for Immich Share Sync.bootstrap/contains the Argo CD project and Application that point back to this repository.scripts/update-immich-sync-image.shis the single image-promotion interface used by CI.
The only canonical Immich Share Sync image version is images[0].newTag in
apps/immich-sync/kustomization.yaml. The resource manifest deliberately omits a tag, and Kustomize supplies the
immutable full Git SHA while rendering.
First-time setup
The cluster already runs Argo CD in the argocd namespace and exposes its UI at https://cd.brunner.ninja.
-
Push this repository so Argo CD can read its public HTTPS URL.
-
Configure the
immich-syncrepository's cross-repository token as described below. -
Review the rendered workload:
kubectl kustomize apps/immich-sync -
Record the existing persistent volume before the first synchronization:
kubectl --namespace default get pvc immich-sync-stats \ -o jsonpath='{.metadata.uid}{"|"}{.spec.volumeName}{"\n"}' -
Bootstrap the Argo CD resources:
./bootstrap/install.sh -
Inspect the result in the UI or CLI:
argocd app get immich-sync argocd app diff immich-sync kubectl --namespace default rollout status deployment/immich-sync kubectl --namespace default get deployment immich-sync \ -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -
Confirm that the PVC UID and volume name are unchanged. Only after Argo CD reports the application
SyncedandHealthy, remove the obsolete CI deployer and delete the oldKUBE_CONFIG_BASE64secret from Gitea:kubectl --namespace default delete rolebinding/immich-sync-deployer \ role/immich-sync-deployer serviceaccount/immich-sync-deployer \ secret/immich-sync-deployer-token
The bootstrap Application enables automatic synchronization, pruning, and self-healing. Consequently, direct edits
to its managed Kubernetes resources are reverted to Git. Change Git when experimenting, observe OutOfSync, and then
watch Argo CD return the application to Synced and Healthy.
Give Immich Share Sync CI permission to promote images
The built-in Gitea Actions job token cannot write to another repository. Create a dedicated bot account, for example
gitops-promoter, add it to feedc0de/homelab-gitops with repository Write permission, and create a personal
access token for that account with only the write:repository scope.
In feedc0de/immich-sync, open Settings → Actions → Secrets and create GITOPS_TOKEN containing that token. The
workflow passes it directly to actions/checkout while checking out this repository; the checkout action configures
authenticated HTTPS for the final git push without placing the token in a committed URL.
The main-branch workflow now performs this sequence:
- Build and push
registry.brunner.ninja/feedc0de/immich-sync:<source SHA>. - Verify that the completed build still belongs to the current
maincommit. - Update
apps/immich-sync/kustomization.yamlwith that SHA. - Commit and push the promotion to this repository.
- Let Argo CD detect and synchronize the Git commit.
For a personal token owned by feedc0de, write:repository also applies to other repositories that account can
write. A dedicated bot restricted to this one repository therefore gives the token a meaningfully smaller blast
radius.
Manual recovery path
Argo CD is the normal deployment mechanism. If it is unavailable, apps/immich-sync/install.sh renders, performs a
server-side dry-run, applies the same Kustomize source, and waits for the Deployment rollout. A later Argo CD refresh
will see the same desired resources.