From 5a008ffa0803eb33b2dc21d58d19b5b8ee3c3560 Mon Sep 17 00:00:00 2001 From: Mukul Sharma Date: Thu, 17 Sep 2026 08:44:57 +0530 Subject: [PATCH] Serve Harbor on the real domain as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A standalone Ingress because Harbor's chart cannot express a second host: expose.ingress.hosts.core is a single scalar, with no extraHosts like argo-cd and no secondaryingress like jenkins. The chart's own Ingress is untouched and keeps serving the nip.io name with its private-CA certificate; both names reach the same backends. The path split is load-bearing and was copied from this cluster's own generated Ingress rather than written from memory: /api/, /service/, /v2/ and /c/ go to harbor-core, everything else to harbor-portal. harbor-core is the API, auth and registry backend; harbor-portal is only the web UI. Sending /v2/ to the portal breaks every image pull, and it fails looking like an authentication problem rather than a routing one. What this deliberately does not do is make the new name primary. Harbor still advertises the nip.io address: externalURL is a single value handed to docker clients in Harbor's own API responses, so the UI may redirect there and a docker login against this hostname is issued a token endpoint pointing at the old one. Both resolve, so it works. Moving externalURL means moving every image reference in the cluster at the same time — running deployments, the dockerconfigjson auths key, toolshed's registry settings and its stored connection — which is its own change, not a line in this one. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N --- .../harbor-ingress-deployshed.yaml | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 extra-manifests/harbor-ingress-deployshed.yaml diff --git a/extra-manifests/harbor-ingress-deployshed.yaml b/extra-manifests/harbor-ingress-deployshed.yaml new file mode 100644 index 0000000..5f5a748 --- /dev/null +++ b/extra-manifests/harbor-ingress-deployshed.yaml @@ -0,0 +1,85 @@ +# Harbor's hostname on the real domain, with a public certificate. +# +# A standalone Ingress because Harbor's chart has no multi-host mechanism at +# all — no extraHosts like argo-cd, no secondaryingress like jenkins. Its +# expose.ingress.hosts.core is a single scalar, so the only way to serve a +# second name is a second object. Checked against the chart, not assumed. +# +# The chart's own Ingress is untouched and keeps serving +# harbor.35.238.248.203.nip.io with its private-CA certificate. Both names +# route to the same backends. +# +# THE PATH SPLIT IS LOAD-BEARING. harbor-core is the API, auth and registry +# backend; harbor-portal is only the web UI. Mirrored from this cluster's own +# generated Ingress (read from the live object, not copied blind): /api/, +# /service/, /v2/ and /c/ go to core, everything else to the portal. Sending +# /v2/ to the portal instead breaks every image pull, and it fails looking +# like an authentication problem rather than a routing one. +# +# Contour matches the longest prefix, so the trailing / rule cannot shadow +# the four above it regardless of order — they are written first anyway, so +# the intent is obvious to whoever reads this next. +# +# WHAT THIS DOES NOT DO: Harbor still advertises the nip.io address. +# externalURL is a single value handed to docker clients in Harbor's own API +# responses, so the UI may redirect there and a docker login against this +# hostname is issued a token endpoint pointing at the old one. Both names +# resolve, so it works — but this name is not truly primary until +# externalURL moves, and that cannot happen until every image reference in +# the cluster moves with it. That is the nip.io removal, done deliberately +# and on its own. +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: harbor-ingress-deployshed + namespace: harbor + annotations: + # A real certificate, unlike the chart's Ingress beside it: that one + # serves a nip.io name, which Let's Encrypt cannot issue for, and is + # signed by the private CA the node pool was told to trust instead. + cert-manager.io/cluster-issuer: letsencrypt-prod +spec: + ingressClassName: contour + tls: + - hosts: + - harbor.infra.deployshed.com + secretName: harbor-deployshed-tls + rules: + - host: harbor.infra.deployshed.com + http: + paths: + - path: /api/ + pathType: Prefix + backend: + service: + name: harbor-core + port: + number: 80 + - path: /service/ + pathType: Prefix + backend: + service: + name: harbor-core + port: + number: 80 + - path: /v2/ + pathType: Prefix + backend: + service: + name: harbor-core + port: + number: 80 + - path: /c/ + pathType: Prefix + backend: + service: + name: harbor-core + port: + number: 80 + - path: / + pathType: Prefix + backend: + service: + name: harbor-portal + port: + number: 80