Compare commits

...

24 Commits
master ... k3s

Author SHA1 Message Date
c5db342dcf feat(manifests): Add db monitoring 2024-12-18 14:20:54 +01:00
3e765d1b4d refactor(db): Bump replica count to 3 2024-12-17 12:42:51 +01:00
c388a9c8e3 feat(backups): Add recurring job group labels 2024-12-05 21:42:27 +01:00
549ecf4cc8 feat(ingress): Move to Nginx Ingress Controller 2024-12-05 14:10:50 +01:00
96f0aba576 feat(backups): Add recovery plan for database 2024-12-05 14:10:50 +01:00
a1ec506af9 fix(backups): Move to 6 char cron values, making the backup once a day at midnight 2024-12-02 12:03:25 +01:00
0fc7740ac3 feat(backups): Configure WAL and schedule backups 2024-12-01 23:20:02 +01:00
a54c41da9d feat: Upgrade version and add SSL certificate 2024-11-27 13:43:28 +01:00
a7a03b2608 feat(ssl): Move to cert-manager 2024-11-17 21:18:02 +01:00
98a35e475e feat(secrets): Move domain to halis.io for sub application 2024-11-11 18:32:38 +01:00
f8346fbe7b fix(ingress): Update certResolver 2024-11-11 14:07:04 +01:00
3525387799 feat: Upgrade configuration for production 2024-11-11 13:45:31 +01:00
fc49a6f412 feat: Bump replica count and remove node selector 2024-01-20 00:28:51 +01:00
3be7d9715f feat(secrets): Implement auto secret synchronization 2024-01-14 02:05:30 +01:00
39b680f3cf feat(db): Migrate to CloudNativePG 2024-01-14 00:09:47 +01:00
1830d126a5 feat(metrics): Add metric scraping
Add ServiceMonitor resource to scrape /metrics endpoint.
Said endpoint cannot be scrapped from outside of the cluster, as a special IngressRoute Middleware prevents the exposition of said endpoint.
2023-07-06 13:49:33 +02:00
5452633f37 feat(init): Add initial installation for admin user 2023-07-04 17:15:04 +02:00
c61680ebf8 fix(conf): Add configmap to kustomization file 2023-07-03 12:42:25 +02:00
1d8b044742 fix(conf): Add config volume mounting 2023-07-03 12:41:15 +02:00
f137e1b0ab fix(env): Correct env variables for database 2023-07-03 12:29:17 +02:00
166fed1741 feat(config): Add configmap for auto provisioning 2023-07-03 12:12:23 +02:00
3245780088 fix(manifest): Fix port routing 2023-06-30 23:42:51 +02:00
793193943e fix(manifest): Fix container image version 2023-06-30 23:40:11 +02:00
6bb2dc2d16 feat(manifests): Add k8s manifests for argo based deployment 2023-06-30 23:22:44 +02:00
16 changed files with 493 additions and 0 deletions

49
README.md Normal file
View File

@ -0,0 +1,49 @@
# Gitea
Front end for Git, with integrated Container Registry and CI/CD capabilities.
This repository only contains configuration used for Kubernetes.
## From Docker to Gitea
Get a dump of your current Docker instance:
```bash
gitea dump -c /data/gitea/conf/app.ini
```
In this context, my `/data` path is mounted to the host.
Then modify the `deployment.yaml` file to only start a "sleeping" container:
```yaml
[...]
image: gitea/gitea:1.22.3
ports:
- containerPort: 3000
command: ["/bin/sh", "-c", "sleep 1000000000"] # Add this line
env:
- name: GITEA__database__DB_TYPE
value: "postgres"
[...]
```
Then, copy the dump to the container:
```bash
kubectl cp <dump file> <namespace>/<pod name>:/data/dump
```
Get into the pod and go as follows.
Unzip the dump
```bash
unzip <dump file>
```
Then, restore the dump
```bash
mv repo/* /data/git/repositories
mv lfs/* /data/git/lfs
mv data/* /data/gitea
```
And finally, restore the database
```bash
PGPASSWORD=$GITEA__database__PASSWD psql -h gitea-db-rw.gitea.svc.cluster.local -U $GITEA__database__USER < halis_gitea.sql
```

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: gitea-admin-creator
namespace: gitea
data:
admin-creator.sh: |
#!/bin/sh
gitea admin user list --admin | grep $(echo ' ' $ADMIN_USER ' ') >/dev/null 2>&1
if [ $? -eq 1 ];
then
gitea admin user create --username $ADMIN_USER --password $ADMIN_PASSWORD --email $ADMIN_MAIL --admin
fi

