Files
2026-07-23 09:21:57 +00:00

13 KiB

CaddyBinaries

Construction et publication automatiques d'un binaire Caddy personnalisé à l'aide de Gitea Actions.

Le workflow :

  1. vérifie chaque jour la dernière version stable de Caddy ;
  2. vérifie si cette version existe déjà dans les releases du dépôt Gitea ;
  3. compile Caddy avec les modules indiqués dans modules.txt ;
  4. vérifie le binaire généré ;
  5. crée une release Gitea ;
  6. publie l'archive et son checksum SHA-256.

Modules inclus

Les modules sont configurés dans modules.txt :

  • github.com/relvacode/caddy-oidc
  • github.com/porech/caddy-maxmind-geolocation
  • github.com/mholt/caddy-l4
  • github.com/caddy-dns/cloudflare

Installation du runner Gitea

Cette documentation correspond à l'installation suivante :

LXC Debian 13 dédié
├── Docker Engine
├── Node.js
├── Gitea Runner 2.2.0
└── runner global : gitea-builder-01
    └── label : docker-builder:host

Le runner est exécuté directement sur l'hôte du LXC et en tant que root. Cette configuration est simple pour construire des images et lancer des conteneurs Docker, mais elle doit être réservée à des dépôts de confiance.

1. Préparer le LXC

Configuration conseillée :

Ressource Valeur conseillée
Distribution Debian 13
Type LXC non privilégié
CPU 4 vCPU
RAM 4 à 6 Go
Disque 60 à 80 Go
Swap 1 Go

Sur l'hôte Proxmox, activer les fonctionnalités nécessaires à Docker :

pct set <CTID> -features nesting=1,keyctl=1
pct restart <CTID>

Remplacer <CTID> par l'identifiant du conteneur LXC.

2. Installer les dépendances

Dans le LXC, en tant que root :

apt update && apt install -y \
  ca-certificates \
  curl \
  git \
  jq \
  nodejs \
  bash \
  tar \
  gzip

Node.js est requis pour les actions JavaScript telles que actions/checkout@v4.

Vérification :

node --version
git --version
curl --version
jq --version

3. Installer Docker

Installation rapide :

curl -fsSL https://get.docker.com | sh

Vérification :

systemctl enable --now docker
docker version
docker run --rm hello-world
docker buildx version

Le script get.docker.com est pratique pour un LXC dédié de homelab. Pour un environnement de production administré strictement, utiliser de préférence le dépôt APT officiel de Docker.

4. Installer Gitea Runner

La version utilisée dans cette documentation est 2.2.0 pour Linux AMD64.

cd /tmp

RUNNER_VERSION="2.2.0"
RUNNER_FILE="gitea-runner-${RUNNER_VERSION}-linux-amd64"
RUNNER_URL="https://dl.gitea.com/gitea-runner/${RUNNER_VERSION}"

curl -fLO "${RUNNER_URL}/${RUNNER_FILE}"
curl -fLO "${RUNNER_URL}/${RUNNER_FILE}.sha256"
sha256sum -c "${RUNNER_FILE}.sha256"

install -m 0755 "${RUNNER_FILE}" /usr/local/bin/act_runner

Vérification :

/usr/local/bin/act_runner --version

Pour un LXC ARM64, remplacer linux-amd64 par linux-arm64 dans RUNNER_FILE.

5. Créer les répertoires

mkdir -p /opt/act_runner
cd /opt/act_runner

Générer la configuration :

/usr/local/bin/act_runner generate-config > /opt/act_runner/config.yaml
chmod 600 /opt/act_runner/config.yaml

6. Configurer les labels

Éditer le fichier :

nano /opt/act_runner/config.yaml

Dans la section runner, configurer les labels suivants :

runner:
  labels:
    - "docker-builder:host"
    - "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
    - "ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04"
    - "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"

Le label utilisé par ce dépôt est :

docker-builder:host

Dans un workflow, il est appelé sans le suffixe :host :

runs-on: docker-builder

Le suffixe :host indique que les commandes sont exécutées directement dans le LXC, au lieu d'être placées dans un conteneur de job isolé.

7. Récupérer le token d'enregistrement

Pour créer un runner global :

Administration Gitea
→ Actions
→ Runners
→ Create new Runner

Copier le token affiché. Un token de runner global permet à ce runner de prendre les jobs de tous les dépôts autorisés sur l'instance.

