Compare commits

...

17 Commits

Author SHA1 Message Date
Márcio Fernandes
3ab4f3b8fa modified: deploy/app/helm-values.yaml
All checks were successful
/ continuous-deploy (push) Successful in 22s
2026-04-26 22:00:40 +00:00
Márcio Fernandes
d4f8664bc6 helm chart version version 12.5.3
All checks were successful
/ continuous-deploy (push) Successful in 19s
2026-04-25 21:51:02 +00:00
Márcio Fernandes
8730c3217b mf-ci-cd
All checks were successful
/ continuous-deploy (push) Successful in 19s
2026-04-18 23:14:14 +00:00
Márcio Fernandes
20360ff1dc network policy: remove 2222 from traefik public ingress
All checks were successful
/ continuous-deploy (push) Successful in 18s
2026-04-12 13:21:30 +00:00
Márcio Fernandes
0599b3d41a ingress revision
All checks were successful
/ continuous-deploy (push) Successful in 20s
2026-04-09 12:34:45 +00:00
Márcio Fernandes
d19eb21529 offsite backup fix packages wrong path, set max offsite size to 5Gb, reset borg repo
All checks were successful
/ continuous-deploy (push) Successful in 19s
2026-03-30 23:46:41 +00:00
Márcio Fernandes
87dc556748 modified: deploy/infra/network-policies.yaml
All checks were successful
/ continuous-deploy (push) Successful in 22s
2026-03-30 00:29:50 +00:00
Márcio Fernandes
4bcb91109c network policies simplification, fix certificate typo
All checks were successful
/ continuous-deploy (push) Successful in 22s
2026-03-29 21:37:33 +00:00
Márcio Fernandes
deb846ad19 modified: deploy/backups/.env.d/secrets.example
All checks were successful
/ continuous-deploy (push) Successful in 25s
2026-03-29 18:00:08 +00:00
Márcio Fernandes
4287af948b act runners add access to buildkit srv
All checks were successful
/ continuous-deploy (push) Successful in 23s
2026-03-28 10:48:24 +00:00
Márcio Fernandes
5861efb310 kb act runner add access to buildkit
All checks were successful
/ continuous-deploy (push) Successful in 20s
2026-03-28 10:39:01 +00:00
Márcio Fernandes
fb8a34ba7a fix: public ingress route
All checks were successful
/ continuous-deploy (push) Successful in 21s
2026-03-28 09:27:37 +00:00
Márcio Fernandes
b02303d51e added SSO, ingress to ingressRoute
All checks were successful
/ continuous-deploy (push) Successful in 19s
2026-03-28 00:44:00 +00:00
Márcio Fernandes
9b36b595b8 deploy: clean up network policies
All checks were successful
/ continuous-deploy (push) Successful in 20s
2026-03-22 13:07:25 +00:00
Márcio Fernandes
a0860185d6 modified: deploy/act-runners/mf/deploy/app/configmap.yaml
Some checks failed
/ continuous-deploy (push) Failing after 8s
2026-03-20 14:56:09 +00:00
Márcio Fernandes
fe74820aea act-runners: add mf act runner
All checks were successful
/ continuous-deploy (push) Successful in 18s
2026-03-20 14:17:06 +00:00
Márcio Fernandes
694756815f normalization of backups jobs names
All checks were successful
/ continuous-deploy (push) Successful in 18s
2026-03-20 09:47:44 +00:00
31 changed files with 316 additions and 187 deletions

View File

