🔧 forgejo: add forgejo-runner

This commit is contained in:
Quentin Campos 2026-04-21 15:25:24 +02:00 committed by Quentin Campos
parent ca41e99489
commit 7082cd4dd5
8 changed files with 209 additions and 17 deletions

View file

@ -1,15 +1,18 @@
name: Build avec Kaniko name: Build
on: [push] on: [push]
jobs: jobs:
kaniko-build: build:
runs-on: k8s # Doit correspondre au label dans ta configmap runs-on: k8s
container:
image: gcr.io/kaniko-project/executor:debug
steps: steps:
- name: Build et Push - uses: actions/checkout@v4
run: | - uses: https://git.qcampos.fr/system/actions/setup-kaniko@main
/kaniko/executor \
--context "${{ github.workspace }}" \ - name: Build and push
--dockerfile "${{ github.workspace }}/Dockerfile" \ uses: docker://gcr.io/kaniko-project/executor:debug
--destination "git.qcampos.fr/${{ github.repository }}:latest" with:
args: >-
--context dir:///github/workspace
--destination git.qcampos.fr/${{ github.repository }}:latest
--destination git.qcampos.fr/${{ github.repository }}:${{ github.sha }}
--skip-tls-verify

View file

@ -1,5 +1,5 @@
FROM python:alpine FROM python:alpine
RUN ["touch", "foo.txt"] RUN ["touch", "barrrrrrr.txt"]
CMD ["python", "-c", "'import this'"] CMD ["python", "-c", "'import this'"]

View file

@ -13,6 +13,8 @@ spec:
labels: labels:
app: forgejo app: forgejo
spec: spec:
imagePullSecrets:
- name: forgejo-registry-secret
containers: containers:
- name: forgejo - name: forgejo
image: codeberg.org/forgejo/forgejo:8 image: codeberg.org/forgejo/forgejo:8
@ -31,6 +33,9 @@ spec:
# Activation du Registre d'images # Activation du Registre d'images
- name: FORGEJO__packages__ENABLED - name: FORGEJO__packages__ENABLED
value: "true" value: "true"
# Required for OCI/container image pushes (chunked upload temp dir)
- name: FORGEJO__packages__CHUNKED_UPLOAD_PATH
value: /data/tmp/package-chunked-upload
# Activation des Actions (CI/CD) # Activation des Actions (CI/CD)
- name: FORGEJO__actions__ENABLED - name: FORGEJO__actions__ENABLED
value: "true" value: "true"

View file

@ -1,10 +1,16 @@
# Docker registry credentials for git.qcampos.fr (Forgejo packages).
#
# Stored as an Opaque secret so the key name becomes the filename when
# mounted as a volume — DinD will expose it to Kaniko at /kaniko/.docker/config.json.
#
# To regenerate the auth value:
# printf 'qcampos:<TOKEN>' | base64 -w0
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: registry-secret name: forgejo-registry-secret
namespace: forgejo namespace: forgejo
type: Opaque
stringData: stringData:
docker-server: git.qcampos.fr config.json: |
docker-username: qcampos {"auths":{"git.qcampos.fr":{"auth":"cWNhbXBvczphMDFhMDRlOGE1NzkzNzdmNWZjZWU5NmFlMDAyMDRkZTdmMTY0Zjgw"}}}
docker-password: "50f5bf95338e2f39d70210d6cc71f82c091d1331"
namespace: forgejo

View file

@ -0,0 +1,43 @@
# ConfigMap contenant la configuration du runner (fichier config.yaml).
# Ce fichier est monté dans le pod et passé au runner via --config.
apiVersion: v1
kind: ConfigMap
metadata:
name: forgejo-runner-config
namespace: forgejo
data:
config.yaml: |
log:
level: info
runner:
file: /data/.runner
# Number of parallel jobs
capacity: 2
# Labels exposed to Forgejo for workflows to target the runner.
# Here "k8s" corresponds to `runs-on: k8s` in workflows.
#
# The job container needs /bin/sh and /bin/sleep (act_runner requirement).
# Kaniko is invoked as a step image (uses: docker://) — not as the job container.
labels:
- "k8s:docker://node:20-bookworm"
container:
# Bind-mount the registry credentials (config.json) that were injected into
# the DinD sidecar into every job container.
# Kaniko looks for credentials in /kaniko/.docker by default
options: "-v /run/secrets/docker:/kaniko/.docker:ro"
# act_runner only allows mounting paths listed here.
valid_volumes:
- /run/secrets/docker
# The action cache allow reuse of artifacts between jobs
# Disabled for now
cache:
enabled: false
host:
workdir: /tmp