Pour limiter son accès, il est également possible de créer le token depuis les paramètres d'une organisation ou d'un dépôt précis.

8. Enregistrer le runner

Depuis /opt/act_runner :

cd /opt/act_runner

/usr/local/bin/act_runner \
  --config /opt/act_runner/config.yaml \
  register \
  --no-interactive \
  --instance "https://git.jst.ovh" \
  --token "COLLER_LE_TOKEN_ICI" \
  --name "gitea-builder-01" \
  --labels "docker-builder:host,ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest,ubuntu-24.04:docker://docker.gitea.com/runner-images:ubuntu-24.04,ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"

L'enregistrement crée le fichier suivant :

/opt/act_runner/.runner

Ce fichier contient l'identité du runner. Ne pas le modifier manuellement.

Vérifier sa présence :

ls -la /opt/act_runner/.runner

9. Tester manuellement le runner

Avant de créer le service systemd :

cd /opt/act_runner
/usr/local/bin/act_runner daemon --config /opt/act_runner/config.yaml

Dans l'interface Gitea, le runner doit apparaître avec :

Nom     : gitea-builder-01
État    : Idle
Type    : Global
Labels  : docker-builder, ubuntu-latest, ubuntu-24.04, ubuntu-22.04

Arrêter le test avec Ctrl+C.

10. Créer le service systemd

Créer le service :

cat > /etc/systemd/system/act_runner.service <<'EOF_SYSTEMD'
[Unit]
Description=Gitea Actions Runner
Documentation=https://docs.gitea.com/usage/actions/runner
Wants=network-online.target
After=network-online.target docker.service
Requires=docker.service

[Service]
Type=simple
User=root
Group=root
Environment="HOME=/root"
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
WorkingDirectory=/opt/act_runner
ExecStart=/usr/local/bin/act_runner daemon --config /opt/act_runner/config.yaml
Restart=always
RestartSec=5
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target
EOF_SYSTEMD

Activer et démarrer le service :

systemctl daemon-reload
systemctl enable --now act_runner

Vérification :

systemctl status act_runner --no-pager -l
journalctl -u act_runner -n 100 --no-pager

Suivre les logs en direct :

journalctl -u act_runner -f

11. Activer les Actions dans le dépôt

Dans le dépôt Gitea :

Paramètres du dépôt
→ Unités du dépôt
→ Activer Repository Actions

Le workflow du projet est stocké dans :

.gitea/workflows/build-caddy.yml

Il cible ce runner avec :

jobs:
  build-caddy:
    runs-on: docker-builder

12. Autoriser la création des releases

Le workflow utilise le token intégré à chaque job :

env:
  GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

Il n'est pas nécessaire de créer manuellement un secret portant ce nom. Gitea fournit automatiquement GITEA_TOKEN à chaque job.

Le workflow demande l'autorisation d'écrire dans les releases :

permissions:
  contents: write

Vérifier également dans Gitea :

Dépôt
→ Paramètres
→ Actions
→ Général

Les permissions maximales du token doivent autoriser l'écriture sur le contenu ou les releases. Une permission maximale en lecture seule provoquera une erreur HTTP 403 lors de la création de la release.

13. Tester le runner avec un workflow minimal

Créer temporairement .gitea/workflows/test-runner.yml :

name: Test runner

on:
  workflow_dispatch:

jobs:
  test:
    runs-on: docker-builder

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Vérifications
        run: |
          hostname
          id
          node --version
          git --version
          docker version
          docker buildx version

Lancer ensuite le workflow depuis l'onglet Actions de Gitea.


Fonctionnement du build Caddy

Déclencheurs

Le workflow principal est lancé :

  • chaque jour à 06:00 UTC ;
  • manuellement avec workflow_dispatch ;
  • après une modification de build.sh, modules.txt ou du workflow sur la branche main.

Configuration :

on:
  schedule:
    - cron: "0 6 * * *"
  workflow_dispatch:
  push:
    branches:
      - main

Compilation

Le runner lance l'image officielle de construction Caddy :

caddy:2-builder-alpine

Le dépôt est monté dans le conteneur et build.sh utilise xcaddy pour compiler le binaire avec les modules présents dans modules.txt.

Fichiers publiés

Chaque release contient :