View File

@ -0,0 +1,12 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: gitea
namespace: gitea
spec:
secretName: git-halis-io-tls
dnsNames:
- git.halis.io
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer

98
manifests/configmap.yaml Normal file
View File

@ -0,0 +1,98 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: gitea-config
namespace: gitea
data:
APP_NAME: Halis hosted git solution
RUN_MODE: prod
GITEA__server__DISABLE_SSH: "true"
GITEA__server__ROOT_URL: "https://git.halis.io"
GITEA__security__INSTALL_LOCK: "true"
GITEA__service__DISABLE_REGISTRATION: "true"
GITEA__metrics__ENABLED: "true"
GITEA__queue__TYPE: "level"
#GITEA__indexer__REPO_INDEXER_ENABLED: "false"
#app.ini: |
# APP_NAME = K8s implementation
# RUN_MODE = prod
# RUN_USER = git
# [repository]
# ROOT = /data/git/repositories
# [repository.local]
# LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
# [repository.upload]
# TEMP_PATH = /data/gitea/uploads
# [server]
# APP_DATA_PATH = /data/gitea
# DOMAIN = localhost
# SSH_DOMAIN = localhost
# HTTP_PORT = 3000
# ROOT_URL = http://localhost:3000/
# SSH_PORT = 22
# SSH_LISTEN_PORT = 22
# LFS_START_SERVER = true
# OFFLINE_MODE = false
# [indexer]
# ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
# [session]
# PROVIDER_CONFIG = /data/gitea/sessions
# PROVIDER = file
# [picture]
# AVATAR_UPLOAD_PATH = /data/gitea/avatars
# REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
# [attachment]
# PATH = /data/gitea/attachments
# [log]
# MODE = console
# LEVEL = info
# ROUTER = console
# ROOT_PATH = /data/gitea/log
# [security]
# SECRET_KEY = NONE
# REVERSE_PROXY_LIMIT = 1
# REVERSE_PROXY_TRUSTED_PROXIES = *
# PASSWORD_HASH_ALGO = pbkdf2
# [service]
# REQUIRE_SIGNIN_VIEW = false
# REGISTER_EMAIL_CONFIRM = false
# ENABLE_NOTIFY_MAIL = false
# ALLOW_ONLY_EXTERNAL_REGISTRATION = false
# ENABLE_CAPTCHA = false
# DEFAULT_KEEP_EMAIL_PRIVATE = false
# DEFAULT_ALLOW_CREATE_ORGANIZATION = true
# DEFAULT_ENABLE_TIMETRACKING = true
# NO_REPLY_ADDRESS = noreply.localhost
# [lfs]
# PATH = /data/git/lfs
# [mailer]
# ENABLED = false
# [openid]
# ENABLE_OPENID_SIGNIN = true
# ENABLE_OPENID_SIGNUP = true
# [cron.update_checker]
# ENABLED = false
# [repository.pull-request]
# DEFAULT_MERGE_STYLE = merge
# [repository.signing]
# DEFAULT_TRUST_MODEL = committer
# [oauth2]
# ENABLE = false

View File

@ -0,0 +1,10 @@
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: gitea-db-backup
namespace: gitea
spec:
schedule: "0 0 0 * * *"
backupOwnerReference: self
cluster:
name: gitea-db

View File

@ -0,0 +1,8 @@
apiVersion: postgresql.cnpg.io/v1
kind: Backup
metadata:
name: gitea-db-ondemand-backup
namespace: gitea
spec:
cluster:
name: gitea-db

View File

@ -0,0 +1,48 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: gitea-db
namespace: gitea
spec:
instances: 2
storage:
size: 1Gi
storageClass: local-path
bootstrap:
recovery:
source: gitea-db
postgresql:
pg_hba:
- host all all all md5
externalClusters:
- name: gitea-db
barmanObjectStore:
serverName: gitea-db
destinationPath: "s3://halis/cloudnativepg"
endpointURL: https://s3.halia.dev
s3Credentials:
accessKeyId:
name: s3-secret
key: AWS_ACCESS_KEY_ID
secretAccessKey:
name: s3-secret
key: AWS_SECRET_ACCESS_KEY
region:
name: s3-secret
key: AWS_REGION
wal:
compression: gzip
maxParallel: 8
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 500m
memory: 500Mi

