Comment ce blog se déploie tout seul en moins de 15 secondes, avec un pipeline minimaliste.
L’architecture
Le pipeline repose sur trois briques :
- Gitea Actions avec
act_runnerpour l’orchestration CI/CD - Alpine Linux 3.19 comme image de build (~8 MB)
- Hugo installé via
apkpour la génération du site statique
Le runner tourne sur le même serveur que Gitea et Nginx. Il monte directement le répertoire web en volume Docker — pas de SSH, pas de rsync, pas d’artefact intermédiaire.
Le workflow
jobs:
build-deploy:
runs-on: ubuntu-latest
container:
image: alpine:3.19
volumes:
- /var/www/blog.bojemoi.me:/deploy
steps:
- name: Install dependencies
run: apk add --no-cache hugo git
- name: Checkout repo
run: |
git clone --depth 1 --branch "${GITHUB_REF_NAME}" \
"http://gitea:3000/${GITHUB_REPOSITORY}.git" .
- name: Build Hugo site
run: hugo --minify
- name: Deploy to web root
run: |
rm -rf /deploy/*
cp -r public/* /deploy/
Quelques choix notables :
- Pas de
actions/checkout— cette action nécessite Node.js, absent d’Alpine. Un simplegit clone --depth 1fait le travail en une fraction de seconde. - Volume mount direct — le runner est configuré avec
valid_volumesdans sonconfig.yamlpour autoriser le mount de/var/www/blog.bojemoi.me. Le déploiement se résume à uncp. - Pas de thème externe — les layouts sont embarqués dans le repo pour éviter toute dépendance réseau au build.
Configuration du runner
Le point clé est le config.yaml de act_runner :
container:
network: gitea_gitea-internal
valid_volumes:
- /var/www/blog.bojemoi.me
Le réseau gitea_gitea-internal permet au conteneur de build de résoudre gitea:3000 pour le clone. Sans ça, le checkout échoue avec Could not resolve host: gitea.
Résultat
Push sur main → build Hugo → fichiers copiés → site live. Le tout en ~15 secondes, avec une empreinte minimale.