Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7252b0fa62 | ||
|
|
9b1af7042e | ||
|
|
cb1b511e2a | ||
|
|
01cf0f2a13 | ||
|
|
a43c4de366 | ||
|
|
b09ca30506 |
@@ -0,0 +1,256 @@
|
||||
name: Check, build and release Caddy
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 6 * * *"
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- build.sh
|
||||
- modules.txt
|
||||
- .gitea/workflows/build-caddy.yml
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-caddy:
|
||||
runs-on: caddy-builder
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Vérifier le runner
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "Dépôt : $GITHUB_REPOSITORY"
|
||||
echo "Commit : $GITHUB_SHA"
|
||||
echo "Dossier : $PWD"
|
||||
|
||||
for command in curl jq docker sha256sum tar; do
|
||||
command -v "$command" >/dev/null || {
|
||||
echo "Missing required command: $command"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
docker version
|
||||
docker info
|
||||
|
||||
- name: Check, build and publish
|
||||
shell: bash
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [ -z "${GITEA_TOKEN:-}" ]; then
|
||||
echo "Le secret GITEA_TOKEN est absent"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GITEA_URL="https://git.jst.ovh"
|
||||
API_URL="${GITEA_URL}/api/v1"
|
||||
|
||||
REPOSITORY="$GITHUB_REPOSITORY"
|
||||
TARGET_COMMIT="$GITHUB_SHA"
|
||||
|
||||
BUILD_CONTAINER=""
|
||||
|
||||
cleanup_builder() {
|
||||
if [ -n "${BUILD_CONTAINER:-}" ]; then
|
||||
echo "Suppression du conteneur de build"
|
||||
docker rm --force "$BUILD_CONTAINER" \
|
||||
>/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup_builder EXIT
|
||||
|
||||
LATEST_VERSION="$(curl -fsSL \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
https://api.github.com/repos/caddyserver/caddy/releases/latest \
|
||||
| jq -er '.tag_name')"
|
||||
|
||||
echo "Latest upstream Caddy version: ${LATEST_VERSION}"
|
||||
|
||||
STATUS="$(curl -sS \
|
||||
-o /tmp/existing-release.json \
|
||||
-w '%{http_code}' \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
"${API_URL}/repos/${REPOSITORY}/releases/tags/${LATEST_VERSION}")"
|
||||
|
||||
case "$STATUS" in
|
||||
200)
|
||||
echo "Release ${LATEST_VERSION} already exists in Gitea; nothing to do."
|
||||
exit 0
|
||||
;;
|
||||
404)
|
||||
echo "No Gitea release found for ${LATEST_VERSION}; starting build."
|
||||
;;
|
||||
*)
|
||||
echo "Unable to query the Gitea release (HTTP ${STATUS}):"
|
||||
cat /tmp/existing-release.json
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -rf ./dist
|
||||
rm -f ./caddy-*-linux-amd64.tar.gz
|
||||
rm -f ./caddy-*-linux-amd64.tar.gz.sha256
|
||||
|
||||
echo "Pulling Caddy builder image"
|
||||
docker pull caddy:2-builder-alpine
|
||||
|
||||
echo "Creating Caddy builder container"
|
||||
|
||||
BUILD_CONTAINER="$(docker create \
|
||||
--env "CADDY_VERSION=${LATEST_VERSION}" \
|
||||
--workdir /workspace \
|
||||
caddy:2-builder-alpine \
|
||||
sh -ec '
|
||||
apk add --no-cache bash tar
|
||||
|
||||
echo "Workspace content:"
|
||||
ls -la /workspace
|
||||
|
||||
chmod +x ./build.sh
|
||||
./build.sh "$CADDY_VERSION"
|
||||
')"
|
||||
|
||||
echo "Builder container: ${BUILD_CONTAINER}"
|
||||
|
||||
echo "Copying repository into builder container"
|
||||
|
||||
tar -C "$PWD" -cf - . \
|
||||
| docker cp - "$BUILD_CONTAINER:/workspace"
|
||||
|
||||
echo "Starting Caddy build"
|
||||
|
||||
docker start --attach "$BUILD_CONTAINER"
|
||||
|
||||
BUILD_EXIT_CODE="$(docker inspect \
|
||||
--format '{{.State.ExitCode}}' \
|
||||
"$BUILD_CONTAINER")"
|
||||
|
||||
if [ "$BUILD_EXIT_CODE" -ne 0 ]; then
|
||||
echo "Caddy build failed with exit code ${BUILD_EXIT_CODE}"
|
||||
exit "$BUILD_EXIT_CODE"
|
||||
fi
|
||||
|
||||
ASSET_NAME="caddy-${LATEST_VERSION}-linux-amd64.tar.gz"
|
||||
|
||||
echo "Copying build results"
|
||||
|
||||
docker cp \
|
||||
"$BUILD_CONTAINER:/workspace/dist" \
|
||||
./dist
|
||||
|
||||
docker cp \
|
||||
"$BUILD_CONTAINER:/workspace/${ASSET_NAME}" \
|
||||
"./${ASSET_NAME}"
|
||||
|
||||
docker rm "$BUILD_CONTAINER"
|
||||
BUILD_CONTAINER=""
|
||||
|
||||
echo "Validating Caddy binary"
|
||||
|
||||
./dist/caddy version
|
||||
|
||||
./dist/caddy list-modules \
|
||||
| grep -Ei 'oidc|maxmind|layer4|cloudflare'
|
||||
|
||||
ASSET="$(find . \
|
||||
-maxdepth 1 \
|
||||
-type f \
|
||||
-name "$ASSET_NAME" \
|
||||
-print \
|
||||
-quit)"
|
||||
|
||||
if [ -z "$ASSET" ]; then
|
||||
echo "Caddy archive was not generated"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ASSET="${ASSET#./}"
|
||||
CHECKSUM="${ASSET}.sha256"
|
||||
|
||||
sha256sum "$ASSET" > "$CHECKSUM"
|
||||
|
||||
echo "Generated files:"
|
||||
ls -lh "$ASSET" "$CHECKSUM"
|
||||
|
||||
MODULES="$(sed \
|
||||
'/^[[:space:]]*#/d;
|
||||
/^[[:space:]]*$/d;
|
||||
s/^/- /' \
|
||||
modules.txt)"
|
||||
|
||||
NOTES="$(cat <<NOTES_EOF
|
||||
Custom Caddy build based on upstream Caddy ${LATEST_VERSION}.
|
||||
|
||||
Build date: $(date -u +'%Y-%m-%d %H:%M UTC')
|
||||
|
||||
## Included modules
|
||||
|
||||
${MODULES}
|
||||
NOTES_EOF
|
||||
)"
|
||||
|
||||
jq -n \
|
||||
--arg tag "$LATEST_VERSION" \
|
||||
--arg target "$TARGET_COMMIT" \
|
||||
--arg name "Custom Caddy ${LATEST_VERSION}" \
|
||||
--arg body "$NOTES" \
|
||||
'{
|
||||
tag_name: $tag,
|
||||
target_commitish: $target,
|
||||
name: $name,
|
||||
body: $body,
|
||||
draft: false,
|
||||
prerelease: false
|
||||
}' \
|
||||
> /tmp/create-release.json
|
||||
|
||||
echo "Creating Gitea release"
|
||||
|
||||
curl -fsS \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
--data-binary @/tmp/create-release.json \
|
||||
"${API_URL}/repos/${REPOSITORY}/releases" \
|
||||
-o /tmp/created-release.json
|
||||
|
||||
RELEASE_ID="$(jq -er '.id' /tmp/created-release.json)"
|
||||
RELEASE_URL="$(jq -er '.html_url' /tmp/created-release.json)"
|
||||
|
||||
echo "Uploading Caddy archive"
|
||||
|
||||
curl -fsS \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
-F "attachment=@${ASSET};type=application/gzip" \
|
||||
"${API_URL}/repos/${REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename "$ASSET")" \
|
||||
-o /tmp/upload-asset.json
|
||||
|
||||
echo "Uploading checksum"
|
||||
|
||||
curl -fsS \
|
||||
-X POST \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
-F "attachment=@${CHECKSUM};type=text/plain" \
|
||||
"${API_URL}/repos/${REPOSITORY}/releases/${RELEASE_ID}/assets?name=$(basename "$CHECKSUM")" \
|
||||
-o /tmp/upload-checksum.json
|
||||
|
||||
echo "Release published: ${RELEASE_URL}"
|
||||
@@ -1,31 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${1:-latest}"
|
||||
CADDY_VERSION="${1:-latest}"
|
||||
|
||||
# Build
|
||||
./build.sh "$VERSION"
|
||||
mkdir -p dist
|
||||
|
||||
# Récupère le nom de l'archive générée
|
||||
ASSET="$(ls -t caddy-*-linux-amd64.tar.gz | head -n1)"
|
||||
ARGS=()
|
||||
while read -r module; do
|
||||
[[ -z "$module" || "$module" =~ ^# ]] && continue
|
||||
ARGS+=(--with "$module")
|
||||
done < modules.txt
|
||||
|
||||
# Déduit la version depuis le nom du fichier
|
||||
TAG="$(basename "$ASSET" | sed -E 's/^caddy-(.*)-linux-amd64\.tar\.gz$/\1/')"
|
||||
if [[ "$CADDY_VERSION" == "latest" ]]; then
|
||||
xcaddy build \
|
||||
"${ARGS[@]}" \
|
||||
--output dist/caddy
|
||||
else
|
||||
xcaddy build "$CADDY_VERSION" \
|
||||
"${ARGS[@]}" \
|
||||
--output dist/caddy
|
||||
fi
|
||||
|
||||
echo "Publishing $TAG"
|
||||
REAL_VERSION="$(dist/caddy version | awk '{print $1}')"
|
||||
|
||||
git tag -f "$TAG"
|
||||
git push origin "$TAG" --force
|
||||
ARCHIVE="caddy-${REAL_VERSION}-linux-amd64.tar.gz"
|
||||
|
||||
# Supprime la release si elle existe (ignore les erreurs)
|
||||
tea release delete "$TAG" >/dev/null 2>&1 || true
|
||||
|
||||
# Crée la nouvelle release
|
||||
tea release create \
|
||||
--tag "$TAG" \
|
||||
--title "$TAG" \
|
||||
--note "Custom Caddy build with modules from modules.txt" \
|
||||
--asset "$ASSET"
|
||||
tar -C dist -czf "$ARCHIVE" caddy
|
||||
|
||||
echo
|
||||
echo "✅ Release publiée : $TAG"
|
||||
echo "Version : $REAL_VERSION"
|
||||
echo "Archive : $ARCHIVE"
|
||||
|
||||
@@ -1,35 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "==> Installation des dépendances"
|
||||
GITEA_HOST="git.jst.ovh"
|
||||
GITEA_URL="https://${GITEA_HOST}"
|
||||
|
||||
echo "==> Installation des dépendances"
|
||||
sudo apt update
|
||||
sudo apt install -y \
|
||||
git \
|
||||
curl \
|
||||
jq \
|
||||
tar \
|
||||
build-essential \
|
||||
golang-go
|
||||
git \
|
||||
curl \
|
||||
jq \
|
||||
tar \
|
||||
build-essential \
|
||||
golang-go
|
||||
|
||||
echo "==> Installation de xcaddy"
|
||||
|
||||
export GOPATH="${HOME}/go"
|
||||
export PATH="${PATH}:${GOPATH}/bin"
|
||||
|
||||
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
|
||||
if ! command -v xcaddy >/dev/null 2>&1; then
|
||||
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
|
||||
fi
|
||||
|
||||
if ! grep -q 'HOME/go/bin' "${HOME}/.bashrc"; then
|
||||
echo 'export PATH="$PATH:$HOME/go/bin"' >> "${HOME}/.bashrc"
|
||||
echo 'export PATH="$PATH:$HOME/go/bin"' >> "${HOME}/.bashrc"
|
||||
fi
|
||||
|
||||
echo "==> Installation de tea"
|
||||
if ! command -v tea >/dev/null 2>&1; then
|
||||
TMP_TEA="$(mktemp)"
|
||||
curl -fsSL "https://dl.gitea.com/tea/main/tea-main-linux-amd64" -o "$TMP_TEA"
|
||||
chmod +x "$TMP_TEA"
|
||||
sudo mv "$TMP_TEA" /usr/local/bin/tea
|
||||
fi
|
||||
|
||||
echo "==> Vérification de la connexion tea à ${GITEA_HOST}"
|
||||
|
||||
if tea login list 2>/dev/null | grep -q "${GITEA_HOST}"; then
|
||||
echo "Connexion tea existante pour ${GITEA_HOST}"
|
||||
else
|
||||
echo "Aucune connexion tea trouvée pour ${GITEA_HOST}"
|
||||
echo "Création d'une connexion tea..."
|
||||
tea login add \
|
||||
--name jst \
|
||||
--url "${GITEA_URL}"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Versions installées :"
|
||||
echo "Versions :"
|
||||
go version
|
||||
"${HOME}/go/bin/xcaddy" version
|
||||
xcaddy version
|
||||
tea --version
|
||||
|
||||
echo
|
||||
echo "✅ Environnement prêt."
|
||||
echo "Recharge ton shell ou exécute :"
|
||||
echo
|
||||
echo 'export PATH="$PATH:$HOME/go/bin"'
|
||||
echo "✅ Init terminé."
|
||||
|
||||
@@ -0,0 +1,625 @@
|
||||
# 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`](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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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` :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
node --version
|
||||
git --version
|
||||
curl --version
|
||||
jq --version
|
||||
```
|
||||
|
||||
## 3. Installer Docker
|
||||
|
||||
Installation rapide :
|
||||
|
||||
```bash
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
```
|
||||
|
||||
Vérification :
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
/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
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/act_runner
|
||||
cd /opt/act_runner
|
||||
```
|
||||
|
||||
Générer la configuration :
|
||||
|
||||
```bash
|
||||
/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 :
|
||||
|
||||
```bash
|
||||
nano /opt/act_runner/config.yaml
|
||||
```
|
||||
|
||||
Dans la section `runner`, configurer les labels suivants :
|
||||
|
||||
```yaml
|
||||
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 :
|
||||
|
||||
```text
|
||||
docker-builder:host
|
||||
```
|
||||
|
||||
Dans un workflow, il est appelé sans le suffixe `:host` :
|
||||
|
||||
```yaml
|
||||
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 :
|
||||
|
||||
```text
|
||||
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` :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```text
|
||||
/opt/act_runner/.runner
|
||||
```
|
||||
|
||||
Ce fichier contient l'identité du runner. Ne pas le modifier manuellement.
|
||||
|
||||
Vérifier sa présence :
|
||||
|
||||
```bash
|
||||
ls -la /opt/act_runner/.runner
|
||||
```
|
||||
|
||||
## 9. Tester manuellement le runner
|
||||
|
||||
Avant de créer le service systemd :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now act_runner
|
||||
```
|
||||
|
||||
Vérification :
|
||||
|
||||
```bash
|
||||
systemctl status act_runner --no-pager -l
|
||||
journalctl -u act_runner -n 100 --no-pager
|
||||
```
|
||||
|
||||
Suivre les logs en direct :
|
||||
|
||||
```bash
|
||||
journalctl -u act_runner -f
|
||||
```
|
||||
|
||||
## 11. Activer les Actions dans le dépôt
|
||||
|
||||
Dans le dépôt Gitea :
|
||||
|
||||
```text
|
||||
Paramètres du dépôt
|
||||
→ Unités du dépôt
|
||||
→ Activer Repository Actions
|
||||
```
|
||||
|
||||
Le workflow du projet est stocké dans :
|
||||
|
||||
```text
|
||||
.gitea/workflows/build-caddy.yml
|
||||
```
|
||||
|
||||
Il cible ce runner avec :
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build-caddy:
|
||||
runs-on: docker-builder
|
||||
```
|
||||
|
||||
## 12. Autoriser la création des releases
|
||||
|
||||
Le workflow utilise le token intégré à chaque job :
|
||||
|
||||
```yaml
|
||||
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 :
|
||||
|
||||
```yaml
|
||||
permissions:
|
||||
contents: write
|
||||
```
|
||||
|
||||
Vérifier également dans Gitea :
|
||||
|
||||
```text
|
||||
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` :
|
||||
|
||||
```yaml
|
||||
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 :
|
||||
|
||||
```yaml
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 6 * * *"
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
```
|
||||
|
||||
## Compilation
|
||||
|
||||
Le runner lance l'image officielle de construction Caddy :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
caddy-vX.Y.Z-linux-amd64.tar.gz
|
||||
caddy-vX.Y.Z-linux-amd64.tar.gz.sha256
|
||||
```
|
||||
|
||||
Le binaire est également vérifié avec :
|
||||
|
||||
```bash
|
||||
./dist/caddy version
|
||||
./dist/caddy list-modules
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Administration courante
|
||||
|
||||
## État du runner
|
||||
|
||||
```bash
|
||||
systemctl status act_runner --no-pager -l
|
||||
```
|
||||
|
||||
## Logs récents
|
||||
|
||||
```bash
|
||||
journalctl -u act_runner -n 100 --no-pager
|
||||
```
|
||||
|
||||
## Redémarrer le runner
|
||||
|
||||
```bash
|
||||
systemctl restart act_runner
|
||||
```
|
||||
|
||||
## Vérifier les composants
|
||||
|
||||
```bash
|
||||
/usr/local/bin/act_runner --version
|
||||
node --version
|
||||
docker version
|
||||
docker buildx version
|
||||
```
|
||||
|
||||
## Nettoyer le cache Docker
|
||||
|
||||
Afficher l'espace utilisé :
|
||||
|
||||
```bash
|
||||
docker system df
|
||||
```
|
||||
|
||||
Nettoyer les images et caches inutilisés depuis plus de sept jours :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
systemctl status act_runner
|
||||
```
|
||||
|
||||
Vérifier que le label est présent dans `/opt/act_runner/config.yaml` :
|
||||
|
||||
```yaml
|
||||
- "docker-builder:host"
|
||||
```
|
||||
|
||||
Puis redémarrer :
|
||||
|
||||
```bash
|
||||
systemctl restart act_runner
|
||||
```
|
||||
|
||||
Le workflow doit contenir :
|
||||
|
||||
```yaml
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```text
|
||||
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
|
||||
|
||||
- [Gitea Runner](https://docs.gitea.com/usage/actions/runner)
|
||||
- [Démarrage rapide de Gitea Actions](https://docs.gitea.com/usage/actions/quickstart)
|
||||
- [Permissions de GITEA_TOKEN](https://docs.gitea.com/usage/actions/token-permissions)
|
||||
- [Installation de Docker sur Debian](https://docs.docker.com/engine/install/debian/)
|
||||
- [Téléchargements de Gitea Runner](https://dl.gitea.com/gitea-runner/)
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
VERSION="${1:-latest}"
|
||||
|
||||
# Compile le binaire
|
||||
./build.sh "$VERSION"
|
||||
|
||||
# Récupère l'archive générée
|
||||
ASSET="$(ls -t caddy-*-linux-amd64.tar.gz | head -n1)"
|
||||
|
||||
# Déduit le tag depuis le nom de l'archive
|
||||
TAG="$(basename "$ASSET" | sed -E 's/^caddy-(.*)-linux-amd64\.tar\.gz$/\1/')"
|
||||
|
||||
echo "Publishing release ${TAG}"
|
||||
|
||||
# Met à jour le tag Git
|
||||
git tag -f "$TAG"
|
||||
git push origin "$TAG" --force
|
||||
|
||||
# Supprime la release existante (si présente)
|
||||
tea release delete "$TAG" >/dev/null 2>&1 || true
|
||||
|
||||
# Génère automatiquement la description
|
||||
NOTES=$(
|
||||
cat <<EOF
|
||||
Custom Caddy build
|
||||
|
||||
Build date: $(date -u +"%Y-%m-%d %H:%M UTC")
|
||||
|
||||
## Included modules
|
||||
|
||||
$(sed '/^\s*#/d;/^\s*$/d;s/^/- /' modules.txt)
|
||||
EOF
|
||||
)
|
||||
|
||||
# Crée la release
|
||||
tea release create \
|
||||
--tag "$TAG" \
|
||||
--title "$TAG" \
|
||||
--note "$NOTES" \
|
||||
--asset "$ASSET"
|
||||
|
||||
echo
|
||||
echo "✅ Release publiée : ${TAG}"
|
||||
Reference in New Issue
Block a user