52
manifests/database.yaml Normal file
View File

@ -0,0 +1,52 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: gitea-db
namespace: gitea
spec:
instances: 3
storage:
size: 1Gi
storageClass: local-path
bootstrap:
initdb:
database: gitea
owner: gitea
secret:
name: gitea-db
postgresql:
pg_hba:
- host all all all md5
backup:
barmanObjectStore:
destinationPath: "s3://halis/cloudnativepg"
endpointURL: https://s3.halia.dev
s3Credentials:
accessKeyId:
name: s3-secret
key: AWS_ACCESS_KEY_ID
secretAccessKey:
name: s3-secret
key: AWS_SECRET_ACCESS_KEY
region:
name: s3-secret
key: AWS_REGION
wal:
compression: gzip
maxParallel: 8
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 500m
memory: 500Mi
monitoring:
enablePodMonitor: true

85
manifests/deployment.yaml Normal file
View File

@ -0,0 +1,85 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: gitea
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
hostname: gitea
subdomain: gitea
containers:
- name: gitea
image: gitea/gitea:1.22.4
ports:
- containerPort: 3000
env:
- name: GITEA__database__DB_TYPE
value: "postgres"
- name: GITEA__database__HOST
value: "gitea-db-rw.gitea.svc.cluster.local:5432"
- name: GITEA__database__NAME
value: "gitea"
- name: GITEA__database__SSL_MODE
value: "require"
- name: GITEA__database__USER
valueFrom:
secretKeyRef:
name: gitea-db
key: username
- name: GITEA__database__PASSWD
valueFrom:
secretKeyRef:
name: gitea-db
key: password
- name: GITEA__server__LFS_JWT_SECRET
valueFrom:
secretKeyRef:
name: gitea-lfs-jwt-secret
key: token
- name: GITEA__security__INTERNAL_TOKEN
valueFrom:
secretKeyRef:
name: gitea-internal-token
key: token
- name: ADMIN_USER
valueFrom:
secretKeyRef:
name: gitea-admin-user
key: token
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: gitea-admin-password
key: token
- name: ADMIN_MAIL
valueFrom:
secretKeyRef:
name: gitea-admin-mail
key: token
envFrom:
- configMapRef:
name: gitea-config
volumeMounts:
- mountPath: "/admin-creator.sh"
name: gitea-admin-creator
subPath: admin-creator.sh
- mountPath: "/data"
name: gitea-data
volumes:
- name: gitea-data
persistentVolumeClaim:
claimName: gitea-pvc
- name: gitea-config-volume
configMap:
name: gitea-config
- name: gitea-admin-creator
configMap:
name: gitea-admin-creator

28
manifests/ingress.yaml Normal file
View File

@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea-ingress
namespace: gitea
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
kubernetes.io/ingress.class: nginx-external
acme.cert-manager.io/http01-edit-in-place: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/metrics(/?)$ https://git.halis.io/$1 permanent;
spec:
tls:
- hosts:
- git.halis.io
secretName: git-halis-io-tls
ingressClassName: nginx-external
rules:
- host: git.halis.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea-svc
port:
number: 80

View File

@ -0,0 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- secrets.yaml
- database.yaml
- database-backup.yaml
- service.yaml
- servicemonitor.yaml
- ingress.yaml
- configmap.yaml
- admin-creator.yaml
- pvc.yaml
- deployment.yaml

4
manifests/namespace.yaml Normal file
View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: gitea

15
manifests/pvc.yaml Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-pvc
namespace: gitea
labels:
recurring-job.longhorn.io/source: enabled
recurring-job-group.longhorn.io/standard-pvc: enabled
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 15Gi
storageClassName: redundant-storage-class

24
manifests/secrets.yaml Normal file
View File

@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitea-secrets
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://git.halis.io/athens-school/k3s-secrets
targetRevision: prod-migration
path: gitea
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
- ApplyOutOfSyncOnly=true
- PruneLast=true
destination:
server: https://kubernetes.default.svc
namespace: gitea

15
manifests/service.yaml Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: gitea-svc
namespace: gitea
labels:
app.kubernetes.io/name: gitea
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 3000
selector:
app: gitea

View File

@ -0,0 +1,14 @@
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: gitea
namespace: gitea
labels:
team: core
spec:
selector:
matchLabels:
app.kubernetes.io/name: gitea
endpoints:
- port: http
path: /metrics