Refactor Harbor deployment to follow project structure pattern

Move Helm chart configuration from inline values in app-harbor.yaml to
separate files in apps/harbor/ subdirectory, following the same pattern
as forgejo and other apps.

Changes:
- Create apps/harbor/Chart.yaml defining dependency on Harbor Helm chart
- Create apps/harbor/values.yaml with all Helm values configuration
- Update app-harbor.yaml to use git path source instead of direct Helm chart
- Add apps/harbor/README.md documenting OIDC setup procedure

OIDC authentication must be configured via Harbor UI after deployment,
as the Helm chart does not support OIDC configuration at deployment time.
The README provides step-by-step instructions for Pocket ID integration.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
CTO Agent 2026-07-18 14:02:31 +00:00
parent daa8112e27
commit 60dc1ac0a0
4 changed files with 180 additions and 115 deletions

View file

@ -6,124 +6,12 @@ metadata:
spec: spec:
project: default project: default
source: source:
repoURL: https://helm.goharbor.io repoURL: git@forgejo.forgejo.svc.cluster.local:basicstack/stack.basicstack.de.git
chart: harbor targetRevision: main
targetRevision: 1.16.1 path: apps/harbor
helm:
valuesObject:
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: harbor.basicstack.de
className: traefik
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
externalURL: https://harbor.basicstack.de
persistence:
enabled: true
resourcePolicy: keep
persistentVolumeClaim:
registry:
storageClass: hcloud-volumes-encrypted
size: 50Gi
database:
storageClass: hcloud-volumes-encrypted
size: 10Gi
redis:
storageClass: hcloud-volumes-encrypted
size: 5Gi
trivy:
storageClass: hcloud-volumes-encrypted
size: 5Gi
jobservice:
jobLog:
storageClass: hcloud-volumes-encrypted
size: 5Gi
# Use internal PostgreSQL and Redis
database:
type: internal
internal:
existingSecret: harbor-secrets
redis:
type: internal
# Harbor admin credentials
existingSecretAdminPassword: harbor-secrets
existingSecretAdminPasswordKey: harborAdminPassword
# Enable OIDC authentication
authMode: oidc_auth
oidc:
name: PocketID
endpoint: https://auth.basicstack.de
clientId: harbor
clientSecret: "" # Will be loaded from secret
groupsClaim: groups
adminGroup: admins
scope: openid,profile,email,groups
autoOnboard: true
userClaim: email
verifyCert: true
existingSecretOIDC: harbor-secrets
existingSecretOIDCKey: oidc.clientSecret
# Resource limits
core:
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 1Gi
cpu: 1000m
portal:
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 256Mi
cpu: 500m
registry:
registry:
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 1Gi
cpu: 1000m
trivy:
enabled: true
resources:
requests:
memory: 512Mi
cpu: 200m
limits:
memory: 2Gi
cpu: 1000m
destination: destination:
server: https://kubernetes.default.svc server: https://kubernetes.default.svc
namespace: harbor namespace: harbor
syncPolicy: syncPolicy:
syncOptions: syncOptions:
- CreateNamespace=true - CreateNamespace=true
automated:
prune: false
selfHeal: true

11
apps/harbor/Chart.yaml Normal file
View file

@ -0,0 +1,11 @@
apiVersion: v2
name: harbor
description: Harbor container registry deployment for BasicStack
type: application
version: 1.0.0
appVersion: "2.12.1"
dependencies:
- name: harbor
version: 1.16.1
repository: https://helm.goharbor.io

71
apps/harbor/README.md Normal file
View file

