Woodpecker CI mit Docker installieren: Schlanke CI/CD-Engine für Gitea und Forgejo
Woodpecker CI v3 mit Docker Compose an Gitea oder Forgejo anbinden: OAuth2, Agent, HTTPS über Reverse Proxy, erste Pipeline, Updates, Backup und sicherer Umgang mit dem Docker-Socket.
Geprüft am 10.10.2026 · für Woodpecker Server 3.19.0, Woodpecker Agent 3.19.0
WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Woodpecker CI ist ein quelloffenes CI/CD-System für selbst gehostete Git-Server wie Gitea und Forgejo. Es entstand als Community-Fork von Drone CI und besteht aus zwei Containern: dem Server mit Web-Oberfläche und API sowie einem Agent, der jeden Pipeline-Schritt in einem eigenen Docker-Container ausführt. Diese Anleitung richtet sich an Linux-Administratoren, die Gitea oder Forgejo bereits betreiben und Tests, Builds und Deployments ohne Jenkins oder Kubernetes automatisieren wollen.
Voraussetzungen
- Docker Engine mit Docker Compose v2 auf einem Linux-Server, siehe Docker und Docker Compose auf Linux installieren.
- Laufende Gitea- oder Forgejo-Instanz mit Administratorzugang, siehe Gitea mit Docker.
- Domain für Woodpecker (zum Beispiel
ci.example.com), die der Git-Server erreicht. Ohne sie kommen keine Webhooks an. - Reverse Proxy mit TLS, zum Beispiel Caddy mit automatischem HTTPS.
- Mindestens 1 vCPU, 1 GB RAM und einige GB Speicher für Build-Images. amd64 und arm64 werden unterstützt.
- Ein eigener Host oder eine eigene VM für den Agent, wenn Dritte Pipelines ausführen dürfen (siehe Sicherheitshinweis in Schritt 4).
Schritt 1: Projektordner und Secret anlegen
Legen Sie ein Verzeichnis für den Stack an und erzeugen Sie das Agent-Secret. Server und Agent authentifizieren sich damit gegenseitig und müssen denselben Wert tragen:
sudo mkdir -p /opt/woodpecker
cd /opt/woodpecker
openssl rand -hex 32Behandeln Sie den Wert wie ein Passwort. Bei einem Leck tauschen Sie ihn auf Server und Agent gleichzeitig aus.
Verifizieren: ls -ld /opt/woodpecker zeigt das Verzeichnis, und openssl hat einen 64-stelligen Hex-Wert ausgegeben.
Schritt 2: OAuth-App in Gitea oder Forgejo erstellen
Woodpecker hat keine eigene Benutzerverwaltung, die Anmeldung läuft über OAuth2 beim Git-Server. Der Ablauf ist in Gitea und Forgejo gleich:
- Als Administrator anmelden und Website-Administration → Integrationen → Anwendungen öffnen (
/admin/settings/applications). Alternativ geht eine benutzerbezogene Anwendung unter Einstellungen → Anwendungen. - Namen vergeben, zum Beispiel
Woodpecker CI. - Als Weiterleitungs-URI exakt
https://ci.example.com/authorizeeintragen. Schema, Hostname und Pfad müssen genau mitWOODPECKER_HOSTübereinstimmen. - Speichern und Client-ID sowie Client-Secret notieren. Das Secret wird nur einmal angezeigt.
Verifizieren: Die Anwendung erscheint in der Liste mit der richtigen Weiterleitungs-URI, Client-ID und Client-Secret sind notiert.
Schritt 3: .env-Datei anlegen
Legen Sie /opt/woodpecker/.env an. Docker Compose liest die Datei automatisch:
WOODPECKER_HOST=https://ci.example.com
WOODPECKER_AGENT_SECRET=AUSGABE_VON_OPENSSL_RAND_HEX_32
WOODPECKER_ADMIN=ihr-gitea-benutzername
# Gitea
WOODPECKER_GITEA=true
WOODPECKER_GITEA_URL=https://git.example.com
WOODPECKER_GITEA_CLIENT=CLIENT_ID_AUS_SCHRITT_2
WOODPECKER_GITEA_SECRET=CLIENT_SECRET_AUS_SCHRITT_2WOODPECKER_HOSTenthält das Schema und keinen abschließenden Schrägstrich.- Für Forgejo nutzen Sie den eigenen Treiber:
WOODPECKER_FORGEJO=true,WOODPECKER_FORGEJO_URL,WOODPECKER_FORGEJO_CLIENTundWOODPECKER_FORGEJO_SECRETstatt derGITEA-Variablen. Passen Sie die Namen dann auch in dercompose.yamlan. - Die Registrierung bleibt geschlossen (
WOODPECKER_OPEN=falseist Standard). Die inWOODPECKER_ADMINgenannten Benutzer dürfen sich trotzdem anmelden, weitere Benutzer legen Sie später an oder öffnen die Registrierung gezielt.
chmod 600 /opt/woodpecker/.envVerifizieren: grep -c '_AUS_\|AUSGABE_' /opt/woodpecker/.env liefert 0 (keine Platzhalter mehr), und stat -c %a /opt/woodpecker/.env liefert 600.
Schritt 4: compose.yaml erstellen
Die Datei orientiert sich an der offiziellen Vorlage. Die Images sind auf eine Version festgelegt, Port 8000 ist nur lokal erreichbar, Port 9000 wird nicht veröffentlicht. Die Images enthalten einen eingebauten Healthcheck (woodpecker-server ping), ein eigener ist nicht nötig. Da die Images keine Shell und kein wget enthalten, würde ein Healthcheck mit wget immer fehlschlagen.
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:v3.19.0
restart: unless-stopped
ports:
- "127.0.0.1:8000:8000"
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_HOST=${WOODPECKER_HOST}
- WOODPECKER_ADMIN=${WOODPECKER_ADMIN}
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
- WOODPECKER_GITEA=${WOODPECKER_GITEA}
- WOODPECKER_GITEA_URL=${WOODPECKER_GITEA_URL}
- WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT}
- WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:v3.19.0
command: agent
restart: unless-stopped
depends_on:
- woodpecker-server
volumes:
- woodpecker-agent-config:/etc/woodpecker
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
- WOODPECKER_MAX_WORKFLOWS=2
volumes:
woodpecker-server-data:
woodpecker-agent-config:Sicherheitshinweis: Der Agent erhält Zugriff auf den Docker-Socket. Jeder, der eine Pipeline in einem aktivierten Repository ändern kann, kann darüber Container mit Root-Rechten auf dem Host starten. Aktivieren Sie nur Repositories vertrauenswürdiger Personen, lassen Sie Pipelines aus Forks nur nach Freigabe laufen und betreiben Sie den Agent bei geteilten Instanzen auf einem separaten Host.
Eckdaten auf einen Blick
| Parameter | Wert | Hinweis |
|---|---|---|
| Images | woodpeckerci/woodpecker-server:v3.19.0, woodpecker-agent:v3.19.0 | Einen latest-Tag gibt es nicht; rollierend: v3, v3.19 |
| Port Web-Oberfläche | 8000 | nur an 127.0.0.1, Zugriff über Reverse Proxy |
| Port gRPC | 9000 | nur im Docker-Netz; externe Agents nur mit TLS |
| Datenbank | SQLite im Volume woodpecker-server-data | PostgreSQL oder MySQL optional |
| Parallele Workflows | WOODPECKER_MAX_WORKFLOWS | Standard 1 |
Verifizieren: docker compose -f /opt/woodpecker/compose.yaml config --quiet endet ohne Ausgabe. Warnungen zu nicht gesetzten Variablen deuten auf Tippfehler in der .env hin.
Schritt 5: Stack starten
cd /opt/woodpecker
docker compose up -d
docker compose psVerifizieren: Nach etwa einer Minute zeigen beide Container Up (healthy). Der Health-Endpunkt antwortet mit Status 204:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8000/healthzErwartet ist 204. Bei Problemen zeigt docker compose logs woodpecker-server --tail=50 die Ursache.
Schritt 6: Reverse Proxy und HTTPS einrichten
Der Git-Server sendet Webhooks an WOODPECKER_HOST, Benutzer melden sich darüber an. Eine minimale Caddy-Konfiguration auf demselben Host:
ci.example.com {
reverse_proxy 127.0.0.1:8000
}Laden Sie Caddy danach neu (sudo systemctl reload caddy). Läuft Caddy selbst als Container, hängen Sie ihn an das Netz des Woodpecker-Stacks und nutzen woodpecker-server:8000 als Ziel.
Verifizieren: curl -s -o /dev/null -w '%{http_code}\n' https://ci.example.com/healthz liefert 204 ohne Zertifikatsfehler, und https://ci.example.com zeigt im Browser die Anmeldeseite.
Schritt 7: Erste Anmeldung und Admin-Einrichtung
https://ci.example.comöffnen und anmelden. Sie werden zum Git-Server weitergeleitet und bestätigen dort den Zugriff der OAuth-Anwendung.- Unter Einstellungen → Agents (Administration) prüfen, ob der Agent verbunden ist.
- Über Repository hinzufügen ein Repository aktivieren. Woodpecker legt dabei den Webhook im Git-Server an.
- In den Repository-Einstellungen festlegen, dass Pipelines aus Pull Requests von Forks eine Freigabe benötigen.
Verifizieren: Ihr Benutzer hat Zugriff auf den Administrationsbereich, dort ist mindestens ein Agent gelistet, und im Git-Server erscheint unter den Webhooks des Repositorys ein Eintrag, der mit https://ci.example.com/api/hook beginnt. docker compose logs woodpecker-agent --tail=20 enthält keine Meldungen zu fehlgeschlagener Authentifizierung.
Schritt 8: Erste Pipeline anlegen
Pipelines liegen als .woodpecker.yaml im Wurzelverzeichnis des Repositorys oder als mehrere Dateien im Ordner .woodpecker/. Legen Sie Image-Tags auch hier fest:
when:
- event: push
steps:
- name: test
image: alpine:3.22
commands:
- echo "Build laeuft in eigenem Container"
- uname -aCommitten und pushen Sie die Datei in ein aktiviertes Repository. Der Webhook startet die Pipeline sofort.
Verifizieren: In der Web-Oberfläche erscheint beim Repository eine neue Pipeline mit dem Status erfolgreich, der Schritt test zeigt die Ausgabe von uname -a. Bleibt die Pipeline aus, prüfen Sie im Git-Server die letzten Zustellungen des Webhooks.
Schritt 9: Updates und Backup
Lesen Sie vor jedem Update die Release Notes auf GitHub, bei Major-Versionen zusätzlich den Migrationsleitfaden. Tragen Sie dann die neue Version für Server und Agent in der compose.yaml ein:
cd /opt/woodpecker
docker compose pull
docker compose up -dFür das Backup genügt das Volume woodpecker-server-data mit der SQLite-Datenbank (Benutzer, Repositories, Pipelines, Secrets). Stoppen Sie den Server dafür kurz:
docker compose stop woodpecker-server
docker run --rm -v woodpecker_woodpecker-server-data:/data:ro -v /backup:/backup \
alpine:3.22 tar -czf /backup/woodpecker-$(date +%F).tar.gz -C /data .
docker compose start woodpecker-serverDer Volume-Name setzt sich aus Projektname (Verzeichnisname) und Volume zusammen, docker volume ls zeigt ihn. Eine vollständige Sicherungsstrategie beschreibt 3-2-1-Backup-Strategie umsetzen.
Verifizieren: curl -s https://ci.example.com/version meldet die neue Version, beide Container sind healthy, und tar -tzf /backup/woodpecker-$(date +%F).tar.gz listet ./woodpecker.sqlite.
Typische Fehler und Lösungen
- Agent verbindet sich nicht, Authentifizierungsfehler im Log: Server und Agent nutzen unterschiedliche
WOODPECKER_AGENT_SECRET-Werte. Wert in der.envprüfen und mitdocker compose up -dbeide Container neu erstellen. - Fehler zur redirect_uri bei der Anmeldung: Die Weiterleitungs-URI der OAuth-Anwendung weicht von
WOODPECKER_HOST+/authorizeab, ofthttpstatthttps. URI in der Anwendung korrigieren. - „registration closed“ bei der Anmeldung: Der Benutzername steht nicht in
WOODPECKER_ADMIN. Namen exakt wie im Git-Server eintragen. - Webhooks schlagen fehl, wenn Git-Server und Woodpecker auf demselben Host laufen: In der
app.inivon Gitea oder Forgejo im Abschnitt[webhook]ALLOWED_HOST_LIST=external,loopbacksetzen und den Git-Server neu starten. - Klonen im Pipeline-Schritt schlägt fehl: Der Klon-Container erreicht die vom Git-Server gemeldete URL nicht. Agent-Variable
WOODPECKER_BACKEND_DOCKER_NETWORKauf das Docker-Netz des Git-Servers setzen. - „permission denied“ am Docker-Socket: Socket nicht eingebunden oder Docker-Dienst gestoppt. Mount in der
compose.yamlundsystemctl status dockerprüfen. - Server bleibt „unhealthy“: Meist ist der Git-Server aus dem Container nicht erreichbar oder die Datenbank nicht beschreibbar.
docker compose logs woodpecker-server --tail=100zeigt die Ursache. - Daten nach Neustart weg: Das Volume wurde mit
docker compose down -vgelöscht.-vnur verwenden, wenn die Daten entfernt werden sollen.
Häufige Fragen
Brauche ich zwingend Gitea oder Forgejo?
Nein. Woodpecker unterstützt auch GitHub, GitLab, Bitbucket Cloud und Bitbucket Data Center. Es wird jedoch nur ein Git-Server pro Instanz angebunden.
Kann ich mehrere Agents betreiben?
Ja. Weitere Agents verbinden sich mit demselben Secret zum gRPC-Port des Servers. Liegen sie auf anderen Hosts, veröffentlichen Sie Port 9000 nur über TLS (WOODPECKER_GRPC_SECURE=true am Agent) und beschränken den Zugriff per Firewall auf die Agent-Adressen.
Wo wird die Pipeline-Konfiguration abgelegt?
Im Repository als .woodpecker.yaml oder als mehrere YAML-Dateien im Ordner .woodpecker/, die als getrennte Workflows laufen.
Läuft Woodpecker auf einem Raspberry Pi oder Apple Silicon?
Ja. Server und Agent gibt es unter anderem für linux/amd64, linux/arm64 und linux/arm. Auf einem Mac laufen sie in Docker Desktop als arm64-Container.
Wie führe ich ein Update auf eine neue Minor-Version durch?
Release Notes lesen, Tag in der compose.yaml für Server und Agent gleichzeitig anpassen, dann docker compose pull und docker compose up -d. Version 3.19.0 schließt eine Sicherheitslücke, über die Matrix-Variablen in den Standard-Clone-Schritt eingeschleust werden konnten; Bestandsinstallationen sollten deshalb zeitnah aktualisieren. Im Test lief das Update von v3.18.1 auf v3.19.0 ohne Eingriff, Server und Agent waren danach healthy, und /version meldete 3.19.0. Mit dem rollierenden Tag v3 erhalten Sie Minor-Updates automatisch, verlieren aber die Kontrolle über den Zeitpunkt.
Kann ich den Docker-Socket vermeiden?
Für das Docker-Backend ist der Socket nötig. Alternativen sind das Kubernetes-Backend, das lokale Backend ohne Container-Isolation oder ein Agent auf einer eigenen VM, die nur für Builds dient. Allgemeine Härtung für Compose-Stacks beschreibt Docker Compose absichern.
Fazit
Woodpecker CI ergänzt Gitea oder Forgejo mit wenig Aufwand um Pipelines. Entscheidend für einen sicheren Betrieb sind festgelegte Image-Versionen, eine nur lokal gebundene Web-Oberfläche hinter HTTPS, geschlossene Registrierung und die bewusste Entscheidung, wer über Pipelines Zugriff auf den Docker-Socket erhält.
Weiterführende Anleitungen und Quellen
- Gitea mit Docker: eigener Git-Server als GitHub-Alternative
- Caddy als Reverse Proxy einrichten: Anfänger-Anleitung mit automatischem HTTPS
- Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only für den Produktivbetrieb
- 3-2-1-Backup-Strategie umsetzen: Anleitung mit Restic, USB-Disk und S3-Cloud
- Docker und Docker Compose auf Linux installieren (Ubuntu/Debian): die Self-Hosting-Grundlage
Offizielle Quellen: Woodpecker CI: Docker-Compose-Installation · Forgejo-Anbindung · Releases auf GitHub