caddy-vX.Y.Z-linux-amd64.tar.gz
caddy-vX.Y.Z-linux-amd64.tar.gz.sha256

Le binaire est également vérifié avec :

./dist/caddy version
./dist/caddy list-modules

Administration courante

État du runner

systemctl status act_runner --no-pager -l

Logs récents

journalctl -u act_runner -n 100 --no-pager

Redémarrer le runner

systemctl restart act_runner

Vérifier les composants

/usr/local/bin/act_runner --version
node --version
docker version
docker buildx version

Nettoyer le cache Docker

Afficher l'espace utilisé :

docker system df

Nettoyer les images et caches inutilisés depuis plus de sept jours :

docker image prune -af --filter "until=168h"
docker builder prune -af --filter "until=168h"

Mettre à jour le runner

Exemple pour mettre à jour vers une nouvelle version :

NEW_VERSION="2.2.0"
RUNNER_FILE="gitea-runner-${NEW_VERSION}-linux-amd64"
RUNNER_URL="https://dl.gitea.com/gitea-runner/${NEW_VERSION}"

cd /tmp
curl -fLO "${RUNNER_URL}/${RUNNER_FILE}"
curl -fLO "${RUNNER_URL}/${RUNNER_FILE}.sha256"
sha256sum -c "${RUNNER_FILE}.sha256"

systemctl stop act_runner
install -m 0755 "${RUNNER_FILE}" /usr/local/bin/act_runner
systemctl start act_runner

/usr/local/bin/act_runner --version
systemctl status act_runner --no-pager

Adapter NEW_VERSION à la version souhaitée.


Dépannage

No matching online runner with label: docker-builder

Vérifier que le runner est en ligne :

systemctl status act_runner

Vérifier que le label est présent dans /opt/act_runner/config.yaml :

- "docker-builder:host"

Puis redémarrer :

systemctl restart act_runner

Le workflow doit contenir :

runs-on: docker-builder

Gitea sélectionne les runners selon leurs labels, et non selon leur nom visible gitea-builder-01.

Cannot find: node in PATH

Installer Node.js et redémarrer le runner :

apt update && apt install -y nodejs
node --version
systemctl restart act_runner

Cette erreur apparaît notamment avec actions/checkout@v4, qui est une action JavaScript.

Le runner reste hors ligne

journalctl -u act_runner -n 100 --no-pager

Vérifier :

  • que https://git.jst.ovh est accessible depuis le LXC ;
  • que /opt/act_runner/.runner existe ;
  • que le service utilise le bon répertoire de travail ;
  • que le token utilisé lors de l'enregistrement correspond à la bonne instance Gitea.

Test manuel :

systemctl stop act_runner
cd /opt/act_runner
/usr/local/bin/act_runner daemon --config /opt/act_runner/config.yaml

Réenregistrer le runner

À utiliser uniquement si le fichier d'enregistrement est invalide ou si le runner a été supprimé de Gitea :

systemctl stop act_runner
rm -f /opt/act_runner/.runner

Récupérer un nouveau token dans Gitea, puis recommencer l'étape d'enregistrement.

Docker ne fonctionne pas dans le workflow

Tester directement dans le LXC :

docker version
docker run --rm hello-world

Comme le runner fonctionne en root et avec le label :host, il doit pouvoir accéder directement au démon Docker du LXC.

Erreur HTTP 403 lors de la création d'une release

Vérifier :

  1. la présence de permissions: contents: write dans le workflow ;
  2. les permissions maximales du token dans Paramètres → Actions → Général ;
  3. que l'exécution ne provient pas d'une pull request non fiable ou d'un fork, pour lesquels les permissions sont restreintes.

Sécurité

Le runner fonctionne avec deux éléments très privilégiés :

root + docker-builder:host

Un workflow peut donc exécuter n'importe quelle commande root dans le LXC et contrôler son démon Docker.

Mesures recommandées :

  • dédier entièrement le LXC au runner ;
  • ne pas y héberger d'autres services ;
  • ne pas y stocker de clés SSH de production ;
  • n'autoriser que des utilisateurs de confiance à modifier les workflows ;
  • ne pas utiliser ce runner pour des dépôts publics acceptant des pull requests non fiables ;
  • sauvegarder le dépôt, mais pas nécessairement les caches Docker ;
  • maintenir Docker, Debian et Gitea Runner à jour.

Documentation officielle