skills/harbor-argocd-deployment/SKILL.md
Deploy Harbor container registry via ArgoCD Helm (chart harbor/harbor). Use when: (1) harbor-nginx or harbor-portal pods crash with 'exec format error' on mixed-arch clusters, (2) harbor-core stuck ContainerCreating with 'references non-existent secret key: secretKey', (3) ArgoCD shows perpetual OutOfSync due to harbor-core/jobservice/registry/registry-htpasswd Secrets or Deployment checksum annotations changing on every sync.
npx skillsauth add aldengolab/lorist harbor-argocd-deploymentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Several non-obvious issues arise when deploying the Harbor Helm chart (v1.18+) via ArgoCD on a mixed-architecture Kubernetes cluster.
Harbor images (nginx-photon, portal) are amd64-only. The chart uses per-component nodeSelectors — there is no top-level nodeSelector:
nginx:
nodeSelector:
kubernetes.io/arch: amd64
portal:
nodeSelector:
kubernetes.io/arch: amd64
core:
nodeSelector:
kubernetes.io/arch: amd64
jobservice:
nodeSelector:
kubernetes.io/arch: amd64
registry:
nodeSelector:
kubernetes.io/arch: amd64
trivy:
nodeSelector:
kubernetes.io/arch: amd64
database:
internal:
nodeSelector:
kubernetes.io/arch: amd64
redis:
internal:
nodeSelector:
kubernetes.io/arch: amd64
exporter:
nodeSelector:
kubernetes.io/arch: amd64
harbor-core mounts the secret specified by existingSecretSecretKey
and always looks for a key literally named secretKey inside it.
If your secret only has an uppercase key (e.g. HARBOR_SECRET_KEY),
the pod will be stuck ContainerCreating with:
MountVolume.SetUp failed: references non-existent secret key: secretKey
Fix: add an alias entry in the ExternalSecret that maps your Doppler/vault
key to secretKey:
- secretKey: secretKey
remoteRef:
key: HARBOR_SECRET_KEY
Harbor generates random values for internal secrets (CSRF_KEY,
JOBSERVICE_SECRET, REGISTRY_HTTP_SECRET, REGISTRY_HTPASSWD) on every
Helm render. This causes perpetual OutOfSync in ArgoCD. Add
ignoreDifferences to the Application:
ignoreDifferences:
- group: ""
kind: Secret
namespace: harbor
name: harbor-core
jsonPointers: ["/data"]
- group: ""
kind: Secret
namespace: harbor
name: harbor-jobservice
jsonPointers: ["/data"]
- group: ""
kind: Secret
namespace: harbor
name: harbor-registry
jsonPointers: ["/data"]
- group: ""
kind: Secret
namespace: harbor
name: harbor-registry-htpasswd
jsonPointers: ["/data"]
- group: apps
kind: Deployment
namespace: harbor
jqPathExpressions:
- .spec.template.metadata.annotations["checksum/secret"]
- .spec.template.metadata.annotations["checksum/secret-core"]
- .spec.template.metadata.annotations["checksum/secret-jobservice"]
argocd app get harbor shows Synced + Healthyexpose.loadBalancer section does not support
loadBalancerClass. See k8s-helm-immutable-field-workaround skill for
the workaround.ignoreDifferences only suppresses the UI diff; ArgoCD will NOT
overwrite the live secret values, which is the desired behavior
(preserves secrets set on first install).development
Build a UEFI Secure Boot PXE netboot server for Ubuntu autoinstall. Use when: designing or implementing network boot infrastructure for automated Ubuntu provisioning with Secure Boot enabled. Covers the complete chain: signed shim+GRUB selection, TFTP layout, kernel parameters, autoinstall config requirements, and post-install bootstrapping scripts. Also applicable when debugging an existing PXE setup that uses the wrong GRUB binary or config paths.
development
Design pattern for running a persistent PXE/TFTP server that safely coexists with already-installed nodes. Use when: building PXE infrastructure that should stay always-on, designing automated bare-metal provisioning in GitOps/Kubernetes environments, or any PXE setup where UEFI boot order has network boot first. Eliminates boot loops without requiring UEFI firmware changes.
development
This skill governs all prose output — Claude's own responses, documentation, PR descriptions, commit messages, README content, comments, and any text the user asks to draft or edit. It should also be used when the user asks to "review my writing", "edit this for clarity", "make this clearer", "simplify this text", "rewrite this", "check my prose", "tighten this up", or "make this more concise". Based on George Orwell's "Politics and the English Language" (1946).
development
Debug Kubernetes pods using hostNetwork: true that crash with "Address already in use" or "failed to create listening socket for port N". Use when: (1) a hostNetwork pod container is in CrashLoopBackOff and logs show a port bind failure, (2) the port works fine in non-hostNetwork pods but fails with hostNetwork, (3) you need to identify which host-level process holds a port from within Kubernetes (no SSH). Covers /proc/net/udp inspection and kubectl debug node with nsenter.