mirror of
https://gitlab.kube.huskypup.net/Scooby/Homelabv4.git
synced 2026-08-23 12:56:46 +00:00
global.workhorse.tls.enabled replaced workhorse's plaintext listener
with a TLS-only one on port 8181 - but that port isn't internal-API
-only, it's also what gitlab-web HTTPRoute routes ALL public
gitlab.kube.huskypup.net traffic to. Envoy terminates public HTTPS
and proxies to the pod in plaintext, so the TLS-only listener 400'd
every public request ("Client sent an HTTP request to an HTTPS
server"). Restored live via a direct ConfigMap patch +
rollout restart before this commit could even be pushed, since the
outage took out this repo's own GitLab-hosted git access too.
global.workhorse.host stays (harmless without tls.enabled). Securing
the VPS's future internal-API-over-WAN hop needs a different
mechanism that doesn't collide with the public listener - not solved
here.
420 lines
14 KiB
YAML
420 lines
14 KiB
YAML
# values/gitlab.values.yaml
|
|
# GitLab with Authentik OIDC SSO Integration
|
|
|
|
global:
|
|
hosts:
|
|
domain: kube.huskypup.net
|
|
gitlab:
|
|
name: gitlab.kube.huskypup.net
|
|
registry:
|
|
name: registry.gitlab.kube.huskypup.net
|
|
tls:
|
|
secretName: gitlab-tls
|
|
minio:
|
|
name: minio.gitlab.kube.huskypup.net
|
|
tls:
|
|
secretName: gitlab-tls
|
|
kas:
|
|
name: kas.kube.huskypup.net
|
|
tls:
|
|
secretName: gitlab-tls
|
|
|
|
# Ingress disabled - Istio VirtualServices handle routing
|
|
ingress:
|
|
enabled: false
|
|
configureCertmanager: false # Use cluster-wide cert-manager, not GitLab's
|
|
|
|
# Edition: Community Edition
|
|
edition: ce
|
|
|
|
# Time zone
|
|
time_zone: UTC
|
|
|
|
# Email configuration (configure as needed)
|
|
email:
|
|
from: 'gitlab@kube.huskypup.net'
|
|
display_name: GitLab
|
|
reply_to: 'noreply@kube.huskypup.net'
|
|
|
|
# External PostgreSQL configuration
|
|
# NOTE: PgBouncer service currently has no endpoints (replicas=0),
|
|
# so GitLab is pointed directly at the CNPG primary service.
|
|
psql:
|
|
host: pg-gitlab-rw.gitlab.svc.cluster.local
|
|
port: 5432
|
|
database: gitlabhq_production
|
|
username: app
|
|
password:
|
|
secret: pg-gitlab-app
|
|
key: password
|
|
|
|
# Gitaly configuration - using Praefect for HA
|
|
gitaly:
|
|
enabled: true # Enabled to deploy Gitaly pods
|
|
internal:
|
|
names: [] # No internal Gitaly, using Praefect
|
|
external: [] # Praefect configured below
|
|
# GitLab cross-site replication (see
|
|
# /home/scooby/.claude/plans/jiggly-snacking-iverson.md) - Gitaly's
|
|
# gRPC has no TLS by default. The VPS's 4th node has to be reached
|
|
# over the same public UniFi WAN forward already used for Postgres
|
|
# (confirmed live the direct-Netbird-IP path doesn't accept inbound
|
|
# connections to home, same as the existing etcd quorum) - without
|
|
# this, that WAN hop would carry the gitaly_token,
|
|
# gitlab_shell_secret, and raw repository contents in plaintext.
|
|
# Chart-native support (tls_listen_addr alongside the existing
|
|
# plaintext listener, both stay active) - cert is a real Let's
|
|
# Encrypt cert via the same DNS-01 ClusterIssuer already used
|
|
# everywhere else (gitaly-tls-certificate.yaml), not a self-signed
|
|
# one, so no custom CA needs distributing to either site.
|
|
tls:
|
|
enabled: true
|
|
|
|
# Gitaly's [gitlab] url (the internal-API callback every Gitaly node
|
|
# uses for gitlab-shell hooks) - a real, TLS-supported override,
|
|
# confirmed live via gitlab/charts/gitlab/templates/_workhorse.tpl.
|
|
# Uses the SAME floating-hostname + CoreDNS-local-rewrite pattern
|
|
# already proven for Postgres and Gitaly's own node addresses: home's
|
|
# 3 Gitaly nodes resolve this locally (no WAN round-trip), the VPS's
|
|
# 4th node resolves it via the UniFi WAN forward - one consistent
|
|
# URL for every node regardless of site.
|
|
#
|
|
# tls.enabled REVERTED 2026-08-22 - broke the live site (HTTP 400
|
|
# "Client sent an HTTP request to an HTTPS server" on
|
|
# gitlab.kube.huskypup.net). Root cause: port 8181 is NOT internal-API
|
|
# -only - confirmed live via `kubectl get httproute gitlab-web` that
|
|
# ALL public traffic (gitlab.kube.huskypup.net, routed through Envoy/
|
|
# Istio edge gateway) also targets gitlab-webservice-default:8181.
|
|
# global.workhorse.tls.enabled replaces the plaintext listener with
|
|
# TLS on that SAME port chart-wide, for both the public site AND the
|
|
# internal API - there's no chart-native way to TLS one without the
|
|
# other. Envoy terminates public HTTPS and proxies to the pod in
|
|
# plaintext, so a TLS-only pod listener 400s every public request.
|
|
# host: left in place (harmless without tls.enabled - only used for
|
|
# the [gitlab] url string, not port selection). Internal-API-over-WAN
|
|
# transport security for the VPS's future Gitaly node needs a
|
|
# different mechanism (e.g. network-layer TLS/mTLS via Istio, or a
|
|
# second dedicated port if the chart ever adds one) - not solved here.
|
|
workhorse:
|
|
host: gitlab-internal-api.ha.huskypup.net
|
|
|
|
# Praefect configuration
|
|
praefect:
|
|
enabled: true
|
|
|
|
# Use CNPG database secret
|
|
dbSecret:
|
|
secret: pg-praefect-app
|
|
key: password
|
|
|
|
virtualStorages:
|
|
- name: default
|
|
gitalyReplicas: 3 # Production HA
|
|
maxUnavailable: 1
|
|
# Required once global.gitaly.tls.enabled: true - the chart's own
|
|
# NOTES.txt validation rejects the render without it ("not
|
|
# specified ('default')... not supported", confirmed live).
|
|
# Matches gitlab.gitaly.tls.secret's default name/keys
|
|
# (gitaly-tls-certificate.yaml issues into this exact secret).
|
|
tlsSecretName: gitlab-gitaly-tls
|
|
|
|
# Praefect PostgreSQL configuration
|
|
psql:
|
|
host: pg-praefect-rw.gitlab.svc.cluster.local
|
|
port: 5432
|
|
dbName: praefect_production
|
|
user: app
|
|
|
|
# External Redis configuration - using standalone Redis for writes
|
|
# (replicated Redis service causes READONLY errors from replicas)
|
|
redis:
|
|
host: redis-gitlab-standalone.gitlab.svc.cluster.local
|
|
port: 6379
|
|
auth:
|
|
enabled: true
|
|
secret: redis-gitlab-secret
|
|
key: password
|
|
|
|
# Application Configuration
|
|
appConfig:
|
|
# OmniAuth SSO Configuration
|
|
#
|
|
# CORRECTED 2026-08-21 (second time - see git history for the wrong
|
|
# 2026-08-20 fix that removed this list entirely). This IS the real,
|
|
# actually-processed OIDC config mechanism for the CNG webservice
|
|
# image (chart's gitlab.appConfig.omniauth.configuration template,
|
|
# infra/_omniauth.tpl) - GITLAB_OMNIBUS_CONFIG below is an
|
|
# omnibus-image-only convention this image never processes, so it
|
|
# was always a documentation-only no-op despite looking functional.
|
|
# gitlab-oidc-secret's `provider` key now holds a full YAML-encoded
|
|
# provider block (apps/gitlab/manifests/external-secret-oidc.yaml),
|
|
# loaded via Ruby's YAML.load_file at container start - not raw
|
|
# client_id/secret strings, which is why plain GITLAB_OIDC_CLIENT_ID/
|
|
# SECRET keys alone (yesterday's assumption) were never enough.
|
|
omniauth:
|
|
enabled: true
|
|
allowSingleSignOn: ['openid_connect']
|
|
blockAutoCreatedUsers: false
|
|
autoLinkUser: ['openid_connect']
|
|
syncProfileFromProvider: ['openid_connect']
|
|
syncProfileAttributes: ['email', 'name']
|
|
providers:
|
|
- secret: gitlab-oidc-secret
|
|
key: provider
|
|
|
|
# Settings for Let's Encrypt ACME Issuer - disabled, using cluster-wide cert-manager
|
|
certmanager-issuer:
|
|
email: admin@kube.huskypup.net
|
|
|
|
# Authentik OIDC Configuration via Rails omnibus config
|
|
# Note: Credentials are loaded from gitlab-oidc-secret via environment variables
|
|
|
|
# SAML Configuration via Rails omnibus config
|
|
# Note: SAML provider configuration is loaded from gitlab-saml-secret
|
|
|
|
# PostgreSQL (external via CloudNativePG)
|
|
postgresql:
|
|
install: false
|
|
|
|
# Redis (external)
|
|
redis:
|
|
install: false
|
|
|
|
# PgBouncer connection pooler
|
|
# NOTE: PgBouncer is deployed via CNPG Pooler CRD (see pgbouncer-pooler.yaml)
|
|
# This setting disables GitLab's bundled PgBouncer chart
|
|
pgbouncer:
|
|
enabled: false # Using external CNPG Pooler instead
|
|
|
|
# MinIO for object storage
|
|
minio:
|
|
persistence:
|
|
storageClass: rook-ceph-block
|
|
size: 100Gi # Production storage
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 512Mi
|
|
limits:
|
|
memory: 2Gi
|
|
|
|
# Container Registry - enabled with S3 storage
|
|
registry:
|
|
enabled: true
|
|
hpa:
|
|
minReplicas: 1
|
|
maxReplicas: 1
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 128Mi
|
|
limits:
|
|
memory: 1Gi
|
|
|
|
# GitLab components
|
|
gitlab:
|
|
# GitLab Webservice - Main application
|
|
webservice:
|
|
minReplicas: 2
|
|
maxReplicas: 3
|
|
workerProcesses: 3
|
|
|
|
# Note: hostAliases for OIDC SSL validation are applied via helmfile postsync hook
|
|
# (GitLab chart doesn't support hostAliases in values.yaml)
|
|
|
|
extraEnvFrom:
|
|
GITLAB_OIDC_CLIENT_ID:
|
|
secretKeyRef:
|
|
name: gitlab-oidc-secret
|
|
key: GITLAB_OIDC_CLIENT_ID
|
|
GITLAB_OIDC_CLIENT_SECRET:
|
|
secretKeyRef:
|
|
name: gitlab-oidc-secret
|
|
key: GITLAB_OIDC_CLIENT_SECRET
|
|
GITLAB_SAML_IDP_FINGERPRINT:
|
|
secretKeyRef:
|
|
name: gitlab-saml-secret
|
|
key: GITLAB_SAML_IDP_FINGERPRINT
|
|
GITLAB_SAML_IDP_SSO_URL:
|
|
secretKeyRef:
|
|
name: gitlab-saml-secret
|
|
key: GITLAB_SAML_IDP_SSO_URL
|
|
extraEnv:
|
|
GITLAB_OMNIBUS_CONFIG: |
|
|
# Authentik OIDC Configuration
|
|
gitlab_rails['omniauth_enabled'] = true
|
|
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect', 'saml']
|
|
gitlab_rails['omniauth_block_auto_created_users'] = false
|
|
gitlab_rails['omniauth_auto_link_user'] = ['openid_connect', 'saml']
|
|
gitlab_rails['omniauth_auto_sign_in_with_provider'] = nil
|
|
gitlab_rails['omniauth_sync_profile_from_provider'] = ['openid_connect', 'saml']
|
|
gitlab_rails['omniauth_sync_profile_attributes'] = ['email', 'name']
|
|
|
|
gitlab_rails['omniauth_providers'] = [
|
|
{
|
|
'name' => 'openid_connect',
|
|
'label' => 'Authentik',
|
|
'args' => {
|
|
'name' => 'openid_connect',
|
|
'scope' => ['openid', 'profile', 'email'],
|
|
'response_type' => 'code',
|
|
'issuer' => 'https://auth.kube.huskypup.net/application/o/gitlab/',
|
|
'discovery' => true,
|
|
'client_auth_method' => 'query',
|
|
'uid_field' => 'sub',
|
|
'send_scope_to_token_endpoint' => true,
|
|
'pkce' => true,
|
|
'client_options' => {
|
|
'identifier' => ENV['GITLAB_OIDC_CLIENT_ID'],
|
|
'secret' => ENV['GITLAB_OIDC_CLIENT_SECRET'],
|
|
'redirect_uri' => 'https://gitlab.kube.huskypup.net/users/auth/openid_connect/callback'
|
|
}
|
|
}
|
|
},
|
|
{
|
|
'name' => 'saml',
|
|
'label' => 'Authentik SAML',
|
|
'args' => {
|
|
'assertion_consumer_service_url' => 'https://gitlab.kube.huskypup.net/users/auth/saml/callback',
|
|
'idp_cert_fingerprint' => ENV['GITLAB_SAML_IDP_FINGERPRINT'],
|
|
'idp_sso_target_url' => ENV['GITLAB_SAML_IDP_SSO_URL'],
|
|
'issuer' => 'https://gitlab.kube.huskypup.net',
|
|
'name_identifier_format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
|
|
'attribute_statements' => {
|
|
'email' => ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'],
|
|
'name' => ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'],
|
|
'first_name' => ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'],
|
|
'last_name' => ['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname']
|
|
}
|
|
}
|
|
}
|
|
]
|
|
# Homelab resource allocation
|
|
resources:
|
|
requests:
|
|
cpu: 300m
|
|
memory: 2Gi
|
|
limits:
|
|
memory: 4Gi
|
|
|
|
# GitLab KAS (Kubernetes Agent Server) - enabled for Kubernetes cluster integration
|
|
kas:
|
|
enabled: true
|
|
minReplicas: 1
|
|
maxReplicas: 1
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
|
|
# Gitaly Cluster (Praefect) - High Availability Git storage
|
|
gitaly:
|
|
# Note: enabled is in global.gitaly
|
|
persistence:
|
|
storageClass: rook-ceph-block
|
|
size: 200Gi # Production storage
|
|
# Production resources
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 512Mi
|
|
limits:
|
|
cpu: "1"
|
|
memory: 2Gi
|
|
|
|
# GitLab Runner - enabled for CI/CD
|
|
gitlab-runner:
|
|
install: false # Will be installed separately
|
|
|
|
# Praefect - Gitaly Cluster routing and transaction manager
|
|
praefect:
|
|
enabled: true
|
|
minReplicas: 1
|
|
maxReplicas: 1
|
|
|
|
# Note: Praefect PostgreSQL config is in global.praefect.psql
|
|
|
|
# Use CNPG-generated database secret
|
|
dbSecret:
|
|
secret: pg-praefect-app
|
|
key: password
|
|
|
|
# Resources
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 256Mi
|
|
limits:
|
|
cpu: 250m
|
|
memory: 512Mi
|
|
|
|
# (dead config removed 2026-08-22: this virtualStorages block never
|
|
# actually did anything - confirmed live the chart's Praefect
|
|
# ConfigMap template iterates global.praefect.virtualStorages, not
|
|
# this one, so gitalyReplicas: 3 up there always won regardless of
|
|
# what this said. See global.praefect.virtualStorages above for the
|
|
# real config.)
|
|
#
|
|
# GitLab cross-site replication (see
|
|
# /home/scooby/.claude/plans/jiggly-snacking-iverson.md): tried a
|
|
# values-only CONFIG_TEMPLATE_DIRECTORY redirect (extraEnv +
|
|
# extraVolumes/extraVolumeMounts) to add a VPS-hosted Gitaly node the
|
|
# chart has no mechanism to register - confirmed live this doesn't
|
|
# work: extraVolumeMounts and extraEnv both render correctly, but
|
|
# extraVolumes is a dead values key for THIS subchart specifically -
|
|
# charts/gitlab/charts/praefect/templates/statefulset.yaml's own
|
|
# volumes: list never calls the gitlab.extraVolumes helper at all
|
|
# (only volumeMounts does), so the mount has nothing to mount and the
|
|
# pod would fail to schedule. No values-only fix exists.
|
|
#
|
|
# Real fix: argocd-apps/apps/gitlab.yaml's ignoreDifferences now
|
|
# covers ConfigMap gitlab-praefect's `data` field, so Helm creates
|
|
# the object (with its own 3-node content) but ArgoCD stops
|
|
# reconciling its content afterward. The actual multi-node content
|
|
# lives in apps/gitlab/manifests/praefect-ha-configmap.yaml as a
|
|
# git-tracked reference/documentation copy (deployed under its own
|
|
# name, praefect-ha-config, harmless and otherwise unused) - the
|
|
# live gitlab-praefect ConfigMap gets kubectl-patched with that same
|
|
# content directly, same "documented but manually-applied"
|
|
# convention as every other cross-cluster secret in this plan.
|
|
|
|
# GitLab Exporter for Prometheus metrics
|
|
gitlab-exporter:
|
|
enabled: true
|
|
metrics:
|
|
enabled: true
|
|
|
|
# Sidekiq background jobs
|
|
sidekiq:
|
|
minReplicas: 1
|
|
maxReplicas: 1
|
|
|
|
# Note: hostAliases applied via helmfile postsync hook
|
|
|
|
# Homelab resources
|
|
resources:
|
|
requests:
|
|
cpu: 25m
|
|
memory: 512Mi
|
|
limits:
|
|
cpu: 250m
|
|
memory: 2Gi
|
|
|
|
# Disable components we already have in the cluster
|
|
certmanager:
|
|
install: false # Using cluster-wide cert-manager
|
|
installCRDs: false
|
|
|
|
prometheus:
|
|
install: false # Using existing Prometheus
|
|
|
|
nginx-ingress:
|
|
enabled: false # Istio handles ingress
|
|
|
|
# Disable GitLab Runner (configure separately if needed)
|
|
gitlab-runner:
|
|
install: false
|