From 319e7925ff10068ecea5091beb7144ae0ebe9f07 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 20 Sep 2025 22:59:22 +0200 Subject: [PATCH 01/20] First commit TBT --- helm/gitea-mirror/.yamllint | 21 ++++ helm/gitea-mirror/Chart.yaml | 12 ++ helm/gitea-mirror/templates/_helpers.tpl | 59 ++++++++++ helm/gitea-mirror/templates/configmap.yaml | 35 ++++++ helm/gitea-mirror/templates/deployment.yaml | 92 +++++++++++++++ helm/gitea-mirror/templates/httproute.yaml | 77 +++++++++++++ helm/gitea-mirror/templates/ingress.yaml | 40 +++++++ helm/gitea-mirror/templates/secret.yaml | 14 +++ helm/gitea-mirror/templates/service.yaml | 35 ++++++ .../templates/serviceaccount.yaml | 17 +++ helm/gitea-mirror/values.yaml | 105 ++++++++++++++++++ 11 files changed, 507 insertions(+) create mode 100644 helm/gitea-mirror/.yamllint create mode 100644 helm/gitea-mirror/Chart.yaml create mode 100644 helm/gitea-mirror/templates/_helpers.tpl create mode 100644 helm/gitea-mirror/templates/configmap.yaml create mode 100644 helm/gitea-mirror/templates/deployment.yaml create mode 100644 helm/gitea-mirror/templates/httproute.yaml create mode 100644 helm/gitea-mirror/templates/ingress.yaml create mode 100644 helm/gitea-mirror/templates/secret.yaml create mode 100644 helm/gitea-mirror/templates/service.yaml create mode 100644 helm/gitea-mirror/templates/serviceaccount.yaml create mode 100644 helm/gitea-mirror/values.yaml diff --git a/helm/gitea-mirror/.yamllint b/helm/gitea-mirror/.yamllint new file mode 100644 index 0000000..111146a --- /dev/null +++ b/helm/gitea-mirror/.yamllint @@ -0,0 +1,21 @@ +--- +extends: default + +ignore: | + .yamllint + node_modules + templates + unittests/bash + +rules: + truthy: + allowed-values: ['true', 'false'] + check-keys: False + level: error + line-length: disable + document-start: disable + comments: + min-spaces-from-content: 1 + braces: + max-spaces-inside: 2 + diff --git a/helm/gitea-mirror/Chart.yaml b/helm/gitea-mirror/Chart.yaml new file mode 100644 index 0000000..042a837 --- /dev/null +++ b/helm/gitea-mirror/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v2 +name: gitea-mirror +description: Kubernetes helm chart for gitea-mirror +type: application +version: 0.0.1 +appVersion: 3.7.2 +icon: https://github.com/RayLabsHQ/gitea-mirror/blob/main/.github/assets/logo.png +keywords: + - git + - gitea +sources: + - https://github.com/RayLabsHQ/gitea-mirror diff --git a/helm/gitea-mirror/templates/_helpers.tpl b/helm/gitea-mirror/templates/_helpers.tpl new file mode 100644 index 0000000..e01bff9 --- /dev/null +++ b/helm/gitea-mirror/templates/_helpers.tpl @@ -0,0 +1,59 @@ +{{/* +Expand the name of the chart. +*/}} + +{{- define "gitea-mirror.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "gitea-mirror.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "gitea-mirror.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "gitea-mirror.labels" -}} +helm.sh/chart: {{ include "gitea-mirror.chart" . }} +app: {{ include "gitea-mirror.name" . }} +{{ include "gitea-mirror.selectorLabels" . }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "gitea-mirror.selectorLabels" -}} +app.kubernetes.io/name: {{ include "gitea-mirror.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +ServiceAccount name +*/}} +{{- define "gitea-mirror.serviceAccountName" -}} +{{ .Values.serviceAccount.name | default (include "gitea-mirror.fullname" .) }} +{{- end -}} diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml new file mode 100644 index 0000000..edc3bb8 --- /dev/null +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -0,0 +1,35 @@ +{{- $gm := index .Values "gitea-mirror" -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "gitea-mirror.fullname" . }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} +data: + # Core configuration + DATABASE_URL: {{ $gm.core.databaseUrl }} + BETTER_AUTH_SECRET: {{ $gm.core.be }} + BETTER_AUTH_URL: {{ $gm.betterAuthSecret }} + # GitHub Config + GITHUB_USERNAME: {{ $gm.github.username }} + PRIVATE_REPOSITORIES: {{ $gm.privateRepositories }} + MIRROR_STARRED: {{ $gm.mirror.starred }} + SKIP_FORKS: {{ $gm.github.skipForks }} + SKIP_STARRED_ISSUES: {{ $gm.github.skipStarredIssues }} + # Gitea Config + GITEA_URL: {{ $gm.gitea.url }} + GITEA_USERNAME: {{ $gm.gitea.username }} + GITEA_ORGANIZATION: {{ $gm.gitea.organization }} + GITEA_ORG_VISIBILITY: {{ $gm.gitea.visibility }} + # Mirror Options + MIRROR_RELEASES: {{ $gm.mirror.releases }} + MIRROR_WIKI: {{ $gm.mirror.wiki }} + MIRROR_METADATA: {{ $gm.mirror.metadata }} + MIRROR_ISSUES: {{ $gm.mirror.issues }} + MIRROR_PULL_REQUESTS: {{ $gm.mirror.pullRequests }} + # Automation + SCHEDULE_ENABLED: {{ $gm.automation.schedule_enabled }} + SCHEDULE_INTERVAL: {{ $gm.automation.schedule_interval }} + # Cleanup + CLEANUP_ENABLED: {{ $gm.cleanup.enabled }} + CLEANUP_INTERVAL: {{ $gm.cleanup.interval }} diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml new file mode 100644 index 0000000..eff6e7f --- /dev/null +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -0,0 +1,92 @@ +{{- $gm := index .Values "gitea-mirror" -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "gitea-mirror.fullname" . }} + annotations: + {{- if .Values.deployment.annotations }} + {{- toYaml .Values.deployment.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} + {{- if .Values.deployment.labels }} + {{- toYaml .Values.deployment.labels | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: {{ .Values.deployment.strategy.type }} + {{- if eq .Values.deployment.strategy.type "RollingUpdate" }} + rollingUpdate: + maxUnavailable: {{ .Values.deployment.strategy.rollingUpdate.maxUnavailable }} + maxSurge: {{ .Values.deployment.strategy.rollingUpdate.maxSurge }} + {{- end }} + selector: + matchLabels: + {{- include "gitea-mirror.selectorLabels" . | nindent 6 }} + {{- if .Values.deployment.labels }} + {{- toYaml .Values.deployment.labels | nindent 6 }} + {{- end }} + template: + metadata: + labels: + {{- include "gitea-mirror.labels" . | nindent 8 }} + {{- if .Values.deployment.labels }} + {{- toYaml .Values.deployment.labels | nindent 8 }} + {{- end }} + spec: + {{- if (or .Values.serviceAccount.create .Values.serviceAccount.name) }} + serviceAccountName: {{ include "gitea-mirror.serviceAccountName" . }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- with .Values.imagePullSecrets }} + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }} + containers: + - name: gitea-mirror + image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion | toString }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + envFrom: + - configMapRef: + name: {{ include "gitea-mirror.fullname" . }} + {{- if $gm.existingSecret }} + - secretRef: + name: {{ $gm.existingSecret }} + {{- else }} + - secretRef: + name: {{ include "gitea-mirror.fullname" . }} + {{- end }} + env: + - name: NODE_ENV + value: "production" + - name: PORT + value: "{{ .Values.deployment.port }}" + {{- if .Values.deployment.env }} + {{- toYaml .Values.deployment.env | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.deployment.port }} + resources: + {{- toYaml .Values.deployment.resources | nindent 12 }} + {{- range $key, $value := .Values.nodeSelector }} + nodeSelector: + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/gitea-mirror/templates/httproute.yaml b/helm/gitea-mirror/templates/httproute.yaml new file mode 100644 index 0000000..11c184f --- /dev/null +++ b/helm/gitea-mirror/templates/httproute.yaml @@ -0,0 +1,77 @@ +{{- if .Values.route.enabled }} +{{- if .Values.route.forceHTTPS }} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ include "gitea-mirror.fullname" . }}-http + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} +spec: + parentRefs: + - name: {{ .Values.route.gateway }} + sectionName: {{ .Values.route.http.gatewaySection }} + namespace: {{ .Values.route.gatewayNamespace }} + hostnames: {{ .Values.route.domain }} + rules: + - filters: + - type: RequestRedirect + requestRedirect: + scheme: https + statusCode: 301 + {{- with .Values.route.http.filters }} + {{ toYaml . | nindent 4 }} + {{- end }} +{{- else }} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ include "gitea-mirror.fullname" . }}-http + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} +spec: + parentRefs: + - name: {{ .Values.route.gateway }} + sectionName: {{ .Values.route.http.gatewaySection }} + namespace: {{ .Values.route.gatewayNamespace }} + hostnames: {{ .Values.route.domain }} + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: {{ include "gitea-mirror.fullname" . }} + port: {{ .Values.service.port }} + {{- with .Values.route.http.filters }} + filters: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ include "gitea-mirror.fullname" . }}-https + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} +spec: + parentRefs: + - name: {{ .Values.route.gateway }} + sectionName: {{ .Values.route.https.gatewaySection }} + namespace: {{ .Values.route.gatewayNamespace }} + hostnames: {{ .Values.route.domain }} + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: {{ include "gitea-mirror.fullname" . }} + port: {{ .Values.service.port }} + {{- with .Values.route.https.filters }} + filters: + {{ toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/gitea-mirror/templates/ingress.yaml b/helm/gitea-mirror/templates/ingress.yaml new file mode 100644 index 0000000..1fff62c --- /dev/null +++ b/helm/gitea-mirror/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "gitea-mirror.fullname" . }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- . | toYaml | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} +{{- end }} +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ tpl . $ | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ tpl .host $ | quote }} + http: + paths: + - path: "/" + pathType: "Prefix" + backend: + service: + name: {{ include "gitea-mirror.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} +{{- end }} + diff --git a/helm/gitea-mirror/templates/secret.yaml b/helm/gitea-mirror/templates/secret.yaml new file mode 100644 index 0000000..0cae2e2 --- /dev/null +++ b/helm/gitea-mirror/templates/secret.yaml @@ -0,0 +1,14 @@ +{{- $gm := index .Values "gitea-mirror" -}} +{{- if (empty $gm.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "gitea-mirror.fullname" . }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} +type: Opaque +stringData: + GITHUB_TOKEN: {{ $gm.github.token | quote }} + GITEA_TOKEN: {{ $gm.gitea.token | quote }} + ENCRYPTION_SECRET: {{ $gm.core.encryptionSecret | quote }} +{{- end }} diff --git a/helm/gitea-mirror/templates/service.yaml b/helm/gitea-mirror/templates/service.yaml new file mode 100644 index 0000000..5ceebae --- /dev/null +++ b/helm/gitea-mirror/templates/service.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "gitea-mirror.fullname" . }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} + {{- if .Values.service.labels }} + {{- toYaml .Values.service.labels | nindent 4 }} + {{- end }} + annotations: + {{- toYaml .Values.service.annotations | nindent 4 }} +spec: + type: {{ .Values.service.type }} + {{- if eq .Values.service.type "LoadBalancer" }} + {{- if .Values.service.loadBalancerClass }} + loadBalancerClass: {{ .Values.service.loadBalancerClass }} + {{- end }} + {{- if and .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- end }} + {{- if .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} + {{- end }} + {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + ports: + - name: http + port: {{ .Values.service.port }} + protocol: TCP + targetPort: http + selector: + {{- include "gitea-mirror.selectorLabels" . | nindent 4 }} + \ No newline at end of file diff --git a/helm/gitea-mirror/templates/serviceaccount.yaml b/helm/gitea-mirror/templates/serviceaccount.yaml new file mode 100644 index 0000000..34249c9 --- /dev/null +++ b/helm/gitea-mirror/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "gitea-mirror.serviceAccountName" . }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{- . | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- . | toYaml | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} + diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml new file mode 100644 index 0000000..ac427db --- /dev/null +++ b/helm/gitea-mirror/values.yaml @@ -0,0 +1,105 @@ +image: + registry: ghcr.io + repository: raylabshq/gitea-mirror + # Leave blank to use the Appversion tag + tag: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] + +ingress: + enabled: false + className: "" + pathType: Prefix + annotations: {} + hosts: + - host: mirror.example.com + paths: + - path: / + tls: [] + # - secretName: chart-example-tls + # hosts: + # - mirror.example.com + +route: + enabled: false + forceHTTPS: true + domain: ["mirror.example.com"] + gateway: "" + gatewayNamespace: "" + http: + gatewaySection: "" + filters: [] + https: + gatewaySection: "" + filters: + - type: ResponseHeaderModifier + responseHeaderModifier: + add: + - name: Strict-Transport-Security + value: "max-age=31536000; includeSubDomains; preload" + +service: + type: ClusterIP + port: 8080 + clusterIP: None + annotations: {} + externalTrafficPolicy: + labels: {} + loadBalancerIP: + loadBalancerClass: + +deployment: + port: 8080 + strategy: + type: Recreate + env: [] + terminationGracePeriodSeconds: 60 + labels: {} + annotations: {} + resources: {} + +serviceAccount: + create: false + name: "" + annotations: {} + labels: {} + automountServiceAccountToken: false + +gitea-mirror: + existingSecret: "" + core: + databaseUrl: file:data/gitea-mirror.db + encryptionSecret: "" + betterAuthSecret: "" + betterAuthUrl: "http://localhost:4321" + + github: + username: "" + token: "" + privateRepositories: true + mirrorStarred: false + skipForks: false + skipStarredIssues: false + + gitea: + url: "" + token: "" + username: "" + organization: "github-mirrors" + visibility: "public" + + mirror: + releases: true + wiki: true + metadata: true + issues: true + pullRequests: true + + automation: + schedule_enabled: true + schedule_interval: 3600 + + cleanup: + enabled: true + retentionDays: 30 From 3c52fe58aac4f55df93af753d3d0d9aedaa10556 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sun, 21 Sep 2025 10:23:48 +0200 Subject: [PATCH 02/20] Missing space --- helm/gitea-mirror/templates/service.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/helm/gitea-mirror/templates/service.yaml b/helm/gitea-mirror/templates/service.yaml index 5ceebae..00c4e73 100644 --- a/helm/gitea-mirror/templates/service.yaml +++ b/helm/gitea-mirror/templates/service.yaml @@ -32,4 +32,3 @@ spec: targetPort: http selector: {{- include "gitea-mirror.selectorLabels" . | nindent 4 }} - \ No newline at end of file From 80fd43ef427026217370fd9b44195fd6e33e631b Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sun, 21 Sep 2025 12:26:26 +0200 Subject: [PATCH 03/20] More features --- helm/gitea-mirror/templates/deployment.yaml | 69 ++++++++++++++++----- helm/gitea-mirror/values.yaml | 28 +++++++++ 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index eff6e7f..11cda3e 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -3,10 +3,10 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "gitea-mirror.fullname" . }} + {{- with .Values.deployment.annotations }} annotations: - {{- if .Values.deployment.annotations }} {{- toYaml .Values.deployment.annotations | nindent 4 }} - {{- end }} + {{- end }} labels: {{- include "gitea-mirror.labels" . | nindent 4 }} {{- if .Values.deployment.labels }} @@ -24,9 +24,6 @@ spec: selector: matchLabels: {{- include "gitea-mirror.selectorLabels" . | nindent 6 }} - {{- if .Values.deployment.labels }} - {{- toYaml .Values.deployment.labels | nindent 6 }} - {{- end }} template: metadata: labels: @@ -42,10 +39,13 @@ spec: priorityClassName: "{{ .Values.priorityClassName }}" {{- end }} {{- with .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.podSecurityContext }} securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- toYaml . | nindent 8 }} + {{- end }} terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }} containers: - name: gitea-mirror @@ -72,21 +72,56 @@ spec: ports: - name: http containerPort: {{ .Values.deployment.port }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /api/health + port: "http" + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /api/health + port: "http" + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + {{- end }} + {{- if .Values.startupProbe.enabled }} + startupProbe: + httpGet: + path: /api/health + port: "http" + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + {{- end }} + {{- with .Values.deployment.resources }} resources: {{- toYaml .Values.deployment.resources | nindent 12 }} - {{- range $key, $value := .Values.nodeSelector }} - nodeSelector: - {{ $key }}: {{ $value | quote }} - {{- end }} - {{- with .Values.affinity }} + {{- end }} + {{- with .Values.affinity }} affinity: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.topologySpreadConstraints }} - topologySpreadConstraints: + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} + {{- end }} + {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index ac427db..e1f5758 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -59,6 +59,34 @@ deployment: annotations: {} resources: {} + +livenessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +readinessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +startupProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + +affinity: {} +nodeSelector: {} +tolerations: [] +topologySpreadConstraints: [] + serviceAccount: create: false name: "" From 4528be8cc6e5e203735b33fb597a65398b4bfa89 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sun, 21 Sep 2025 12:29:02 +0200 Subject: [PATCH 04/20] Too many spaces --- helm/gitea-mirror/values.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index e1f5758..d821d8d 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -59,7 +59,6 @@ deployment: annotations: {} resources: {} - livenessProbe: enabled: true initialDelaySeconds: 60 From f701574e675bc2f1ee479acf2c377a3a904f2b50 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sun, 21 Sep 2025 15:15:58 +0200 Subject: [PATCH 05/20] Move NODE_ENV to the configmap --- helm/gitea-mirror/templates/configmap.yaml | 1 + helm/gitea-mirror/templates/deployment.yaml | 2 -- helm/gitea-mirror/values.yaml | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml index edc3bb8..a953c74 100644 --- a/helm/gitea-mirror/templates/configmap.yaml +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -6,6 +6,7 @@ metadata: labels: {{- include "gitea-mirror.labels" . | nindent 4 }} data: + NODE_ENV: {{ $gm.nodeEnv }} # Core configuration DATABASE_URL: {{ $gm.core.databaseUrl }} BETTER_AUTH_SECRET: {{ $gm.core.be }} diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index 11cda3e..c99bd7a 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -62,8 +62,6 @@ spec: name: {{ include "gitea-mirror.fullname" . }} {{- end }} env: - - name: NODE_ENV - value: "production" - name: PORT value: "{{ .Values.deployment.port }}" {{- if .Values.deployment.env }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index d821d8d..d896b1e 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -95,6 +95,7 @@ serviceAccount: gitea-mirror: existingSecret: "" + nodeEnv: production core: databaseUrl: file:data/gitea-mirror.db encryptionSecret: "" From 1e2c1c686d15e478693db1d4109acba1933afc2e Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sun, 21 Sep 2025 21:15:50 +0200 Subject: [PATCH 06/20] Add volumes --- helm/gitea-mirror/templates/deployment.yaml | 20 ++++++++++++++++ helm/gitea-mirror/templates/pvc.yaml | 26 +++++++++++++++++++++ helm/gitea-mirror/values.yaml | 10 ++++++++ 3 files changed, 56 insertions(+) create mode 100644 helm/gitea-mirror/templates/pvc.yaml diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index c99bd7a..f30e0d6 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -103,6 +103,12 @@ spec: failureThreshold: {{ .Values.startupProbe.failureThreshold }} successThreshold: {{ .Values.startupProbe.successThreshold }} {{- end }} + volumeMounts: + - name: data + mountPath: /app/data + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} {{- with .Values.deployment.resources }} resources: {{- toYaml .Values.deployment.resources | nindent 12 }} @@ -123,3 +129,17 @@ spec: topologySpreadConstraints: {{- toYaml . | nindent 8 }} {{- end }} + volumes: + {{- if .Values.persistence.enabled }} + {{- if .Values.persistence.mount }} + - name: data + persistentVolumeClaim: + claimName: {{ .Values.persistence.claimName }} + {{- end }} + {{- else if not .Values.persistence.enabled }} + - name: data + emptyDir: {} + {{- end }} + {{- if .Values.extraVolumes }} + {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} diff --git a/helm/gitea-mirror/templates/pvc.yaml b/helm/gitea-mirror/templates/pvc.yaml new file mode 100644 index 0000000..0e63293 --- /dev/null +++ b/helm/gitea-mirror/templates/pvc.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.persistence.enabled .Values.persistence.create }} +{{- $gm := index .Values "gitea-mirror" -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ .Values.persistence.claimName }} + labels: + {{- include "gitea-mirror.labels" . | nindent 4 }} + {{- with .Values.persistence.annotations }} + annotations: + {{ . | toYaml | indent 4}} + {{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessModes }} + {{- with .Values.persistence.storageClass }} + storageClass: {{ . }} + {{- end }} + volumeMode: Filesystem + {{- with .Values.persistence.volumeName }} + volumeName: {{ . }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size }} +{{- end }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index d896b1e..07eb7f6 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -81,10 +81,20 @@ startupProbe: failureThreshold: 6 successThreshold: 1 +persistence: + enabled: true + create: true + claimName: gitea-mirror-storage + storageClass: "" + accessMode: ReadWriteOnce + size: 1Gi + affinity: {} nodeSelector: {} tolerations: [] topologySpreadConstraints: [] +extraVolumes: [] +extraVolumeMounts: [] serviceAccount: create: false From cd86a09bbddb806234f2c2a1742df86490a96f12 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Wed, 24 Sep 2025 20:29:14 +0200 Subject: [PATCH 07/20] Minor fixes --- helm/gitea-mirror/templates/configmap.yaml | 44 ++++++++++----------- helm/gitea-mirror/templates/deployment.yaml | 2 - helm/gitea-mirror/templates/httproute.yaml | 4 +- helm/gitea-mirror/templates/pvc.yaml | 4 +- helm/gitea-mirror/values.yaml | 3 +- 5 files changed, 28 insertions(+), 29 deletions(-) diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml index a953c74..4451772 100644 --- a/helm/gitea-mirror/templates/configmap.yaml +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -6,31 +6,31 @@ metadata: labels: {{- include "gitea-mirror.labels" . | nindent 4 }} data: - NODE_ENV: {{ $gm.nodeEnv }} + NODE_ENV: {{ $gm.nodeEnv | quote }} # Core configuration - DATABASE_URL: {{ $gm.core.databaseUrl }} - BETTER_AUTH_SECRET: {{ $gm.core.be }} - BETTER_AUTH_URL: {{ $gm.betterAuthSecret }} + DATABASE_URL: {{ $gm.core.databaseUrl | quote }} + BETTER_AUTH_SECRET: {{ $gm.core.be | quote }} + BETTER_AUTH_URL: {{ $gm.betterAuthSecret | quote }} # GitHub Config - GITHUB_USERNAME: {{ $gm.github.username }} - PRIVATE_REPOSITORIES: {{ $gm.privateRepositories }} - MIRROR_STARRED: {{ $gm.mirror.starred }} - SKIP_FORKS: {{ $gm.github.skipForks }} - SKIP_STARRED_ISSUES: {{ $gm.github.skipStarredIssues }} + GITHUB_USERNAME: {{ $gm.github.username | quote }} + PRIVATE_REPOSITORIES: {{ $gm.privateRepositories | quote }} + MIRROR_STARRED: {{ $gm.mirror.starred | quote }} + SKIP_FORKS: {{ $gm.github.skipForks | quote }} + SKIP_STARRED_ISSUES: {{ $gm.github.skipStarredIssues | quote }} # Gitea Config - GITEA_URL: {{ $gm.gitea.url }} - GITEA_USERNAME: {{ $gm.gitea.username }} - GITEA_ORGANIZATION: {{ $gm.gitea.organization }} - GITEA_ORG_VISIBILITY: {{ $gm.gitea.visibility }} + GITEA_URL: {{ $gm.gitea.url | quote }} + GITEA_USERNAME: {{ $gm.gitea.username | quote }} + GITEA_ORGANIZATION: {{ $gm.gitea.organization | quote }} + GITEA_ORG_VISIBILITY: {{ $gm.gitea.visibility | quote }} # Mirror Options - MIRROR_RELEASES: {{ $gm.mirror.releases }} - MIRROR_WIKI: {{ $gm.mirror.wiki }} - MIRROR_METADATA: {{ $gm.mirror.metadata }} - MIRROR_ISSUES: {{ $gm.mirror.issues }} - MIRROR_PULL_REQUESTS: {{ $gm.mirror.pullRequests }} + MIRROR_RELEASES: {{ $gm.mirror.releases | quote }} + MIRROR_WIKI: {{ $gm.mirror.wiki | quote }} + MIRROR_METADATA: {{ $gm.mirror.metadata | quote }} + MIRROR_ISSUES: {{ $gm.mirror.issues | quote }} + MIRROR_PULL_REQUESTS: {{ $gm.mirror.pullRequests | quote }} # Automation - SCHEDULE_ENABLED: {{ $gm.automation.schedule_enabled }} - SCHEDULE_INTERVAL: {{ $gm.automation.schedule_interval }} + SCHEDULE_ENABLED: {{ $gm.automation.schedule_enabled| quote }} + SCHEDULE_INTERVAL: {{ $gm.automation.schedule_interval | quote }} # Cleanup - CLEANUP_ENABLED: {{ $gm.cleanup.enabled }} - CLEANUP_INTERVAL: {{ $gm.cleanup.interval }} + CLEANUP_ENABLED: {{ $gm.cleanup.enabled | quote }} + CLEANUP_INTERVAL: {{ $gm.cleanup.interval | quote }} diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index f30e0d6..929cd5a 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -131,11 +131,9 @@ spec: {{- end }} volumes: {{- if .Values.persistence.enabled }} - {{- if .Values.persistence.mount }} - name: data persistentVolumeClaim: claimName: {{ .Values.persistence.claimName }} - {{- end }} {{- else if not .Values.persistence.enabled }} - name: data emptyDir: {} diff --git a/helm/gitea-mirror/templates/httproute.yaml b/helm/gitea-mirror/templates/httproute.yaml index 11c184f..d9a8bc1 100644 --- a/helm/gitea-mirror/templates/httproute.yaml +++ b/helm/gitea-mirror/templates/httproute.yaml @@ -46,7 +46,7 @@ spec: port: {{ .Values.service.port }} {{- with .Values.route.http.filters }} filters: - {{ toYaml . | nindent 4 }} + {{- toYaml . | nindent 8 }} {{- end }} {{- end }} --- @@ -72,6 +72,6 @@ spec: port: {{ .Values.service.port }} {{- with .Values.route.https.filters }} filters: - {{ toYaml . | nindent 4 }} + {{- toYaml . | nindent 8 }} {{- end }} {{- end }} diff --git a/helm/gitea-mirror/templates/pvc.yaml b/helm/gitea-mirror/templates/pvc.yaml index 0e63293..81f9ce9 100644 --- a/helm/gitea-mirror/templates/pvc.yaml +++ b/helm/gitea-mirror/templates/pvc.yaml @@ -12,9 +12,9 @@ metadata: {{- end }} spec: accessModes: - - {{ .Values.persistence.accessModes }} + {{- toYaml .Values.persistence.accessModes | nindent 4 }} {{- with .Values.persistence.storageClass }} - storageClass: {{ . }} + storageClassName: {{ . }} {{- end }} volumeMode: Filesystem {{- with .Values.persistence.volumeName }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index 07eb7f6..123450d 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -86,7 +86,8 @@ persistence: create: true claimName: gitea-mirror-storage storageClass: "" - accessMode: ReadWriteOnce + accessModes: + - ReadWriteOnce size: 1Gi affinity: {} From f9d18f34abf7c91b0b519e72addd6ac68ad01c47 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Wed, 24 Sep 2025 20:41:24 +0200 Subject: [PATCH 08/20] Fix image tag --- helm/gitea-mirror/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index 929cd5a..20ba57f 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -49,7 +49,7 @@ spec: terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }} containers: - name: gitea-mirror - image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion | toString }} + image: {{ .Values.image.registry }}/{{ .Values.image.repository }}:v{{ .Values.image.tag | default .Chart.AppVersion | toString }} imagePullPolicy: {{ .Values.image.pullPolicy }} envFrom: - configMapRef: From 432a2bc54d4234b3009c6bab69bf8fc8eea89ffe Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Wed, 24 Sep 2025 20:47:54 +0200 Subject: [PATCH 09/20] Add missing podSecurityContext --- helm/gitea-mirror/values.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index 123450d..6cad53c 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -6,6 +6,11 @@ image: pullPolicy: IfNotPresent imagePullSecrets: [] +podSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + fsGroupChangePolicy: OnRootMismatch ingress: enabled: false From 7386b54a460ed8e49955924b38f812fce3cd0e30 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Wed, 24 Sep 2025 21:12:16 +0200 Subject: [PATCH 10/20] Fix env vars --- helm/gitea-mirror/templates/configmap.yaml | 7 ++++--- helm/gitea-mirror/values.yaml | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml index 4451772..0455d14 100644 --- a/helm/gitea-mirror/templates/configmap.yaml +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -9,11 +9,12 @@ data: NODE_ENV: {{ $gm.nodeEnv | quote }} # Core configuration DATABASE_URL: {{ $gm.core.databaseUrl | quote }} - BETTER_AUTH_SECRET: {{ $gm.core.be | quote }} - BETTER_AUTH_URL: {{ $gm.betterAuthSecret | quote }} + BETTER_AUTH_SECRET: {{ $gm.core.betterAuthSecret | quote }} + BETTER_AUTH_URL: {{ $gm.core.betterAuthUrl | quote }} + BETTER_AUTH_TRUSTED_ORIGINS: {{ $gm.core.betterAuthTrustedOrigins | quote }} # GitHub Config GITHUB_USERNAME: {{ $gm.github.username | quote }} - PRIVATE_REPOSITORIES: {{ $gm.privateRepositories | quote }} + PRIVATE_REPOSITORIES: {{ $gm.github.privateRepositories | quote }} MIRROR_STARRED: {{ $gm.mirror.starred | quote }} SKIP_FORKS: {{ $gm.github.skipForks | quote }} SKIP_STARRED_ISSUES: {{ $gm.github.skipStarredIssues | quote }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index 6cad53c..b0d2ff6 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -117,6 +117,7 @@ gitea-mirror: encryptionSecret: "" betterAuthSecret: "" betterAuthUrl: "http://localhost:4321" + betterAuthTrustedOrigins: "http://localhost:4321" github: username: "" From 1fe20c3e54f6021489cd3c1f41e130bd06f42087 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Wed, 24 Sep 2025 22:07:15 +0200 Subject: [PATCH 11/20] GITHUB_TYPE env var --- helm/gitea-mirror/templates/configmap.yaml | 1 + helm/gitea-mirror/values.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml index 0455d14..9c4a909 100644 --- a/helm/gitea-mirror/templates/configmap.yaml +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -14,6 +14,7 @@ data: BETTER_AUTH_TRUSTED_ORIGINS: {{ $gm.core.betterAuthTrustedOrigins | quote }} # GitHub Config GITHUB_USERNAME: {{ $gm.github.username | quote }} + GITHUB_TYPE: {{ $gm.github.type | quote }} PRIVATE_REPOSITORIES: {{ $gm.github.privateRepositories | quote }} MIRROR_STARRED: {{ $gm.mirror.starred | quote }} SKIP_FORKS: {{ $gm.github.skipForks | quote }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index b0d2ff6..f711daa 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -122,6 +122,7 @@ gitea-mirror: github: username: "" token: "" + type: personal privateRepositories: true mirrorStarred: false skipForks: false From 18de63d192ef55f0c5e4268eb3808b813334a2d6 Mon Sep 17 00:00:00 2001 From: "Virgil R." Date: Sat, 27 Sep 2025 10:04:42 +0200 Subject: [PATCH 12/20] Update deployment.yaml --- helm/gitea-mirror/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index 20ba57f..d57e3c2 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -13,7 +13,7 @@ metadata: {{- toYaml .Values.deployment.labels | nindent 4 }} {{- end }} spec: - replicas: {{ .Values.replicaCount }} + replicas: 1 strategy: type: {{ .Values.deployment.strategy.type }} {{- if eq .Values.deployment.strategy.type "RollingUpdate" }} From c0fff30fcbdbd6ea0ddf001e17c084dfded25d7d Mon Sep 17 00:00:00 2001 From: "Virgil R." Date: Sat, 27 Sep 2025 10:12:29 +0200 Subject: [PATCH 13/20] Create README.md --- helm/gitea-mirror/README.md | 307 ++++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 helm/gitea-mirror/README.md diff --git a/helm/gitea-mirror/README.md b/helm/gitea-mirror/README.md new file mode 100644 index 0000000..f612a20 --- /dev/null +++ b/helm/gitea-mirror/README.md @@ -0,0 +1,307 @@ +# gitea-mirror (Helm Chart) + +Deploy **gitea-mirror** to Kubernetes using Helm. The chart packages a Deployment, Service, optional Ingress or Gateway API HTTPRoutes, ConfigMap and Secret, a PVC (optional), and an optional ServiceAccount. + +- **Chart name:** `gitea-mirror` +- **Type:** `application` +- **App version:** `3.7.2` (default image tag, can be overridden) + +--- + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8+ +- (Optional) Gateway API (v1) if you plan to use `route.*` HTTPRoutes, see https://github.com/kubernetes-sigs/gateway-api/ +- (Optional) An Ingress controller if you plan to use `ingress.*` + +--- + +## Quick start + +From the repo root (chart path: `helm/gitea-mirror`): + +```bash +# Create a namespace (optional) +kubectl create namespace gitea-mirror + +# Install with minimal required secrets/values +helm upgrade --install gitea-mirror ./helm/gitea-mirror --namespace gitea-mirror --set "gitea-mirror.github.username=" --set "gitea-mirror.github.token=" --set "gitea-mirror.gitea.url=https://gitea.example.com" --set "gitea-mirror.gitea.token=" +``` + +The default Service is `ClusterIP` on port `8080`. You can expose it via Ingress or Gateway API; see below. + +--- + +## Upgrading + +Standard Helm upgrade: + +```bash +helm upgrade gitea-mirror ./helm/gitea-mirror -n gitea-mirror +``` + +If you change persistence settings or storage class, a rollout may require PVC recreation. + +--- + +## Uninstalling + +```bash +helm uninstall gitea-mirror -n gitea-mirror +``` + +If you enabled persistence with a PVC the data may persist; delete the PVC manually if you want a clean slate. + +--- + +## Configuration + +### Global image & pod settings + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `image.registry` | string | `ghcr.io` | Container registry. | +| `image.repository` | string | `raylabshq/gitea-mirror` | Image repository. | +| `image.tag` | string | `""` | Image tag; when empty, uses the chart `appVersion` (`3.7.2`). | +| `image.pullPolicy` | string | `IfNotPresent` | K8s image pull policy. | +| `imagePullSecrets` | list | `[]` | Image pull secrets. | +| `podSecurityContext.runAsUser` | int | `1001` | UID. | +| `podSecurityContext.runAsGroup` | int | `1001` | GID. | +| `podSecurityContext.fsGroup` | int | `1001` | FS group. | +| `podSecurityContext.fsGroupChangePolicy` | string | `OnRootMismatch` | FS group change policy. | +| `nodeSelector` / `tolerations` / `affinity` / `topologySpreadConstraints` | — | — | Standard scheduling knobs. | +| `extraVolumes` / `extraVolumeMounts` | list | `[]` | Append custom volumes/mounts. | +| `priorityClassName` | string | `""` | Optional Pod priority class. | + +### Deployment + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `deployment.port` | int | `8080` | Container port & named `http` port. | +| `deployment.strategy.type` | string | `Recreate` | Update strategy (`Recreate` or `RollingUpdate`). | +| `deployment.strategy.rollingUpdate.maxUnavailable/maxSurge` | string/int | — | Used when `type=RollingUpdate`. | +| `deployment.env` | list | `[]` | Extra environment variables. | +| `deployment.resources` | map | `{}` | CPU/memory requests & limits. | +| `deployment.terminationGracePeriodSeconds` | int | `60` | Grace period. | +| `livenessProbe.*` | — | enabled, `/api/health` | Liveness probe (HTTP GET to `/api/health`). | +| `readinessProbe.*` | — | enabled, `/api/health` | Readiness probe. | +| `startupProbe.*` | — | enabled, `/api/health` | Startup probe. | + +> The Pod mounts a volume at `/app/data` (PVC or `emptyDir` depending on `persistence.enabled`). + +### Service + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `service.type` | string | `ClusterIP` | Service type. | +| `service.port` | int | `8080` | Service port. | +| `service.clusterIP` | string | `None` | ClusterIP (only when `type=ClusterIP`). | +| `service.externalTrafficPolicy` | string | `""` | External traffic policy (LB). | +| `service.loadBalancerIP` | string | `""` | LoadBalancer IP. | +| `service.loadBalancerClass` | string | `""` | LoadBalancer class. | +| `service.annotations` / `service.labels` | map | `{}` | Extra metadata. | + +### Ingress (optional) + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `ingress.enabled` | bool | `false` | Enable Ingress. | +| `ingress.className` | string | `""` | IngressClass name. | +| `ingress.hosts[0].host` | string | `mirror.example.com` | Hostname. | +| `ingress.tls` | list | `[]` | TLS blocks (secret name etc.). | +| `ingress.annotations` | map | `{}` | Controller-specific annotations. | + +> The Ingress exposes `/` to the chart’s Service. + +### Gateway API HTTPRoutes (optional) + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `route.enabled` | bool | `false` | Enable Gateway API HTTPRoutes. | +| `route.forceHTTPS` | bool | `true` | If true, create an HTTP route that redirects to HTTPS (301). | +| `route.domain` | list | `["mirror.example.com"]` | Hostnames. | +| `route.gateway` | string | `""` | Gateway name. | +| `route.gatewayNamespace` | string | `""` | Gateway namespace. | +| `route.http.gatewaySection` | string | `""` | SectionName for HTTP listener. | +| `route.https.gatewaySection` | string | `""` | SectionName for HTTPS listener. | +| `route.http.filters` / `route.https.filters` | list | `[]` | Additional filters. (Defaults add HSTS header on HTTPS.) | + +### Persistence + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `persistence.enabled` | bool | `true` | Enable persistent storage. | +| `persistence.create` | bool | `true` | Create a PVC from the chart. | +| `persistence.claimName` | string | `gitea-mirror-storage` | PVC name. | +| `persistence.storageClass` | string | `""` | StorageClass to use. | +| `persistence.accessModes` | list | `["ReadWriteOnce"]` | Access modes. | +| `persistence.size` | string | `1Gi` | Requested size. | +| `persistence.volumeName` | string | `""` | Bind to existing PV by name (optional). | +| `persistence.annotations` | map | `{}` | PVC annotations. | + +### ServiceAccount (optional) + +| Key | Type | Default | Description | +| --- | --- | --- | --- | +| `serviceAccount.create` | bool | `false` | Create a ServiceAccount. | +| `serviceAccount.name` | string | `""` | SA name (defaults to release fullname). | +| `serviceAccount.automountServiceAccountToken` | bool | `false` | Automount token. | +| `serviceAccount.annotations` / `labels` | map | `{}` | Extra metadata. | + +--- + +## Application configuration (`gitea-mirror.*`) + +These values populate a **ConfigMap** (non-secret) and a **Secret** (for tokens and sensitive fields). Environment variables from both are consumed by the container. + +### Core + +| Key | Default | Mapped env | +| --- | --- | --- | +| `gitea-mirror.nodeEnv` | `production` | `NODE_ENV` | +| `gitea-mirror.core.databaseUrl` | `file:data/gitea-mirror.db` | `DATABASE_URL` | +| `gitea-mirror.core.encryptionSecret` | `""` | `ENCRYPTION_SECRET` (Secret) | +| `gitea-mirror.core.betterAuthSecret` | `""` | `BETTER_AUTH_SECRET` | +| `gitea-mirror.core.betterAuthUrl` | `http://localhost:4321` | `BETTER_AUTH_URL` | +| `gitea-mirror.core.betterAuthTrustedOrigins` | `http://localhost:4321` | `BETTER_AUTH_TRUSTED_ORIGINS` | + +### GitHub + +| Key | Default | Mapped env | +| --- | --- | --- | +| `gitea-mirror.github.username` | `""` | `GITHUB_USERNAME` | +| `gitea-mirror.github.token` | `""` | `GITHUB_TOKEN` (Secret) | +| `gitea-mirror.github.type` | `personal` | `GITHUB_TYPE` | +| `gitea-mirror.github.privateRepositories` | `true` | `PRIVATE_REPOSITORIES` | +| `gitea-mirror.github.skipForks` | `false` | `SKIP_FORKS` | +| `gitea-mirror.github.skipStarredIssues` | `false` | `SKIP_STARRED_ISSUES` | +| `gitea-mirror.github.mirrorStarred` | `false` | `MIRROR_STARRED` | + +### Gitea + +| Key | Default | Mapped env | +| --- | --- | --- | +| `gitea-mirror.gitea.url` | `""` | `GITEA_URL` | +| `gitea-mirror.gitea.token` | `""` | `GITEA_TOKEN` (Secret) | +| `gitea-mirror.gitea.username` | `""` | `GITEA_USERNAME` | +| `gitea-mirror.gitea.organization` | `github-mirrors` | `GITEA_ORGANIZATION` | +| `gitea-mirror.gitea.visibility` | `public` | `GITEA_ORG_VISIBILITY` | + +### Mirror options + +| Key | Default | Mapped env | +| --- | --- | --- | +| `gitea-mirror.mirror.releases` | `true` | `MIRROR_RELEASES` | +| `gitea-mirror.mirror.wiki` | `true` | `MIRROR_WIKI` | +| `gitea-mirror.mirror.metadata` | `true` | `MIRROR_METADATA` | +| `gitea-mirror.mirror.issues` | `true` | `MIRROR_ISSUES` | +| `gitea-mirror.mirror.pullRequests` | `true` | `MIRROR_PULL_REQUESTS` | +| `gitea-mirror.mirror.starred` | _(see note above)_ | `MIRROR_STARRED` | + +### Automation & cleanup + +| Key | Default | Mapped env | +| --- | --- | --- | +| `gitea-mirror.automation.schedule_enabled` | `true` | `SCHEDULE_ENABLED` | +| `gitea-mirror.automation.schedule_interval` | `3600` | `SCHEDULE_INTERVAL` (seconds) | +| `gitea-mirror.cleanup.enabled` | `true` | `CLEANUP_ENABLED` | +| `gitea-mirror.cleanup.retentionDays` | `30` | `CLEANUP_INTERVAL` | + +> **Secrets:** If you set `gitea-mirror.existingSecret` (name of an existing Secret), the chart will **not** create its own Secret and will reference yours instead. Otherwise it creates a Secret with `GITHUB_TOKEN`, `GITEA_TOKEN`, `ENCRYPTION_SECRET`. + +--- + +## Exposing the service + +### Using Ingress + +```yaml +ingress: + enabled: true + className: "nginx" + hosts: + - host: mirror.example.com + tls: + - secretName: mirror-tls + hosts: + - mirror.example.com +``` + +This creates an Ingress routing `/` to the service on port `8080`. + +### Using Gateway API (HTTPRoute) + +```yaml +route: + enabled: true + domain: ["mirror.example.com"] + gateway: "my-gateway" + gatewayNamespace: "gateway-system" + http: + gatewaySection: "http" + https: + gatewaySection: "https" + # Example extra filter already included by default: add HSTS header +``` + +If `forceHTTPS: true`, the chart emits an HTTP route that redirects to HTTPS with 301. An HTTPS route is always created when `route.enabled=true`. + +--- + +## Persistence & data + +By default, the chart provisions a PVC named `gitea-mirror-storage` with `1Gi` and mounts it at `/app/data`. To use an existing PV or tune storage, adjust `persistence.*` in `values.yaml`. If you disable persistence, an `emptyDir` will be used instead. + +--- + +## Environment & health endpoints + +The container listens on `PORT` (defaults to `deployment.port` = `8080`) and exposes `GET /api/health` for liveness/readiness/startup probes. + +--- + +## Examples + +### Minimal (tokens via chart-managed Secret) + +```yaml +gitea-mirror: + github: + username: "gitea-mirror" + token: "" + gitea: + url: "https://gitea.company.tld" + token: "" +``` + +### Bring your own Secret + +```yaml +gitea-mirror: + existingSecret: "gitea-mirror-secrets" + github: + username: "gitea-mirror" + gitea: + url: "https://gitea.company.tld" +``` + +Where `gitea-mirror-secrets` contains keys `GITHUB_TOKEN`, `GITEA_TOKEN`, `ENCRYPTION_SECRET`. + +--- + +## Development + +Lint the chart: + +```bash +yamllint -c helm/gitea-mirror/.yamllint helm/gitea-mirror +``` + +Tweak probes, resources, and scheduling as needed; see `values.yaml`. + +--- + +## License + +This chart is part of the `RayLabsHQ/gitea-mirror` repository. See the repository for licensing details. From 91fa3604b6e026b68f6411d5bfa9047d2ef6e3cc Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 27 Sep 2025 10:24:18 +0200 Subject: [PATCH 14/20] Add some basic CICD for testing --- .github/ci/values-ci.yaml | 59 +++++++++++++++++++++++++++++++++ .github/workflows/helm-test.yml | 50 ++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 .github/ci/values-ci.yaml create mode 100644 .github/workflows/helm-test.yml diff --git a/.github/ci/values-ci.yaml b/.github/ci/values-ci.yaml new file mode 100644 index 0000000..ed3b034 --- /dev/null +++ b/.github/ci/values-ci.yaml @@ -0,0 +1,59 @@ +image: + registry: ghcr.io + repository: raylabshq/gitea-mirror + tag: "" + +service: + type: ClusterIP + port: 8080 + +ingress: + enabled: true + className: "nginx" + hosts: + - host: ci.example.com + +route: + enabled: true + forceHTTPS: true + domain: ["ci.example.com"] + gateway: "dummy-gw" + gatewayNamespace: "default" + http: + gatewaySection: "http" + https: + gatewaySection: "https" + +gitea-mirror: + nodeEnv: production + core: + databaseUrl: "file:data/gitea-mirror.db" + betterAuthSecret: "dummy" + betterAuthUrl: "http://localhost:4321" + betterAuthTrustedOrigins: "http://localhost:4321" + github: + username: "ci-user" + token: "not-used-in-template" + type: "personal" + privateRepositories: true + skipForks: false + skipStarredIssues: false + gitea: + url: "https://gitea.example.com" + token: "not-used-in-template" + username: "ci-user" + organization: "github-mirrors" + visibility: "public" + mirror: + releases: true + wiki: true + metadata: true + issues: true + pullRequests: true + starred: false + automation: + schedule_enabled: true + schedule_interval: "3600" + cleanup: + enabled: true + interval: "2592000" diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml new file mode 100644 index 0000000..999efbc --- /dev/null +++ b/.github/workflows/helm-test.yml @@ -0,0 +1,50 @@ +name: Helm Chart CI + +on: + pull_request: + push: + branches: [ main ] + workflow_dispatch: + +jobs: + yamllint: + name: Lint YAML + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Install yamllint + run: pip install --disable-pip-version-check yamllint + - name: Run yamllint + run: | + yamllint -c helm/gitea-mirror/.yamllint helm/gitea-mirror + + helm-template: + name: Helm lint & template + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Helm + uses: azure/setup-helm@v4 + with: + version: v3.19.0 + - name: Helm lint + run: | + helm lint ./helm/gitea-mirror + - name: Template with defaults + run: | + helm template test ./helm/gitea-mirror > /tmp/render-defaults.yaml + test -s /tmp/render-defaults.yaml + - name: Template with CI values + run: | + helm template test ./helm/gitea-mirror -f .github/ci/values-ci.yaml > /tmp/render-ci.yaml + test -s /tmp/render-ci.yaml + - name: Show a summary + run: | + echo "Rendered with defaults:" + awk 'NR<=50{print} NR==51{print "..."; exit}' /tmp/render-defaults.yaml + echo "" + echo "Rendered with CI values:" + awk 'NR<=50{print} NR==51{print "..."; exit}' /tmp/render-ci.yaml From 8f379baad459d5f0ea17e3ae7d525c1b3d4f16d3 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 27 Sep 2025 10:34:20 +0200 Subject: [PATCH 15/20] Improve CI/CD --- .github/workflows/README.md | 7 +++++++ .github/workflows/helm-test.yml | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index aba0aa2..e0af5b2 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -85,3 +85,10 @@ If a workflow fails: - Security vulnerabilities For persistent issues, consider opening an issue in the repository. + + +### Helm Test (`helm-test.yml`) + +This workflow run on the main branch and pull requests. it: +- Run yamllint to keep the formating unified +- Run helm template with different value files diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml index 999efbc..4127a75 100644 --- a/.github/workflows/helm-test.yml +++ b/.github/workflows/helm-test.yml @@ -4,6 +4,10 @@ on: pull_request: push: branches: [ main ] + paths: + - 'helm-charts/gitea-mirror/**' + - '.github/workflows/helm-test.yml' + - '.github/ci/values-ci.yaml' workflow_dispatch: jobs: From 6fd2774d437c8b9d9e6821b2e2cc96829fe67ab6 Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 27 Sep 2025 15:13:54 +0200 Subject: [PATCH 16/20] Fix MIRROR_STARRED var --- helm/gitea-mirror/templates/configmap.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml index 9c4a909..9a9991f 100644 --- a/helm/gitea-mirror/templates/configmap.yaml +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -16,7 +16,7 @@ data: GITHUB_USERNAME: {{ $gm.github.username | quote }} GITHUB_TYPE: {{ $gm.github.type | quote }} PRIVATE_REPOSITORIES: {{ $gm.github.privateRepositories | quote }} - MIRROR_STARRED: {{ $gm.mirror.starred | quote }} + MIRROR_STARRED: {{ $gm.github.mirrorStarred | quote }} SKIP_FORKS: {{ $gm.github.skipForks | quote }} SKIP_STARRED_ISSUES: {{ $gm.github.skipStarredIssues | quote }} # Gitea Config From cf5027bafc4bbbfa740a50fa50129539d22e271b Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 27 Sep 2025 15:15:42 +0200 Subject: [PATCH 17/20] Fix CLEANUP_RETENTION_DAYS --- helm/gitea-mirror/README.md | 2 +- helm/gitea-mirror/templates/configmap.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/helm/gitea-mirror/README.md b/helm/gitea-mirror/README.md index f612a20..f4d663c 100644 --- a/helm/gitea-mirror/README.md +++ b/helm/gitea-mirror/README.md @@ -206,7 +206,7 @@ These values populate a **ConfigMap** (non-secret) and a **Secret** (for tokens | `gitea-mirror.automation.schedule_enabled` | `true` | `SCHEDULE_ENABLED` | | `gitea-mirror.automation.schedule_interval` | `3600` | `SCHEDULE_INTERVAL` (seconds) | | `gitea-mirror.cleanup.enabled` | `true` | `CLEANUP_ENABLED` | -| `gitea-mirror.cleanup.retentionDays` | `30` | `CLEANUP_INTERVAL` | +| `gitea-mirror.cleanup.retentionDays` | `30` | `CLEANUP_RETENTION_DAYS` | > **Secrets:** If you set `gitea-mirror.existingSecret` (name of an existing Secret), the chart will **not** create its own Secret and will reference yours instead. Otherwise it creates a Secret with `GITHUB_TOKEN`, `GITEA_TOKEN`, `ENCRYPTION_SECRET`. diff --git a/helm/gitea-mirror/templates/configmap.yaml b/helm/gitea-mirror/templates/configmap.yaml index 9a9991f..c9acfe7 100644 --- a/helm/gitea-mirror/templates/configmap.yaml +++ b/helm/gitea-mirror/templates/configmap.yaml @@ -35,4 +35,4 @@ data: SCHEDULE_INTERVAL: {{ $gm.automation.schedule_interval | quote }} # Cleanup CLEANUP_ENABLED: {{ $gm.cleanup.enabled | quote }} - CLEANUP_INTERVAL: {{ $gm.cleanup.interval | quote }} + CLEANUP_RETENTION_DAYS: {{ $gm.cleanup.retentionDays | quote }} From 9c1ac76ff9b792d47564b900415b0f2c9e02f48c Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 27 Sep 2025 15:18:52 +0200 Subject: [PATCH 18/20] Fix annotations --- helm/gitea-mirror/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helm/gitea-mirror/templates/deployment.yaml b/helm/gitea-mirror/templates/deployment.yaml index d57e3c2..34e02a2 100644 --- a/helm/gitea-mirror/templates/deployment.yaml +++ b/helm/gitea-mirror/templates/deployment.yaml @@ -5,7 +5,7 @@ metadata: name: {{ include "gitea-mirror.fullname" . }} {{- with .Values.deployment.annotations }} annotations: - {{- toYaml .Values.deployment.annotations | nindent 4 }} + {{- toYaml . | nindent 4 }} {{- end }} labels: {{- include "gitea-mirror.labels" . | nindent 4 }} From 1f98f441f32a27eddd038403b788b87001887c5d Mon Sep 17 00:00:00 2001 From: V-Paranoiaque Date: Sat, 27 Sep 2025 18:28:10 +0200 Subject: [PATCH 19/20] Fix ingress + improve testing --- .github/workflows/helm-test.yml | 4 ++++ helm/gitea-mirror/templates/ingress.yaml | 4 ++-- helm/gitea-mirror/values.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml index 4127a75..2aa11aa 100644 --- a/.github/workflows/helm-test.yml +++ b/.github/workflows/helm-test.yml @@ -2,6 +2,10 @@ name: Helm Chart CI on: pull_request: + paths: + - 'helm-charts/gitea-mirror/**' + - '.github/workflows/helm-test.yml' + - '.github/ci/values-ci.yaml' push: branches: [ main ] paths: diff --git a/helm/gitea-mirror/templates/ingress.yaml b/helm/gitea-mirror/templates/ingress.yaml index 1fff62c..6458752 100644 --- a/helm/gitea-mirror/templates/ingress.yaml +++ b/helm/gitea-mirror/templates/ingress.yaml @@ -28,8 +28,8 @@ spec: - host: {{ tpl .host $ | quote }} http: paths: - - path: "/" - pathType: "Prefix" + - path: {{ .path | default "/" }} + pathType: {{ .pathType | default "Prefix" }} backend: service: name: {{ include "gitea-mirror.fullname" $ }} diff --git a/helm/gitea-mirror/values.yaml b/helm/gitea-mirror/values.yaml index f711daa..41121c8 100644 --- a/helm/gitea-mirror/values.yaml +++ b/helm/gitea-mirror/values.yaml @@ -15,12 +15,12 @@ podSecurityContext: ingress: enabled: false className: "" - pathType: Prefix annotations: {} hosts: - host: mirror.example.com paths: - path: / + pathType: Prefix tls: [] # - secretName: chart-example-tls # hosts: From 63f20a7f04534a66bf6c1c01b200d65ef88b0c4f Mon Sep 17 00:00:00 2001 From: "Virgil R." Date: Tue, 30 Sep 2025 20:07:48 +0200 Subject: [PATCH 20/20] Update helm-test.yml --- .github/workflows/helm-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml index 2aa11aa..18ec940 100644 --- a/.github/workflows/helm-test.yml +++ b/.github/workflows/helm-test.yml @@ -3,13 +3,13 @@ name: Helm Chart CI on: pull_request: paths: - - 'helm-charts/gitea-mirror/**' + - 'helm/gitea-mirror/**' - '.github/workflows/helm-test.yml' - '.github/ci/values-ci.yaml' push: branches: [ main ] paths: - - 'helm-charts/gitea-mirror/**' + - 'helm/gitea-mirror/**' - '.github/workflows/helm-test.yml' - '.github/ci/values-ci.yaml' workflow_dispatch: