feat: deploy Forgejo self-hosted git server
- Add ZFS NFS datasets: media-pool/git (50G) and media-pool/git-db (10G) - Add nfs-git and nfs-git-db NFS subdir provisioner Helm values - Deploy Forgejo 10 (StatefulSet) + PostgreSQL 16 (StatefulSet) in infrastructure namespace - StorageClasses: nfs-git (repos/LFS, 50Gi) and nfs-git-db (postgres, 10Gi) - Ingress: git.vandachevici.ro with TLS via cert-manager - SSH NodePort 30022 for git clone ssh://git@host:30022/user/repo.git - Authentik OIDC provider configured (client ID: ZdnrHgyfUncSIPPrOe1o7UAA42N7BMhUHXjQVw4Y) - Add 'git' subdomain to dns-updater configmap Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
29440b68a9
commit
88540b6ded
4 changed files with 420 additions and 0 deletions
14
deployment/helm/nfs-provisioners/values-git-db.yaml
Normal file
14
deployment/helm/nfs-provisioners/values-git-db.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
nfs:
|
||||
mountOptions:
|
||||
- soft
|
||||
- timeo=30
|
||||
path: /media-pool/git-db
|
||||
server: 192.168.2.193
|
||||
storageClass:
|
||||
allowVolumeExpansion: true
|
||||
archiveOnDelete: true
|
||||
defaultClass: false
|
||||
mountOptions:
|
||||
- soft
|
||||
- timeo=30
|
||||
name: nfs-git-db
|
||||
14
deployment/helm/nfs-provisioners/values-git.yaml
Normal file
14
deployment/helm/nfs-provisioners/values-git.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
nfs:
|
||||
mountOptions:
|
||||
- soft
|
||||
- timeo=30
|
||||
path: /media-pool/git
|
||||
server: 192.168.2.193
|
||||
storageClass:
|
||||
allowVolumeExpansion: true
|
||||
archiveOnDelete: true
|
||||
defaultClass: false
|
||||
mountOptions:
|
||||
- soft
|
||||
- timeo=30
|
||||
name: nfs-git
|
||||
72
deployment/infrastructure/dns-updater.yaml
Normal file
72
deployment/infrastructure/dns-updater.yaml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations: {}
|
||||
name: dns-updater-config
|
||||
namespace: infrastructure
|
||||
data:
|
||||
DOMAIN: vandachevici.ro
|
||||
NAME: photos;backup;media;chat;openttd;excalidraw;prv;drive;grafana;paperclip;proxmox;parts;dns;games;git
|
||||
REMOVE_DUPLICATES: 'true'
|
||||
SLEEP_INTERVAL: '60'
|
||||
---
|
||||
# NOTE: Secret 'dns-updater-secret' must be created manually:
|
||||
# kubectl create secret generic dns-updater-secret \
|
||||
# --from-literal=digitalocean-token=<YOUR_TOKEN> \
|
||||
# -n infrastructure
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
annotations: {}
|
||||
labels:
|
||||
app: dns-updater
|
||||
name: dns-updater
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: dns-updater
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: dns-updater
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: DIGITALOCEAN_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: digitalocean-token
|
||||
name: dns-updater-secret
|
||||
- name: DOMAIN
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: DOMAIN
|
||||
name: dns-updater-config
|
||||
- name: NAME
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: NAME
|
||||
name: dns-updater-config
|
||||
- name: SLEEP_INTERVAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: SLEEP_INTERVAL
|
||||
name: dns-updater-config
|
||||
- name: REMOVE_DUPLICATES
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
key: REMOVE_DUPLICATES
|
||||
name: dns-updater-config
|
||||
image: tunix/digitalocean-dyndns:latest
|
||||
name: dns-updater
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
restartPolicy: Always
|
||||
320
deployment/infrastructure/forgejo.yaml
Normal file
320
deployment/infrastructure/forgejo.yaml
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
---
|
||||
# Forgejo git server + PostgreSQL database
|
||||
# Domain: git.vandachevici.ro
|
||||
# Auth: Authentik OIDC (configured post-deploy via admin UI)
|
||||
# Storage: NFS on HP ProLiant (media-pool/git, media-pool/git-db)
|
||||
# SSH: NodePort 30022 (clone with: git clone ssh://git@<host>:30022/<user>/<repo>.git)
|
||||
#
|
||||
# Initial deploy steps after applying:
|
||||
# 1. Create Authentik OIDC provider (see plan.md todo: authentik-oidc)
|
||||
# 2. In Forgejo admin: Site Administration → Authentication Sources → Add OAuth2 Source
|
||||
# - Provider: OpenID Connect
|
||||
# - Name: authentik
|
||||
# - Client ID/Secret: from Authentik
|
||||
# - OpenID Discovery URL: https://auth.vandachevici.ro/application/o/forgejo/.well-known/openid-configuration
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: forgejo-db-secret
|
||||
namespace: infrastructure
|
||||
type: Opaque
|
||||
stringData:
|
||||
POSTGRES_DB: forgejo
|
||||
POSTGRES_USER: forgejo
|
||||
POSTGRES_PASSWORD: Hg9mKnRpQwXvTz2Ld8cJsY4bAeUfN6
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: forgejo-secret
|
||||
namespace: infrastructure
|
||||
type: Opaque
|
||||
stringData:
|
||||
# Random secret key for Forgejo session/cookie signing
|
||||
# Generate with: openssl rand -hex 32
|
||||
secret-key: 5f323a291b24ba0d83c5df56569eeeb44e5eda0bcfc9f3d9601d5ab46f5f3754
|
||||
|
||||
---
|
||||
# PostgreSQL for Forgejo
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: forgejo-db-pvc
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 10Gi
|
||||
storageClassName: nfs-git-db
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: forgejo-db
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: forgejo-db
|
||||
serviceName: forgejo-db
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: forgejo-db
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16-alpine
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
name: postgres
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-db-secret
|
||||
key: POSTGRES_DB
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-db-secret
|
||||
key: POSTGRES_USER
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-db-secret
|
||||
key: POSTGRES_PASSWORD
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
volumeMounts:
|
||||
- name: db-data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- pg_isready
|
||||
- -U
|
||||
- forgejo
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
failureThreshold: 5
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- pg_isready
|
||||
- -U
|
||||
- forgejo
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: db-data
|
||||
persistentVolumeClaim:
|
||||
claimName: forgejo-db-pvc
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: forgejo-db
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
selector:
|
||||
app: forgejo-db
|
||||
ports:
|
||||
- name: postgres
|
||||
port: 5432
|
||||
targetPort: 5432
|
||||
|
||||
---
|
||||
# Forgejo git server
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: forgejo-data-pvc
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 50Gi
|
||||
storageClassName: nfs-git
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: forgejo
|
||||
serviceName: forgejo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: forgejo
|
||||
spec:
|
||||
initContainers:
|
||||
- name: wait-for-db
|
||||
image: busybox:1.36
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
until nc -z forgejo-db 5432; do
|
||||
echo "Waiting for PostgreSQL..."
|
||||
sleep 2
|
||||
done
|
||||
echo "PostgreSQL is ready"
|
||||
containers:
|
||||
- name: forgejo
|
||||
image: codeberg.org/forgejo/forgejo:10
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
name: http
|
||||
- containerPort: 22
|
||||
name: ssh
|
||||
env:
|
||||
- name: FORGEJO__database__DB_TYPE
|
||||
value: postgres
|
||||
- name: FORGEJO__database__HOST
|
||||
value: forgejo-db:5432
|
||||
- name: FORGEJO__database__NAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-db-secret
|
||||
key: POSTGRES_DB
|
||||
- name: FORGEJO__database__USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-db-secret
|
||||
key: POSTGRES_USER
|
||||
- name: FORGEJO__database__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-db-secret
|
||||
key: POSTGRES_PASSWORD
|
||||
- name: FORGEJO__server__DOMAIN
|
||||
value: git.vandachevici.ro
|
||||
- name: FORGEJO__server__ROOT_URL
|
||||
value: https://git.vandachevici.ro
|
||||
- name: FORGEJO__server__SSH_DOMAIN
|
||||
value: git.vandachevici.ro
|
||||
- name: FORGEJO__server__SSH_PORT
|
||||
value: "30022"
|
||||
- name: FORGEJO__server__SSH_LISTEN_PORT
|
||||
value: "22"
|
||||
- name: FORGEJO__security__SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: forgejo-secret
|
||||
key: secret-key
|
||||
- name: FORGEJO__service__DISABLE_REGISTRATION
|
||||
value: "false"
|
||||
- name: FORGEJO__service__REQUIRE_SIGNIN_VIEW
|
||||
value: "false"
|
||||
volumeMounts:
|
||||
- name: forgejo-data
|
||||
mountPath: /data
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 15
|
||||
failureThreshold: 5
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: forgejo-data
|
||||
persistentVolumeClaim:
|
||||
claimName: forgejo-data-pvc
|
||||
|
||||
---
|
||||
# ClusterIP for HTTP (used by ingress)
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
selector:
|
||||
app: forgejo
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
|
||||
---
|
||||
# NodePort for SSH git access (git clone ssh://git@git.vandachevici.ro:30022/user/repo.git)
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: forgejo-ssh
|
||||
namespace: infrastructure
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
app: forgejo
|
||||
ports:
|
||||
- name: ssh
|
||||
port: 22
|
||||
targetPort: 22
|
||||
nodePort: 30022
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: forgejo
|
||||
namespace: infrastructure
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: git.vandachevici.ro
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: forgejo
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- git.vandachevici.ro
|
||||
secretName: forgejo-tls
|
||||
Loading…
Add table
Reference in a new issue