@ -0,0 +1,71 @@
# Harbor Container Registry
Harbor is deployed at https://harbor.basicstack.de
## Initial Access
The initial admin credentials are stored in the `harbor-secrets` sealed secret:
- Username: `admin`
- Password: Retrieved from secret key `harborAdminPassword`
## OIDC Authentication Setup
Harbor requires OIDC to be configured via the web UI or API after initial deployment. The Helm chart does not support OIDC configuration at deployment time.
### Steps to Configure Pocket ID OIDC
1. **Create OIDC Client in Pocket ID**
- Navigate to https://auth.basicstack.de
- Create a new client with these settings:
- Client ID: `harbor`
- Redirect URIs: `https://harbor.basicstack.de/c/oidc/callback`
- Scopes: `openid`, `profile`, `email`, `groups`
- Save the client secret
2. **Configure OIDC in Harbor**
- Log in to Harbor as admin: https://harbor.basicstack.de
- Navigate to: **Administration****Configuration** → **Authentication**
- Select **OIDC** as the authentication mode
- Fill in the following:
- **OIDC Provider Name**: `PocketID`
- **OIDC Endpoint**: `https://auth.basicstack.de`
- **OIDC Client ID**: `harbor`
- **OIDC Client Secret**: (paste the secret from Pocket ID)
- **Group Claim Name**: `groups`
- **OIDC Admin Group**: `admins`
- **OIDC Scope**: `openid,profile,email,groups`
- **Verify Certificate**: ✓ (enabled)
- **Automatic onboarding**: ✓ (enabled)
- **Username Claim**: `email`
- Click **Test OIDC Server** to verify connectivity
- Click **Save** to apply the configuration
3. **Test OIDC Login**
- Log out of Harbor
- Return to the Harbor login page
- You should now see a "Login via OIDC Provider" button
- Click it to authenticate via Pocket ID
### Reference Documentation
- Harbor OIDC Configuration: https://goharbor.io/docs/2.12.0/administration/configure-authentication/oidc-auth/
- Pocket ID Harbor Example: https://pocket-id.org/docs/client-examples/harbor
## Storage
Harbor uses encrypted Hetzner Cloud volumes for persistence:
- Registry data: 50Gi
- PostgreSQL database: 10Gi
- Redis cache: 5Gi
- Trivy vulnerability database: 5Gi
- Job service logs: 5Gi
All PVCs are configured with `resourcePolicy: keep` to prevent data loss during upgrades.
## Architecture
- **Ingress**: Traefik with Let's Encrypt TLS certificates
- **Database**: Internal PostgreSQL
- **Cache**: Internal Redis
- **Vulnerability Scanning**: Trivy enabled
- **Authentication**: OIDC via Pocket ID (after manual configuration)

95
apps/harbor/values.yaml Normal file
View file

@ -0,0 +1,95 @@
harbor:
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: harbor.basicstack.de
className: traefik
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
externalURL: https://harbor.basicstack.de
persistence:
enabled: true
resourcePolicy: keep
persistentVolumeClaim:
registry:
storageClass: hcloud-volumes-encrypted
size: 50Gi
database:
storageClass: hcloud-volumes-encrypted
size: 10Gi
redis:
storageClass: hcloud-volumes-encrypted
size: 5Gi
trivy:
storageClass: hcloud-volumes-encrypted
size: 5Gi
jobservice:
jobLog:
storageClass: hcloud-volumes-encrypted
size: 5Gi
# Use internal PostgreSQL and Redis
database:
type: internal
internal:
existingSecret: harbor-secrets
redis:
type: internal
# Harbor admin credentials
existingSecretAdminPassword: harbor-secrets
existingSecretAdminPasswordKey: harborAdminPassword
# OIDC authentication via Pocket ID
# Note: Harbor requires database_auth to be configured first, then OIDC can be added via UI
# See: https://goharbor.io/docs/2.12.0/administration/configure-authentication/oidc-auth/
# Resource limits
core:
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 1Gi
cpu: 1000m
portal:
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 256Mi
cpu: 500m
registry:
registry:
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 1Gi
cpu: 1000m
trivy:
enabled: true
resources:
requests:
memory: 512Mi
cpu: 200m
limits:
memory: 2Gi
cpu: 1000m