# Product-neutral object names (RAPPS-WP-0019). The upstream chart is named # 'gitea'; these overrides keep that legacy name out of live objects. The data # volume keeps its existing claim name; renaming it needs a data copy. fullnameOverride: forge nameOverride: forge # Non-secret Forgejo Helm values (gitea-charts/gitea chart + Forgejo image). # Layer helm/forgejo-secrets.sops.yaml for database password and admin credentials. # Recreate avoids leveldb queue lock fights on the shared RWO PVC during upgrades. strategy: type: Recreate # Main Forgejo container sizing (FORGE-WP-0011, CUST-WP-0071, RESOURCE-WP-0008). # Evidence 2026-10-21 (7d): CPU p95 133-160m, peak ~1030m; memory working set # p95 ~956Mi, per-pod peak 1252Mi, RSS peak 500Mi; no OOM events. # Request = p95 rule (200m / 1104Mi). Memory limit 1536Mi = 1.23x working-set # peak and ~3x RSS peak (the rest is reclaimable page cache). No CPU limit: # bursts to ~1 core are normal for git pack/clone work and must not throttle. resources: requests: cpu: 200m memory: 1104Mi limits: memory: 1536Mi service: http: type: ClusterIP image: registry: code.forgejo.org repository: forgejo/forgejo tag: "11.0.3" rootless: true persistence: enabled: true claimName: gitea-shared-storage size: 10Gi postgresql: enabled: false postgresql-ha: enabled: false redis-cluster: enabled: false valkey-cluster: enabled: false # File subPath keeps Git from copying ConfigMap projection symlinks. extraVolumes: - name: secret-scan-template configMap: name: forgejo-secret-template-d1df801be39f defaultMode: 365 extraContainerVolumeMounts: - &id001 name: secret-scan-template mountPath: /opt/forge-secret-template/hooks/pre-receive.d/10-custodian-secret-scan subPath: hook readOnly: true extraInitVolumeMounts: - *id001 # Verify admitted scanner custody after Kubernetes fsGroup volume processing. # Only the existing security subtree is mounted; no credentials are needed. preExtraInitContainers: - name: verify-secret-scanner image: code.forgejo.org/forgejo/forgejo@sha256:691657c7e64af7730a2e885e6d022cf16ae60724931c5392bd61838afadcaeba imagePullPolicy: IfNotPresent command: - sh - -c - "#!/bin/sh\nset +vx\nset -eu\ntest \"$(id -u)\" = 1000\ntest -d /data && test ! -L /data\ntest -d /data/security && test ! -L /data/security\ntest -d /data/security/receive-secret-scan && test ! -L /data/security/receive-secret-scan\ntest -d /data/security/receive-secret-scan/20261012-57a0642b6251 && test ! -L /data/security/receive-secret-scan/20261012-57a0642b6251\ntest -f /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan && test ! -L /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan\ntest \"$(stat -c %u /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan)\" = 1000\ntest \"$(sha256sum /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan | cut -d \" \" -f 1)\" = 57a0642b625105440fe146fceb4d244fd2dd08a75beb316831675643e6cc27ec\ncase \"$(stat -c %a /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan)\" in 755|775) ;; *) exit 21;; esac\ntest -f /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks && test ! -L /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks\ntest \"$(stat -c %u /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks)\" = 1000\ntest \"$(sha256sum /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks | cut -d \" \" -f 1)\" = 88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509\ncase \"$(stat -c %a /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks)\" in 755|775) ;; *) exit 21;; esac\nif [ \"${1:-check}\" = apply ]; then\n chmod 755 /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan\n test \"$(stat -c %a /data/security/receive-secret-scan/20261012-57a0642b6251/receive-secret-scan)\" = 755\n chmod 755 /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks\n test \"$(stat -c %a /data/security/receive-secret-scan/20261012-57a0642b6251/gitleaks)\" = 755\nfi\n\n#!/bin/sh\nset +vx\nset -eu\ntest \"$(id -u)\" = 1000\ntest -d /data && test ! -L /data\ntest -d /data/security && test ! -L /data/security\ntest -d /data/security/receive-secret-scan && test ! -L /data/security/receive-secret-scan\ntest -d /data/security/receive-secret-scan/20261018-73ee04078786 && test ! -L /data/security/receive-secret-scan/20261018-73ee04078786\ntest -f /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan && test ! -L /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan\ntest \"$(stat -c %u /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan)\" = 1000\ntest \"$(sha256sum /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan | cut -d \" \" -f 1)\" = 73ee04078786801fc74d80d2bef122b7764c93856e403e8de5b078336d7f9e1a\ncase \"$(stat -c %a /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan)\" in 755|775) ;; *) exit 21;; esac\ntest -f /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks && test ! -L /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks\ntest \"$(stat -c %u /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks)\" = 1000\ntest \"$(sha256sum /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks | cut -d \" \" -f 1)\" = 88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509\ncase \"$(stat -c %a /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks)\" in 755|775) ;; *) exit 21;; esac\nif [ \"${1:-check}\" = apply ]; then\n chmod 755 /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan\n test \"$(stat -c %a /data/security/receive-secret-scan/20261018-73ee04078786/receive-secret-scan)\" = 755\n chmod 755 /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks\n test \"$(stat -c %a /data/security/receive-secret-scan/20261018-73ee04078786/gitleaks)\" = 755\nfi\n\n#!/bin/sh\nset +vx\nset -eu\ntest \"$(id -u)\" = 1000\ntest -d /data && test ! -L /data\ntest -d /data/security && test ! -L /data/security\ntest -d /data/security/receive-secret-scan && test ! -L /data/security/receive-secret-scan\ntest -d /data/security/receive-secret-scan/20261027-b735d052a49f && test ! -L /data/security/receive-secret-scan/20261027-b735d052a49f\ntest -f /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan && test ! -L /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan\ntest \"$(stat -c %u /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan)\" = 1000\ntest \"$(sha256sum /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan | cut -d \" \" -f 1)\" = b735d052a49fc8e9cca14cddee074c5429352ad71841eb6548459294f15683a2\ncase \"$(stat -c %a /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan)\" in 755|775) ;; *) exit 21;; esac\ntest -f /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks && test ! -L /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks\ntest \"$(stat -c %u /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks)\" = 1000\ntest \"$(sha256sum /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks | cut -d \" \" -f 1)\" = 88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509\ncase \"$(stat -c %a /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks)\" in 755|775) ;; *) exit 21;; esac\nif [ \"${1:-check}\" = apply ]; then\n chmod 755 /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan\n test \"$(stat -c %a /data/security/receive-secret-scan/20261027-b735d052a49f/receive-secret-scan)\" = 755\n chmod 755 /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks\n test \"$(stat -c %a /data/security/receive-secret-scan/20261027-b735d052a49f/gitleaks)\" = 755\nfi\n" - sh - apply securityContext: runAsUser: 1000 runAsGroup: 1000 runAsNonRoot: true allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: requests: cpu: 10m memory: 32Mi limits: cpu: 100m memory: 64Mi volumeMounts: - name: data mountPath: /data/security subPath: security terminationMessagePath: /dev/termination-log terminationMessagePolicy: File gitea: oauth: - name: netkingdom provider: openidConnect key: forgejo secret: "" autoDiscoverUrl: https://kc.coulomb.social/.well-known/openid-configuration scopes: openid,profile,email,groups admin: username: forgejo_admin email: admin@coulomb.social passwordMode: initialOnlyRequireReset # Mailer password from OpenBao via ExternalSecret forgejo-mailer (not Helm/SOPS). additionalConfigFromEnvs: - name: GITEA__GIT_0X2E_CONFIG__INIT_0X2E_TEMPLATEDIR value: /opt/forge-secret-template - name: GITEA__mailer__PASSWD valueFrom: secretKeyRef: name: forgejo-mailer key: MAILER_PASSWD config: oauth2_client: ENABLE_AUTO_REGISTRATION: false ACCOUNT_LINKING: login OPENID_CONNECT_SCOPES: openid profile email groups database: DB_TYPE: postgres HOST: forgejo-db-rw.databases.svc.cluster.local:5432 NAME: forgejo USER: forgejo server: DOMAIN: forgejo.coulomb.social SSH_DOMAIN: forgejo.coulomb.social SSH_PORT: 22 SSH_LISTEN_PORT: 2222 DISABLE_SSH: false service: DISABLE_REGISTRATION: true security: INSTALL_LOCK: true session: COOKIE_SECURE: true mailer: ENABLED: true FROM: forgejo@coulomb.social # IONOS submission port 587 uses STARTTLS, not implicit TLS (smtps). PROTOCOL: smtp+starttls SMTP_ADDR: smtp.ionos.de SMTP_PORT: 587 USER: forgejo@coulomb.social actions: ENABLED: true