Self-Host Ton propre CI/CD : Droney vs GitHub Actions (et pourquoi j'ai switché)
GitHub Actions te coûte trop cher ? J'ai migré mes pipelines vers Droney, un runner CI/CD self-hosté. Voici comment, avec les pièges à éviter.
Tu payes GitHub Actions pour quoi déjà ?
Soyons honnêtes deux minutes.
Tu commences petit. Un repo perso. Quelques commits. GitHub Actions gratuit, 2000 minutes/mois, ça passe large.
Puis ton projet grossit. Tu ajoutes des tests. Du linting. Des builds Docker. Des déploiements auto. Et soudain bam — t’as bouffé tes 2000 minutes en 10 jours.
Options :
- Payer $4 pour 10 000 minutes supplémentaires (ça va encore)
- Optimiser tes workflows à l’extrême (pain in the cul)
- Self-hoster ton propre runner
J’ai choisi l’option 3. Et honnêtement ? J’aurais dû le faire plus tôt.
Pourquoi j’ai quitté GitHub Actions
Regardons les chiffres pour mon setup :
Avant (GitHub Actions) :
- 3 repos actifs
- ~50 builds/semaine
- Temps moyen : 8 minutes/build
- Total : ~1600 minutes/mois (dans la limite gratuite, mais tendu)
- Problème : Les builds Docker sont lents, pas de cache persistant entre runs
Après (Droney self-hosté) :
- Même charge
- Temps moyen : 4 minutes/build (cache local + hardware dédié)
- Coût : 0€ (ça tourne sur mon VPS déjà payé)
- Bonus : J’ai le contrôle total, pas de limite de timeout
Laswitch n’a pas été juste économique. C’était aussi une question de contrôle.
Quand ton build Docker prend 25 minutes sur GitHub Actions à cause du réseau et du cache qui se reset à chaque run, tu commences à te poser des questions.
Droney : C’est quoi ce truc ?
Droney, c’est un système CI/CD self-hosté inspiré de Travis CI et GitHub Actions.
Architecture simple :
- Server : Orchestre les pipelines, écoute les webhooks
- Runner : Exécute les jobs (peut être sur la même machine ou distribué)
- CLI : Pour tester tes pipelines en local avant de push
Pourquoi Droney et pas Jenkins/GitLab ?
J’ai testé les trois. Voici mon verdict :
| Outil | Setup | Resource Usage | Learning Curve | Verdict |
|---|---|---|---|---|
| Jenkins | 2h+ | Lourd (Java) | Raide | Overkill pour mes besoins |
| GitLab CI | 1h+ | Moyen | Moyen | Bien mais nécessite GitLab complet |
| Droney | 15 min | Léger (Go) | Faible | Parfait pour petits/moyens projets |
Droney, c’est un binaire. Point. Pas de base de données obligatoire. Pas de JVM à faire tourner. Juste un exec qui écoute des webhooks et lance des containers Docker.
Si tu utilises déjà Docker, tu vas te sentir chez toi.
Installation : 15 minutes montre en main
Je pars du principe que tu as Docker installé. Si c’est pas le cas, arrête tout et reviens quand c’est fait.
Étape 1 : Lancer le server Droney
docker run -d \
--name=drone-server \
--restart=always \
-e DRONE_SERVER_HOST=drone.ton-domaine.com \
-e DRONE_SERVER_PROTO=https \
-e DRONE_RPC_SECRET=$(openssl rand -hex 16) \
-e DRONE_GITHUB_SERVER=https://github.com \
-e DRONE_GITHUB_CLIENT_ID=TON_CLIENT_ID \
-e DRONE_GITHUB_CLIENT_SECRET=TON_CLIENT_SECRET \
-v drone_data:/var/lib/drone \
-p 8080:80 \
drone/drone:2
Les variables critiques :
DRONE_RPC_SECRET : Génère-en un nouveau avec openssl rand -hex 16. C’est ta clé secrète pour l’auth entre server et runners.
DRONE_GITHUB_CLIENT_ID & CLIENT_SECRET : À récupérer sur https://github.com/settings/developers (crée une OAuth App).
⚠️ Piège classique : Oublie pas de mettre DRONE_SERVER_HOST avec le bon domaine. Si tu changes après, tu devras recréer la BDD.
Étape 2 : Lancer le runner
docker run -d \
--name=drone-runner \
--restart=always \
-e DRONE_RPC_PROTO=http \
-e DRONE_RPC_HOST=drone-server \
-e DRONE_RPC_SECRET=TON_RPC_SECRET (le même que plus haut) \
-e DRONE_RUNNER_NAME=mon-runner-1 \
-e DRONE_RUNNER_CAPACITY=2 \
-v /var/run/docker.sock:/var/run/docker.sock \
drone/drone-runner-docker:2
Le runner se connecte au server et attend les jobs. La capacité de 2 veut dire : 2 builds en parallèle max.
Étape 3 : Activer ton repo
Va sur http://ton-domaine:8080, login avec GitHub, et active les repos que tu veux build.
Ton premier pipeline .drone.yml
À la racine de ton repo, crée un fichier .drone.yml :
kind: pipeline
type: docker
name: default
steps:
- name: lint
image: node:20
commands:
- npm ci
- npm run lint
- name: test
image: node:20
commands:
- npm ci
- npm test
- name: build
image: docker:24
commands:
- docker build -t mon-app .
- docker push mon-app:latest
volumes:
- name: docker-socket
path: /var/run/docker.sock
volumes:
- name: docker-socket
host:
path: /var/run/docker.sock
Ce qui se passe :
- Droney détecte le push sur GitHub (via webhook auto-configuré)
- Il lance 3 steps séquentiels
- Chaque step tourne dans un container éphémère
- Le build Docker utilise le socket host pour builder l’image
Différence majeure avec GitHub Actions : Ici, tu gères toi-même le cache. GitHub Actions te donne actions/cache out of the box. Avec Droney, c’est à toi de monter des volumes persistants si tu veux du cache npm/entre builds.
Le vrai défi : Le cache Docker
C’est LÀ que j’ai perdu le plus de temps.
Sur GitHub Actions, tu as ça :
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
Magic. Rapide. Ça marche.
Sur Droney ? Rien n’est magique. Tu dois configurer toi-même un cache Docker.
Solution 1 : Registry local avec cache
J’ai setup un registry Docker local :
docker run -d \
--name registry \
--restart=always \
-v registry_data:/var/lib/registry \
-p 5000:5000 \
registry:2
Et dans mon .drone.yml :
- name: build
image: gcr.io/kaniko-project/executor:latest
commands:
- /kaniko/executor \
--context . \
--dockerfile Dockerfile \
--destination mon-registry:5000/mon-app:latest \
--cache=true \
--cache-repo=mon-registry:5000/cache
volumes:
- name: kaniko-cache
path: /kaniko/.docker
Kaniko build dans un container sans besoin du Docker socket (plus secure), et utilise un cache persistant.
Résultat :
- Build initial : 8 minutes
- Build avec cache : 2 minutes 🔥
Solution 2 : BuildKit avec cache mount (plus simple)
Si tu veux rester sur Docker build classique :
- name: build
image: docker:24-dind
commands:
- export DOCKER_BUILDKIT=1
- docker build -t mon-app \
--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from mon-app:latest \
.
Mais ça nécessite le runner en mode dind (Docker in Docker), ce qui est un peu plus complexe à setup.
Mon conseil : Commence sans cache. Une fois que tes builds sont lents, ajoute le cache registry. Pas besoin de prématurer l’optimisation.
Gérer les secrets (sans se tirer une balle)
GitHub Actions a secrets. Droney a… des secrets aussi, mais c’est différent.
Méthode 1 : Secrets au niveau du repo (via UI)
Dans l’UI Droney, va sur ton repo → Settings → Secrets. Ajoute tes variables :
DOCKER_USERNAMEDOCKER_PASSWORDDEPLOY_SSH_KEY
Elles seront injectées automatiquement dans tes pipelines.
Méthode 2 : Secrets externalisés (recommandé)
Pour plus de sécurité, utilise un vault externe :
steps:
- name: deploy
image: alpine
environment:
VAULT_ADDR: http://vault.internal
VAULT_TOKEN: { from_secret: vault_token }
commands:
- apk add --no-cache curl jq
- export DB_PASSWORD=$(curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
$VAULT_ADDR/v1/secret/db | jq -r .data.password)
- ./deploy.sh
Pourquoi c’est mieux ?
- Tes secrets ne sont pas stockés dans Droney
- Rotation facile
- Audit trail (qui a accédé à quoi)
Le piège : Droney par défaut mask les secrets dans les logs. Mais si tu fais echo $SECRET dans ton script, il s’affichera en clair. Fais gaffe.
Scaling : Un runner ne suffit pas
Quand j’ai commencé, un runner = suffisant.
Puis j’ai ajouté 5 nouveaux projets. Les builds ont commencé à faire la queue.
Solution : Multiple runners
Droney supporte nativement le scaling horizontal :
# Runner 1 (VPS Paris)
docker run -d \
-e DRONE_RPC_HOST=drone-server \
-e DRONE_RUNNER_NAME=runner-paris \
-e DRONE_RUNNER_CAPACITY=2 \
...
# Runner 2 (VPS Frankfurt)
docker run -d \
-e DRONE_RPC_HOST=drone-server \
-e DRONE_RUNNER_NAME=runner-frankfurt \
-e DRONE_RUNNER_CAPACITY=2 \
...
Les deux runners se connectent au même server. Droney dispatch les jobs au premier disponible.
Avantage :
- Build parallèles réels
- Redondance (si un runner tombe, l’autre prend le relais)
Inconvénient :
- Faut gérer plusieurs machines
- Le cache n’est pas partagé (chaque runner a son propre cache Docker)
Pour aller plus loin : Runner auto-scaling
Droney supporte les runners Kubernetes et les runners “dynamic” qui spawn des containers à la demande.
Honnêtement ? C’est overkill sauf si tu as 50+ builds/jour. Commence simple.
Ce que j’aurais aimé savoir avant de migrer
1. Les webhooks GitHub peuvent foirer
Parfois, GitHub envoie pas le webhook. Ou Droney le rate. Résultat : tu push, rien ne se lance.
Fix : Dans l’UI Droney, y’a un bouton “Trigger Build” manuel. Utile en cas de doute.
Tu peux aussi checker les logs :
docker logs drone-server | grep webhook
2. Le debugging est moins évident
GitHub Actions : tu vois chaque step en temps réel, logs colorés, UI propre.
Droney : logs bruts. Si un step crash, tu dois lire les logs Docker pour comprendre.
Astuce : Ajoute un step de debug :
- name: debug
image: alpine
commands:
- env
- ls -la
- cat package.json
3. Pas de marketplace de plugins
GitHub Actions : uses: actions/checkout@v4, uses: docker/setup-buildx@v3, etc.
Droney : Tout est dans des containers. Tu dois trouver ou builder tes propres images.
Exemple : Pour déployer sur Kubernetes, tu peux pas juste uses: azure/k8s-deploy@v1. Tu dois monter un container avec kubectl configuré.
** workaround :** Utilise des images officielles :
bitnami/kubectlpour Kubernetesamazon/aws-clipour AWSgoogle/cloud-sdkpour GCP
4. La migration prend plus de temps que prévu
J’avais estimé 2h. Ça m’a pris 2 jours.
Pourquoi ? Parce que :
- Faut réécrire tous les workflows (syntax différente)
- Faut debugger les problèmes de cache
- Faut configurer les secrets manuellement
- Faut tester en prod (oui, j’ai cassé 3 déploiements avant de comprendre)
Conseil : Migre un repo à la fois. Commence par le moins critique.
GitHub Actions vs Droney : Le verdict honnête
Reste sur GitHub Actions si :
- Tu as < 1000 minutes/mois (donc gratuit)
- Tu veux du plug-and-play
- Tu as besoin du marketplace (plein d’actions préfaites)
- Tu veux l’intégration native GitHub (PR checks, status, etc.)
Passe à Droney si :
- Tu dépasses les 2000 minutes/mois (donc payant)
- Tu veux کنترل total sur ton infra
- Tu as déjà un VPS qui tourne de toute façon
- Tu veux optimizer les builds Docker (cache persistant, hardware dédié)
- Tu veux apprendre comment fonctionne un CI/CD “sous le capot”
Mon cas : J’ai switché pour l’argent (économise ~10€/mois). Mais je reste pour le contrôle.
Quand un build foire, je peux checker les logs du container directement. Je peux tuner le hardware. Je ne suis pas limité par les quotas GitHub.
Alternatives à Droney
J’ai mentionné Jenkins et GitLab CI. Mais y’a d’autres options :
Woodpecker CI
Fork de Drone (avant le rachat par Harness). Plus communautaire, updates plus fréquentes. Syntax compatible.
Pourquoi choisir : Si tu veux du 100% open-source sans boîte commerciale derrière.
Gitea Actions
Si tu utilises déjà Gitea (alternative à GitHub), leur CI intégré est basé sur Act (le runner GitHub Actions open-source).
Pourquoi choisir : Tout-in-one. Repo + CI au même endroit.
GitHub Self-Hosted Runners
Tu peux runner des jobs GitHub Actions sur ta propre machine.
# Dans repo Settings → Actions → Runners
./config.sh --url https://github.com/ton-repo --token XYZ
Pourquoi choisir : Tu gardes la syntax GitHub Actions, mais avec ton propre hardware. Meilleur des deux mondes.
Inconvénient : Toujours dépendant de GitHub pour l’orchestration.
Conclusion : Est-ce que ça vaut le coup ?
Oui, si :
- Tu payes déjà pour GitHub Actions
- Tu as un VPS qui tourne (coût marginal = 0)
- Tu es à l’aise avec Docker
- Tu veux apprendre le CI/CD “bas niveau”
Non, si :
- Tu es dans les limites gratuites
- Tu veux juste que ça marche
- Tu as pas le temps de maintenir un service de plus
Mon bilan après 3 mois :
- Économies : ~30€ (j’ai 3 projets qui auraient nécessité des plans payants)
- Temps investi : 2 jours de setup + maintenance minimale
- Satisfaction : Élevée. J’ai appris un max sur les runners, les webhooks, le cache Docker.
Et honnêtement ? Voir mes builds tourner sur mon serveur, avec ma config, sans dépendre d’un provider… ça fait plaisir.
Ressources
- Drone Documentation Officielle
- Drone Docker Runner
- GitHub Self-Hosted Runners
- Kaniko Documentation (build Docker sans Docker)
Écrit le 2026-03-21 sur un VPS Hetzner CX11 (2 vCPU, 2GB RAM). Tests réalisés sur 3 repos personnels avec ~50 builds/semaine.
Stay in the loop 📬
Get self-hosting tutorials, tool reviews, and infrastructure tips delivered to your inbox. No spam, unsubscribe anytime.
Join 0 self-hosters. Free forever.