@@ -4,12 +4,17 @@ Welcome to public repository of my [Git Server](https://git.limbosolutions.com)
Using [gitea](https://git.limbosolutions.com/kb/gitea) as git server.
- [SSO](#sso)
- [Deploy](#deploy)
- [Continuous Deploy](#continuous-deploy)
- [App](#app)
- [Infra](#infra)
- [Backups](#backups)
## SSO
<https://integrations.goauthentik.io/development/gitea/>
## Deploy
References:

View File

@@ -13,6 +13,7 @@ spec:
metadata:
labels:
app: act-runner
buildkit.infra.limbosolutions.com/allow-build: "true"
spec:
containers:
- name: act-runner

View File

@@ -13,6 +13,7 @@ spec:
metadata:
labels:
app: act-runner
buildkit.infra.limbosolutions.com/allow-build: "true"
spec:
containers:
- name: act-runner

View File

@@ -0,0 +1,13 @@
# mylimbo - act-runner
**Deploy app:**
```bash
./deploy/ops-scripts/apply-app.sh
```
**Deploy Infra:**
```bash
./deploy/ops-scripts/apply-infra.sh
```

View File

@@ -1,3 +1,2 @@
**
!.gitignore
!*.example

View File

@@ -0,0 +1,26 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: act-runner
data:
config.yaml: |
log:
level: info
runner:
capacity: 1
labels:
- oci-image-builder
- kubectl
- helm
- ansible
- ubuntu
- network-utils
- deploy
- amd64
- limbosolutions-com
cache:
enabled: false
host:
workdir: "/data/runner"

View File

@@ -0,0 +1,67 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: act-runner
labels:
app: act-runner
spec:
replicas: 1
selector:
matchLabels:
app: act-runner
template:
metadata:
labels:
app: act-runner
buildkit.infra.limbosolutions.com/allow-build: "true"
spec:
containers:
- name: act-runner
image: git.limbosolutions.com/kb/gitea/act_runner:0.3-fatboy
imagePullPolicy: Always
env:
- name: LOG_LEVEL
value: "trace"
- name: CONFIG_FILE
value: /etc/act_runner/config.yaml
- name: GITEA_INSTANCE_URL
valueFrom:
secretKeyRef:
name: act-runner
key: GITEA_INSTANCE_URL
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: act-runner
key: GITEA_RUNNER_REGISTRATION_TOKEN
- name: GITEA_RUNNER_NAME
valueFrom:
secretKeyRef:
name: act-runner
key: GITEA_RUNNER_NAME
- name: GITEA_RUNNER_EPHEMERAL
value: "0"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "1024Mi"
cpu: "1000m"
volumeMounts:
- name: config-map
mountPath: /etc/act_runner/config.yaml
subPath: config.yaml
- name: runner-data
mountPath: /data/runner
volumes:
- name: config-map
configMap:
name: act-runner
- name: runner-data
emptyDir: {} # or PVC if you want persistence across pod restarts

View File

@@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
- deployment.yaml
generatorOptions:
disableNameSuffixHash: true
secretGenerator:
- name: act-runner
envs:
- .env.d/.env

View File

@@ -0,0 +1,4 @@
#!/bin/bash
set -e
NAMESPACE=mf-cicd
kubectl kustomize deploy/app | kubectl --namespace ${NAMESPACE} apply -f -

View File

@@ -0,0 +1,4 @@
#!/bin/bash
set -e
NAMESPACE=mf-cicd
kubectl create namespace ${NAMESPACE} || true

View File

@@ -13,6 +13,7 @@ spec:
metadata:
labels:
app: act-runner
buildkit.infra.limbosolutions.com/allow-build: "true"
spec:
containers:
- name: act-runner

View File

@@ -1,5 +1,8 @@
global:
# forcing docker.io to use cache from harbor
imageRegistry: "docker.io"
image:
registry: ""
# IMPORTANT:
# The default image used by the Gitea Helm chart is the *rootless* variant.
# Rootless Gitea does NOT include an SSH server, so enabling SSH in the chart
@@ -15,9 +18,6 @@ image:
# This ensures the container includes OpenSSH and can expose the SSH port.
repository: gitea/gitea
pullPolicy: Always
tag: 1
# dependency:
# https://github.com/bitnami/charts/blob/main/bitnami/valkey-cluster/Chart.yaml
valkey-cluster:
enabled: false
@@ -92,9 +92,9 @@ postgresql-ha:
postgresql:
enabled: true
image:
repository: bitnami/postgresql
repository: bitnamilegacy/postgresql
tag: 16
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
global:
postgresql:
auth:
@@ -152,10 +152,9 @@ persistence:
service:
ssh:
type: LoadBalancer
enabled: true
clusterIP: "" # empty string → Kubernetes assigns a routable ClusterIP
type: ClusterIP
port: 2222
externalTrafficPolicy: Local
http:
clusterIP: "" # empty string → Kubernetes assigns a routable ClusterIP
type: ClusterIP

View File

@@ -1,6 +1,6 @@
PBS_REPOSITORY="pbs repository"
PBS_PASSWORD="pbs access password"
PBS_FINGERPRINT="00:00:00:00:00" # the pbs finger print
PBS_REPOSITORY=xxx@pbs@server_address:collection
PBS_PASSWORD=pbs access password
PBS_FINGERPRINT=00:00:00:00:00 # pbs server fingerprint
BORG_REPO="ssh://user@server/path" # required by offsite backup
BORG_PASSPHRASE="borg passphrase" # required by offsite backup
OFFSITE_TARGET_FOLDER="test:target_path" # follow rclone naming convention

View File

@@ -12,11 +12,12 @@ spec:
template:
metadata:
labels:
app: offsite-backup
dbAccess: "true"
backups.infra.limbosolutions.com/ssh: "true"
spec:
restartPolicy: Never
initContainers:
- name: postgres-export
- name: postgres
resources:
limits:
memory: "512Mi"
@@ -46,7 +47,7 @@ spec:
containers:
- name: borg-client
- name: borg-backup
image: git.limbosolutions.com/kb/borg-backup:latest
imagePullPolicy: Always
resources:
@@ -81,7 +82,7 @@ spec:
value: ssh -p 2222 -o StrictHostKeyChecking=no -o LogLevel=ERROR
- name: REPO_SYNC_MAX_SIZE
value: "21474836480" # 20GB
value: "5368709120" # 5GB
- name: MODE
value: SHELL
@@ -98,7 +99,7 @@ spec:
# done
borg create ${BORG_REPO}::postgresql-export-$(date +%Y%m%d%H%M%S) /data/postgresql-export
borg create ${BORG_REPO}::gitea-data-$(date +%Y%m%d%H%M%S) /data/gitea-data --exclude /data/packages --exclude /data/tmp
borg create ${BORG_REPO}::gitea-data-$(date +%Y%m%d%H%M%S) /data/gitea-data --exclude /data/gitea-data/packages --exclude /data/gitea-data/tmp
#cleanup
borg prune -v --list --keep-daily=10 --keep-weekly=7 --keep-monthly=-1 ${BORG_REPO} --glob-archives='gitea-data*'

View File

@@ -11,11 +11,13 @@ spec:
template:
metadata:
labels:
app: pbs-backup
dbAccess: "true"
app: backup-pbs
backups.infra.limbosolutions.com/pbs: "true"
spec:
restartPolicy: Never
initContainers:
- name: postgres-export
- name: postgres
image: postgres:latest
resources:
limits:
@@ -49,7 +51,7 @@ spec:
readOnly: true
containers:
- name: gitea-pbs-client
- name: pbs-client
image: git.limbosolutions.com/kb/pbs-client
imagePullPolicy: Always
resources:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- cronjobs/borg-offsite-cronjob.yaml
- cronjobs/pbs-cronjob.yaml
- cronjobs/backup-borg-offsite.yaml
- cronjobs/backup-pbs.yaml
secretGenerator:
- name: gitea-backup

View File

@@ -1 +0,0 @@
EGRESS_BACKUPSRV_CIDR="BACKUPSRV-IP-ADDRESS/32"

View File

@@ -0,0 +1,11 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: limbosolutions-com-tls
spec:
secretName: limbosolutions-com-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- git.limbosolutions.com

View File

@@ -0,0 +1,14 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: ssh-public
annotations:
kubernetes.io/ingress.class: traefik-public
spec:
entryPoints:
- tcp2222
routes:
- match: HostSNI(`*`)
services:
- name: gitea-ssh
port: 2222

View File

@@ -0,0 +1,14 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: ssh
annotations:
kubernetes.io/ingress.class: traefik
spec:
entryPoints:
- tcp2222
routes:
- match: HostSNI(`*`)
services:
- name: gitea-ssh
port: 2222

View File

@@ -0,0 +1,17 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: web-public
annotations:
kubernetes.io/ingress.class: traefik-public
spec:
entryPoints:
- websecure
routes:
- match: Host(`git.limbosolutions.com`) && !PathPrefix(`/-/admin`)
kind: Rule
services:
- name: gitea-http
port: 3000
tls:
secretName: limbosolutions-com-tls

View File

@@ -0,0 +1,17 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: web
annotations:
kubernetes.io/ingress.class: traefik
spec:
entryPoints:
- websecure
routes:
- match: Host(`git.limbosolutions.com`)
kind: Rule
services:
- name: gitea-http
port: 3000
tls:
secretName: limbosolutions-com-tls

View File

@@ -1,27 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: git-limbosolutions-com
namespace: git-limbosolutions-com
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure, public-https
spec:
ingressClassName: traefik
rules:
- host: git.limbosolutions.com
http:
paths:
- backend:
service:
name: gitea-http
port:
number: 3000
path: /
pathType: Prefix
tls:
- secretName: limbosolutions-com-tls
hosts:
- "git.limbosolutions.com"

View File

@@ -3,27 +3,13 @@ kind: Kustomization
resources:
- namespace.yaml
- cd-serviceaccount.yaml
- ingress.yaml
- network-policies/egress.yaml
- network-policies/egress-local-services.yaml
- network-policies/ingress.yaml
- network-policies.yaml
- certificate.yaml
- ingress-web.yaml
- ingress-web-public.yaml
- ingress-ssh.yaml
- ingress-ssh-public.yaml
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: infra-setup-vars
namespace: git-limbosolutions-com
envs:
- ./.env.d/.env
replacements:
- source:
kind: ConfigMap
name: infra-setup-vars
fieldPath: data.EGRESS_BACKUPSRV_CIDR
targets:
- select:
kind: NetworkPolicy
name: git-limbosolutions-com-egress-local
fieldPaths:
- spec.egress.0.to.0.ipBlock.cidr

View File

@@ -0,0 +1,60 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-same-namespace-ingress
spec:
endpointSelector: {} # All pods in this namespace
ingress:
- fromEndpoints:
- matchExpressions:
- key: k8s:io.kubernetes.pod.namespace
operator: In
values:
- git-limbosolutions-com
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-traefik-ingress
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: gitea
ingress:
# -------------------------------------------------------------
# Allow Traefik (internal and public) to reach Gitea on port 3000 (web)
# -------------------------------------------------------------
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: traefik
matchExpressions:
- key: k8s:io.kubernetes.pod.namespace
operator: In
values:
- traefik
- traefik-public
toPorts:
- ports:
- port: "3000"
protocol: TCP
# -------------------------------------------------------------
# Allow Traefik (internal) to reach Gitea on port 3000 (ssh)
# -------------------------------------------------------------
- fromEndpoints:
- matchLabels:
app.kubernetes.io/name: traefik
matchExpressions:
- key: k8s:io.kubernetes.pod.namespace
operator: In
values:
- traefik
toPorts:
- ports:
- port: "2222"
protocol: TCP

View File

@@ -1,21 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: git-limbosolutions-com-egress-local
namespace: git-limbosolutions-com
spec:
podSelector: {} # apply to all pods in the namespace
policyTypes:
- Egress
egress:
# allow backup server
- to:
- ipBlock:
cidr: ${BACKUPSRV_CIDR}

View File

@@ -1,38 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: git-limbosolutions-com-egress
namespace: git-limbosolutions-com
spec:
podSelector: {} # apply to all pods in the namespace
policyTypes:
- Egress
egress:
# Allow DNS to kube-system
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
# allow namespace communication
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: git-limbosolutions-com
podSelector: {}
# Allow all egress EXCEPT private networks
- to:
- ipBlock:
cidr: 0.0.0.0/0 # first allow everything
except: # remove local network (so it means blocking, cidr is allowing everything )
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 169.254.0.0/16
- 127.0.0.0/8
- 224.0.0.0/4
- 240.0.0.0/4

View File

@@ -1,47 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: git-limbosolutions-com-ingress
namespace: git-limbosolutions-com
spec:
# Apply this policy only to the Gitea pods
podSelector:
matchLabels:
app.kubernetes.io/name: gitea
policyTypes:
- Ingress
ingress:
# ---------------------------------------------------------------------
# Allow HTTPS (3000) ONLY from Traefik running in kube-system
# ---------------------------------------------------------------------
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- protocol: TCP
port: http # HTTPS routed by Traefik
# ---------------------------------------------------------------------
# Allow SSH (2222) from the internet, but block all internal traffic
#
# - cidr: 0.0.0.0/0 allows all external IPs
# - except: blocks all cluster networks
#
# This forces ALL SSH traffic to come through external firewall
# ,preventing pod-to-pod or service-to-pod SSH access.
# ---------------------------------------------------------------------
- from:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/16 # Pod network (blocks all pods)
- 10.43.0.0/16 # Service network (blocks ClusterIP access)
ports:
- protocol: TCP
port: ssh # ssh port routed by firewall

View File

@@ -5,6 +5,8 @@ metadata:
namespace: git-limbosolutions-com
labels:
app: borg-backup-sidekick
dbAccess: "true"
backups.infra.limbosolutions.com/ssh: "true"
spec:
containers:
- name: borg-backup-sidekick
@@ -21,14 +23,14 @@ spec:
- name: BORG_REPO
valueFrom:
secretKeyRef:
name: gitea-backup-secret
key: borg_repo
name: gitea-backup
key: BORG_REPO
- name: BORG_PASSPHRASE
valueFrom:
secretKeyRef:
name: gitea-backup-secret
key: borg_passphrase
name: gitea-backup
key: BORG_PASSPHRASE
- name: BORG_RSH
value: ssh -p 2222 -o StrictHostKeyChecking=no -o LogLevel=ERROR
@@ -47,12 +49,12 @@ spec:
- name: gitea-backup-secrets
mountPath: /root/.ssh/id_rsa
subPath: ssh_id_rsa
subPath: SSH_ID_RSA
readOnly: true
- name: gitea-backup-secrets
mountPath: /app/borg/key
subPath: borg_key
subPath: BORG_KEY
volumes:
- name: gitea-backup-secrets
secret:

View File

@@ -1,5 +1,6 @@
#/bin/bash
kubectl kustomize deploy/backups | kubectl apply -f -
# load environment variables from file
if [ -f "deploy/app/.env.d/.env" ]; then
# Export all variables from the file
@@ -10,11 +11,12 @@ if [ -f "deploy/app/.env.d/.env" ]; then
fi
if [ -n "${APP_HELM_VALUE_GITEA_ADMIN_USERNAME:-}" ]; then
echo "Executing helm deploy."
helm repo add gitea-charts https://dl.gitea.com/charts/ --force-update
helm upgrade --install gitea gitea-charts/gitea --version 12.5.0 \
helm upgrade --install gitea gitea-charts/gitea --version 12.5.3 \
--values deploy/app/helm-values.yaml \
--set valkey.global.valkey.password=${APP_HELM_VALUE_VALKEY_GLOBAL_PASSWORD} \
--set postgresql.global.postgresql.auth.postgresPassword=${APP_HELM_VALUE_POSTGRESQL_AUTH_POSTGRESPASSWORD} \
@@ -32,4 +34,7 @@ if [ -n "${APP_HELM_VALUE_GITEA_ADMIN_USERNAME:-}" ]; then
--set gitea.config.security.PASSWORD_HASH_ALGO=${APP_HELM_VALUE_GITEA_CONFIG_SECURITY_PASSWORD_HASH_ALGO} \
--set gitea.config.service.oauth2.JWT_SECRET=${APP_HELM_VALUE_GITEA_CONFIG_SERVICE_OAUTH2_JWT_SECRET} \
--namespace=git-limbosolutions-com
echo "executing deploy of backups jobs."
kubectl kustomize deploy/backups | kubectl -n git-limbosolutions-com apply -f -
fi

View File

@@ -2,6 +2,6 @@
set -e
echo "Executing infra deploy."
kubectl kustomize deploy/infra | kubectl apply -f -
kubectl kustomize deploy/infra | kubectl -n git-limbosolutions-com apply -f -