Woodpecker CI is a community fork of Drone CI, fully open source (Apache 2.0), lightweight, and popular with self-hosters, especially alongside Gitea or Forgejo. Pipelines are YAML files in your repository, and every step runs in a container. A small VPS runs it easily.
Comparison: Drone CI and Gitea Actions (GitHub Actions-compatible, built into Gitea).
Architecture
- Server: web UI, API, receives webhooks from your forge (Gitea, Forgejo, GitHub, GitLab, Bitbucket).
- Agents: run pipeline steps using a backend (Docker, Kubernetes, or local).
1. OAuth application in Gitea/Forgejo
Settings → Applications → Create OAuth2 Application:
- name: Woodpecker;
- redirect URI:
https://ci.example.com/authorize.
Note the client ID and secret.
2. Docker Compose
# /opt/woodpecker/compose.yaml
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:v3
restart: unless-stopped
ports:
- "127.0.0.1:8000:8000"
volumes:
- ./data:/var/lib/woodpecker
environment:
WOODPECKER_HOST: https://ci.example.com
WOODPECKER_OPEN: "false"
WOODPECKER_ADMIN: youradmin
WOODPECKER_GITEA: "true"
WOODPECKER_GITEA_URL: https://git.example.com
WOODPECKER_GITEA_CLIENT: <client-id>
WOODPECKER_GITEA_SECRET: <client-secret>
WOODPECKER_AGENT_SECRET: <openssl rand -hex 32>
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:v3
restart: unless-stopped
depends_on: [woodpecker-server]
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WOODPECKER_SERVER: woodpecker-server:9000
WOODPECKER_AGENT_SECRET: <same secret>
WOODPECKER_MAX_WORKFLOWS: 2
cd /opt/woodpecker && docker compose up -d
Put Nginx with HTTPS in front of port 8000. See Nginx reverse proxy. Check the Woodpecker docs for the current major version, and environment variable names.
WOODPECKER_OPEN=false with WOODPECKER_ADMIN keeps random users of your forge from registering. The Gitea instance itself: see Gitea.
3. Enable a repository, add a pipeline
Log in, enable the repository, and add .woodpecker.yaml (or a .woodpecker/ directory with several workflow files):
when:
- event: [push, pull_request]
branch: main
steps:
- name: test
image: python:3.12-slim
commands:
- pip install -r requirements.txt
- pytest -q
- name: image
image: woodpeckerci/plugin-docker-buildx
settings:
registry: git.example.com
repo: git.example.com/team/myapp
tags: ${CI_COMMIT_SHA:0:8}
username: { from_secret: registry_user }
password: { from_secret: registry_token }
when:
- event: push
branch: main
- name: deploy
image: appleboy/drone-ssh
settings:
host: { from_secret: vps_host }
username: deploy
key: { from_secret: vps_ssh_key }
script:
- cd /opt/app && docker compose pull && docker compose up -d
when:
- event: push
branch: main
Gitea and Forgejo include a container registry, so git.example.com can host your images. Add secrets in the repository settings in Woodpecker. See GitHub Actions secrets for the general principles.
Securing agents
- The agent mounts the Docker socket: pipelines can control the host. Use dedicated build VPS agents, and restrict which repositories may run privileged plugins.
- Limit concurrency (
WOODPECKER_MAX_WORKFLOWS) to the VPS’s CPU and RAM. - Clean up images and volumes regularly. See Docker disk cleanup.
- Pull requests from forks: don’t expose secrets to them (Woodpecker requires approval for untrusted contributors).
Woodpecker vs Gitea Actions vs Drone
| Woodpecker | Gitea Actions | Drone | |
|---|---|---|---|
| Licence | Apache 2.0 | MIT (part of Gitea) | Mixed (enterprise features) |
| Syntax | Drone-like YAML | GitHub Actions-compatible | Drone YAML |
| Separate service | Yes | Built into Gitea (+ act_runner) | Yes |
| Best for | Simple, open-source CI | Reusing GitHub Actions workflows | Existing Drone users |
Quick reference
| Item | Value |
|---|---|
| Server / agent images | woodpeckerci/woodpecker-server, woodpeckerci/woodpecker-agent |
| Pipeline file | .woodpecker.yaml or .woodpecker/*.yaml |
| Shared secret | WOODPECKER_AGENT_SECRET |
| Secrets in steps | from_secret: |
| Gitea redirect URI | https://ci.example.com/authorize |
Related: CI/CD pipeline explained and Docker Compose in production.