Woodpecker CI est un serveur CI/CD open source auto-hébergeable, fork communautaire de Drone CI maintenu après que Drone soit passé sous modèle commercial. Il adopte une architecture server + agent : le serveur gère l'orchestration et l'UI, les agents exécutent les pipelines dans des conteneurs Docker. Les pipelines sont définis dans des fichiers .woodpecker.yaml versionnés dans le dépôt. Woodpecker s'authentifie via OAuth2 auprès de GitHub, GitLab, Gitea, Forgejo, Codeberg ou Bitbucket.
Informations essentielles
Origine : Communauté (fork de Drone CI) · Licence : Apache 2.0 · Architectures : x86_64, ARM64
Liens : Site officiel · Documentation · GitHub · Releases
Support : Projet communautaire actif, releases fréquentes.
Stack par défaut
| Composant | Valeur |
|---|---|
| Server | woodpeckerci/woodpecker-server |
| Agent | woodpeckerci/woodpecker-agent |
| Port server (web) | 8000 (HTTP) |
| Port server (gRPC agents) | 9000 |
| Base de données | SQLite (défaut), PostgreSQL, MySQL |
| Exécution pipelines | Docker (par défaut), Kubernetes, local |
| Fichier pipeline | .woodpecker.yaml (ou .woodpecker/*.yaml) |
Prérequis
| Ressource | Valeur |
|---|---|
| Docker | Engine installé sur la machine agent |
| OAuth2 | Application OAuth créée sur GitHub/GitLab/Gitea/Forgejo |
| DNS | URL publique accessible depuis le SCM (pour les webhooks) |
Installation
1. Créer l'application OAuth (exemple GitHub)
Sur https://github.com/settings/applications/new :
- Application name : Woodpecker CI
- Homepage URL :
https://woodpecker.example.com - Authorization callback URL :
https://woodpecker.example.com/authorize
Récupérer le Client ID et le Client Secret.
2. Docker Compose
# docker-compose.yml
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker-server
restart: always
ports:
- "8000:8000" # Interface web
- "9000:9000" # gRPC pour les agents
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
# URL publique du serveur (utilisée pour les webhooks Git)
- WOODPECKER_HOST=https://woodpecker.example.com
# Secret partagé server <-> agents (générer avec: openssl rand -hex 32)
- WOODPECKER_AGENT_SECRET=changeme-use-a-random-secret
# Authentification GitHub
- WOODPECKER_GITHUB=true
- WOODPECKER_GITHUB_CLIENT=<client-id>
- WOODPECKER_GITHUB_SECRET=<client-secret>
# Restreindre l'accès à certaines organisations (optionnel)
# - WOODPECKER_ORGS=mon-org
# Base de données (PostgreSQL recommandé en prod)
# - WOODPECKER_DATABASE_DRIVER=postgres
# - WOODPECKER_DATABASE_DATASOURCE=postgres://user:pass@postgres/woodpecker?sslmode=disable
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
container_name: woodpecker-agent
restart: always
depends_on:
- woodpecker-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=changeme-use-a-random-secret
# Nombre de pipelines parallèles sur cet agent
- WOODPECKER_MAX_PROCS=2
volumes:
woodpecker-server-data:
docker compose up -d
# Ouvrir https://woodpecker.example.com
Authentification GitLab
environment:
- WOODPECKER_GITLAB=true
- WOODPECKER_GITLAB_CLIENT=<app-id>
- WOODPECKER_GITLAB_SECRET=<app-secret>
- WOODPECKER_GITLAB_URL=https://gitlab.com # ou instance privée
Authentification Gitea / Forgejo
environment:
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_CLIENT=<client-id>
- WOODPECKER_GITEA_SECRET=<client-secret>
- WOODPECKER_GITEA_URL=https://gitea.example.com
Écrire un pipeline
Le fichier .woodpecker.yaml est à la racine du dépôt.
Pipeline basique
# .woodpecker.yaml
steps:
- name: test
image: golang:1.22-alpine
commands:
- go test ./...
- name: build
image: golang:1.22-alpine
commands:
- go build -o app ./cmd/server
- name: docker-build
image: woodpeckerci/plugin-docker-buildx
settings:
repo: ghcr.io/org/my-app
tags: latest
username:
from_secret: registry_user
password:
from_secret: registry_password
when:
branch: main
Conditions d'exécution
steps:
- name: deploy-prod
image: bitnami/kubectl
commands:
- kubectl apply -f manifests/
when:
branch: main # Uniquement sur la branche main
event: push # Uniquement sur les push (pas les PR)
Variables secrètes
steps:
- name: deploy
image: alpine
environment:
DB_PASSWORD:
from_secret: db_password # Secret défini dans l'UI Woodpecker
commands:
- echo "deploying..."
Les secrets sont définis dans l'UI Woodpecker : Settings > Secrets (niveau repo, organisation ou global).
Pipelines parallèles
steps:
- name: test-unit
image: golang:1.22
commands:
- go test ./pkg/...
depends_on: []
- name: test-integration
image: golang:1.22
commands:
- go test ./integration/...
depends_on: [] # depends_on vide = parallèle
- name: build
image: golang:1.22
commands:
- go build ./...
depends_on: # Attend les deux tests
- test-unit
- test-integration
Mise à jour
docker compose pull && docker compose up -d
Troubleshooting
# Logs du serveur
docker logs woodpecker-server --tail 50 -f
# Logs de l'agent
docker logs woodpecker-agent --tail 50 -f
# Webhook non déclenché
# Vérifier que WOODPECKER_HOST est accessible depuis le SCM
# Vérifier les webhooks dans les settings du dépôt sur GitHub/GitLab
# Pipeline échoué : voir les logs dans l'UI Woodpecker
# ou via les logs de l'agent pendant l'exécution
# L'agent ne se connecte pas au serveur
# Vérifier WOODPECKER_AGENT_SECRET identique server et agent
# Vérifier que le port 9000 est accessible (gRPC)
Ressources
- Site officiel : https://woodpecker-ci.org
- Documentation : https://woodpecker-ci.org/docs/
- GitHub : https://github.com/woodpecker-ci/woodpecker
- Plugins : https://woodpecker-ci.org/plugins
- Releases : https://github.com/woodpecker-ci/woodpecker/releases