Introduction to Woodpecker CI
Woodpecker CI is a community-driven, open-source continuous integration and continuous deployment (CI/CD) server. Originally a fork of Drone CI, it has evolved into a robust, independent platform that leverages Docker containers to execute pipeline steps. It integrates seamlessly with popular version control systems like GitHub, GitLab, Gitea, and Bitbucket.
Why does Woodpecker CI matter? In modern software development, automated testing and deployment are non-negotiable. Woodpecker provides a lightweight, highly scalable, and container-native approach to CI/CD. Because every step in a Woodpecker pipeline runs inside its own Docker container, developers are guaranteed a clean, isolated, and reproducible environment. This eliminates the "it works on my machine" problem and drastically simplifies dependency management.
Core Concepts of Woodpecker CI
Before diving into configuration, it is essential to understand the fundamental building blocks of Woodpecker CI.
Pipelines and Steps
A pipeline is a sequence of automated processes triggered by an event in your version control system (such as a push or a pull request). Pipelines are defined in a YAML file (typically .woodpecker.yml) located at the root of your repository. Each pipeline consists of multiple steps. A step represents a single command or script executed inside a Docker container.
Server and Agents
Woodpecker uses a distributed architecture consisting of a central Server and one or more Agents. The Server is the brain of the operation: it handles webhooks from your Git provider, manages the database, and serves the web UI. The Agents are the workers; they connect to the Server, receive pipeline jobs, and execute the Docker containers required to run the steps.
Installation and Setup
The easiest way to get started with Woodpecker CI is by using Docker Compose. This method allows you to spin up both the Woodpecker Server and a Woodpecker Agent alongside a database in a matter of minutes.
Docker Compose Setup
Below is a basic docker-compose.yml file to run Woodpecker CI. You will need to replace the OAuth client ID and secret with credentials generated from your Git hosting provider (e.g., GitHub or Gitea).
version: '3'
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
ports:
- "8000:8000"
- "9000:9000"
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_OPEN=true
- WOODPECKER_HOST=http://localhost:8000
- WOODPECKER_GITHUB=true
- WOODPECKER_GITHUB_CLIENT=YOUR_GITHUB_CLIENT_ID
- WOODPECKER_GITHUB_SECRET=YOUR_GITHUB_CLIENT_SECRET
- WOODPECKER_AGENT_SECRET=YOUR_SHARED_AGENT_SECRET
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
command: 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=YOUR_SHARED_AGENT_SECRET
volumes:
woodpecker-server-data:
Once you run docker-compose up -d, you can navigate to http://localhost:8000 to access the Woodpecker UI and authorize your Git account.
Writing Your First Pipeline
To automate your project, create a .woodpecker.yml file in the root of your repository. This file dictates what happens when code is pushed.
The .woodpecker.yml File
Here is a simple example of a pipeline for a Node.js application. It installs dependencies, runs tests, and builds the project.
steps:
install:
image: node:18-alpine
commands:
- npm ci
test:
image: node:18-alpine
commands:
- npm test
build:
image: node:18-alpine
commands:
- npm run build
In this configuration, Woodpecker will execute three steps sequentially. Each step uses the node:18-alpine Docker image. Woodpecker automatically clones your repository into the working directory before running the first step, and the workspace is shared between steps, allowing build artifacts to persist.
Advanced Configuration
As your project grows, you will need more control over when and how your pipelines run. Woodpecker provides powerful features for conditional execution, matrix builds, and secret management.
Conditional Execution
You can use the when block to restrict when a step or pipeline should run. For example, you might only want to deploy your application when code is pushed to the main branch.
steps:
build:
image: node:18-alpine
commands:
- npm run build
deploy:
image: alpine:latest
commands:
- echo "Deploying to production..."
when:
branch: main
event: push
This configuration ensures that the deploy step is skipped unless the triggering event is a push to the main branch.
Matrix Builds
Matrix builds allow you to run the same pipeline across multiple environments simultaneously. This is incredibly useful for testing compatibility across different language versions or operating systems.
matrix:
NODE_VERSION:
- 16
- 18
- 20
steps:
test:
image: node:${NODE_VERSION}-alpine
commands:
- npm ci
- npm test
With this configuration, Woodpecker will spawn three parallel executions of the test step, using Node.js 16, 18, and 20 respectively.
Secrets and Environment Variables
Hardcoding sensitive information like API keys or database passwords in your .woodpecker.yml file is a major security risk. Woodpecker allows you to inject secrets securely. You can add secrets via the Woodpecker UI or the CLI, and then reference them in your pipeline.
steps:
deploy:
image: alpine:latest
commands:
- echo $DEPLOY_TOKEN
secrets: [ deploy_token ]
When this step runs, Woodpecker will inject the deploy_token secret into the container as the DEPLOY_TOKEN environment variable.
Best Practices
To get the most out of Woodpecker CI, consider the following best practices:
- Use specific image tags: Avoid using
latestfor your step images. Pinning specific versions (e.g.,node:18.19.0-alpine) ensures your pipelines remain stable and reproducible over time. - Keep steps small and focused: Break down large, monolithic scripts into smaller, logical steps. This makes it easier to identify failures and allows Woodpecker to cache and parallelize more effectively.
- Leverage caching: Re-downloading dependencies for every build is slow. Use Woodpecker's volume caching or external caching mechanisms (like caching a directory to a persistent volume) to speed up your pipelines.
- Protect your secrets: Always use Woodpecker's built-in secret management for sensitive data. Never commit credentials to your version control system.
- Optimize Docker images: Use Alpine-based images or slim variants where possible to reduce the time it takes to pull the image and start the container.
Conclusion
Woodpecker CI is a powerful, flexible, and container-native CI/CD engine that fits perfectly into modern cloud-native workflows. By understanding its core concepts, mastering the YAML configuration syntax, and adhering to best practices, you can automate your testing and deployment processes with confidence. Whether you are running a small open-source project or a large-scale enterprise application, Woodpecker's distributed architecture and Docker-based execution model provide the reliability and scalability you need to ship code faster and more securely.