View file

@ -0,0 +1,103 @@
# ForgeJo Runner : Uses a side-container with DinD
apiVersion: apps/v1
kind: Deployment
metadata:
name: forgejo-runner
namespace: forgejo
spec:
# Single replica, the concurrency is handled by the runner itself
replicas: 1
selector:
matchLabels:
app: forgejo-runner
template:
metadata:
labels:
app: forgejo-runner
spec:
containers:
# Runner : main container
- name: forgejo-runner
image: code.forgejo.org/forgejo/runner:3.3.0
command:
- /bin/sh
- -c
- |
# Register the runner on first boot if .runner does not exist yet.
# The register step contacts Forgejo, exchanges the registration token
# for a session token, and writes it to /data/.runner.
# On subsequent starts the file already exists and we skip straight to daemon.
if [ ! -f /data/.runner ]; then
forgejo-runner register \
--no-interactive \
--config /config/config.yaml \
--instance "$GITEA_INSTANCE_URL" \
--token "$GITEA_RUNNER_REGISTRATION_TOKEN"
fi
exec forgejo-runner daemon --config /config/config.yaml
env:
- name: GITEA_INSTANCE_URL
value: "https://git.qcampos.fr"
# The runner must talk to DinD for job container management.
- name: DOCKER_HOST
value: "tcp://localhost:2375"
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: forgejo-runner-secret
key: registration-token
volumeMounts:
- name: config
mountPath: /config
readOnly: true
# Persistent storage for the .runner file (post-registration session token)
- name: data
mountPath: /data
# DinD : side container — provides the Docker daemon for job containers
- name: docker-dind
image: docker:dind
env:
# Disable TLS so the runner connects on plain TCP port 2375
- name: DOCKER_TLS_CERTDIR
value: ""
securityContext:
# Required for DinD to create kernel namespaces and run containers
privileged: true
volumeMounts:
# Persist Docker layer cache across pod restarts to speed up builds
- name: docker-storage
mountPath: /var/lib/docker
# Registry credentials — mounted here so DinD can bind-mount this
# path into job containers (e.g. Kaniko) via container.options.
# The file is exposed at /run/secrets/docker/config.json.
- name: registry-credentials
mountPath: /run/secrets/docker
readOnly: true
volumes:
- name: config
configMap:
name: forgejo-runner-config
- name: data
persistentVolumeClaim:
claimName: forgejo-runner-data
# emptyDir is fine here — Docker layers are re-pulled after a pod restart,
# which is acceptable on a VPS. Replace with a PVC if cold starts become slow.
- name: docker-storage
emptyDir: {}
# Docker config.json for the Forgejo registry — injected from a K8s secret.
# DinD bind-mounts this into every job container via container.options in the configmap.
- name: registry-credentials
secret:
secretName: forgejo-registry-secret

View file

@ -0,0 +1,16 @@
# Stockage persistant pour l'état d'enregistrement du runner (fichier .runner).
# Ce fichier contient le token de session émis par Forgejo après le premier enregistrement.
# Sans ce PVC, le runner se ré-enregistre à chaque redémarrage du pod et crée
# un nouveau runner orphelin dans l'interface Forgejo.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: forgejo-runner-data
namespace: forgejo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
# Le fichier .runner est minuscule — 100Mi est largement suffisant.
storage: 100Mi

View file

@ -0,0 +1,16 @@
# Secret contenant le token d'enregistrement du runner.
# Ce token se trouve dans Forgejo : Administration du site → Runners → "Créer un runner".
# Il est utilisé UNE SEULE FOIS au démarrage pour s'enregistrer auprès de Forgejo.
# Après l'enregistrement, Forgejo émet un token de session stocké dans le fichier .runner
# à l'intérieur du pod — ce token d'enregistrement n'est plus nécessaire ensuite.
#
# ⚠️ Ce token est en clair dans le dépôt. Pour un usage en production, privilégier
# Sealed Secrets ou External Secrets Operator.
apiVersion: v1
kind: Secret
metadata:
name: forgejo-runner-secret
namespace: forgejo
stringData:
# Remplacer par le token copié depuis l'interface Forgejo.
registration-token: "LOqadesvfA2tjVRoyWUxCnzYjmgMhZqhHHT30nnp"