Why Woodpecker CI?

Woodpecker CI is a community-driven fork of Drone CI, offering a lightweight yet feature-rich CI/CD solution perfect for developers who want full control over their build infrastructure.

Key Advantages

  • Lightweight footprint — ideal for VPS
  • Container-native — isolated Docker steps
  • Simple YAML configuration
  • Multi-platform support (Linux, Windows, ARM)
  • Active community & regular updates
  • No vendor lock-in

Supported Git Forges

  • GitHub
  • GitLab
  • Gitea
  • Forgejo
  • Bitbucket

Prerequisites

Before beginning, ensure you have:

Server Requirements

  • RamNode VPS with 2GB+ RAM recommended
  • Ubuntu 22.04 or 24.04 LTS
  • Root or sudo access
  • Domain name pointed to your server

Required Ports

  • 22/TCP: SSH access
  • 80/TCP: HTTP traffic
  • 443/TCP: HTTPS traffic

Update System & Install Utilities

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget gnupg lsb-release ca-certificates apt-transport-https

Configure Firewall

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Install Docker

Woodpecker runs as Docker containers. Install Docker Engine:

Add Docker Repository

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install Docker Engine

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Enable Docker & Verify

sudo systemctl enable docker
sudo systemctl start docker
docker --version

# Optional: Add user to docker group
sudo usermod -aG docker $USER
newgrp docker

Create OAuth Application

Woodpecker authenticates users through your Git forge. Create an OAuth application:

GitHub

Settings → Developer settings → OAuth Apps → New OAuth App

GitLab

User Settings → Applications

Gitea/Forgejo

Site Administration → Applications

💡 Tip: Save the Client ID and Client Secret — you'll need these in the next step.

Configure Woodpecker Server

Create the configuration directory and Docker Compose file:

Create Directory & Generate Secret

sudo mkdir -p /opt/woodpecker
cd /opt/woodpecker

# Generate agent secret
openssl rand -hex 32

Create docker-compose.yml

sudo nano docker-compose.yml

docker-compose.yml

version: '3.8'

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:latest
    container_name: woodpecker-server
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - woodpecker-server-data:/var/lib/woodpecker/
    environment:
      # Server Configuration
      - WOODPECKER_HOST=https://ci.yourdomain.com
      - WOODPECKER_OPEN=true
      - WOODPECKER_ADMIN=your-git-username

# Agent Secret (use the value generated earlier)
      - WOODPECKER_AGENT_SECRET=your-generated-secret-here

# GitHub Configuration
      - WOODPECKER_GITHUB=true
      - WOODPECKER_GITHUB_CLIENT=your-github-client-id
      - WOODPECKER_GITHUB_SECRET=your-github-client-secret

# GitLab Configuration (uncomment for GitLab)
      # - WOODPECKER_GITLAB=true
      # - WOODPECKER_GITLAB_URL=https://gitlab.com
      # - WOODPECKER_GITLAB_CLIENT=your-gitlab-client-id
      # - WOODPECKER_GITLAB_SECRET=your-gitlab-client-secret

# Gitea Configuration (uncomment for Gitea)
      # - WOODPECKER_GITEA=true
      # - WOODPECKER_GITEA_URL=https://gitea.yourdomain.com
      # - WOODPECKER_GITEA_CLIENT=your-gitea-client-id
      # - WOODPECKER_GITEA_SECRET=your-gitea-client-secret

woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:latest
    container_name: woodpecker-agent
    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=your-generated-secret-here
      - WOODPECKER_MAX_WORKFLOWS=4

volumes:
  woodpecker-server-data:

Nginx & SSL Configuration

Set up Nginx as a reverse proxy with SSL:

Install Nginx

sudo apt install -y nginx

Create Nginx Configuration

sudo nano /etc/nginx/sites-available/woodpecker

Nginx Server Block

server {
    listen 80;
    server_name ci.yourdomain.com;

location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
    }
}

Enable Site & Get SSL Certificate

sudo ln -s /etc/nginx/sites-available/woodpecker /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

# Install Certbot and get SSL certificate
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d ci.yourdomain.com

# Verify auto-renewal
sudo certbot renew --dry-run

Launch Woodpecker

Start the Woodpecker server and agent:

cd /opt/woodpecker
sudo docker compose up -d

# Verify containers are running
docker compose ps

# Check logs for any issues
docker compose logs -f woodpecker-server

Success: Navigate to https://ci.yourdomain.com and login with your Git forge credentials.

Create Your First Pipeline

Create a .woodpecker.yml file in your repository root:

Node.js Pipeline Example

steps:
  - name: install
    image: node:20-alpine
    commands:
      - npm ci

- name: lint
    image: node:20-alpine
    commands:
      - npm run lint

- name: test
    image: node:20-alpine
    commands:
      - npm test

- name: build
    image: node:20-alpine
    commands:
      - npm run build

Python Pipeline Example

steps:
  - name: install
    image: python:3.12-slim
    commands:
      - pip install -r requirements.txt

- name: lint
    image: python:3.12-slim
    commands:
      - pip install flake8
      - flake8 .

- name: test
    image: python:3.12-slim
    commands:
      - pip install pytest
      - pytest

💡 Tip: Enable your repository in the Woodpecker UI, then commit and push the pipeline file to trigger your first build.

Advanced Configuration

Explore advanced pipeline features:

Using Secrets

Secrets in Pipelines

steps:
  - name: deploy
    image: alpine
    secrets: [docker_username, docker_password]
    commands:
      - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin
      - docker push myregistry/myapp:latest

Conditional Execution

Branch-based Deployment

steps:
  - name: deploy-staging
    image: alpine
    commands:
      - ./deploy.sh staging
    when:
      branch: develop

- name: deploy-production
    image: alpine
    commands:
      - ./deploy.sh production
    when:
      branch: main
      event: push

Matrix Builds

Test Multiple Versions

matrix:
  NODE_VERSION:
    - 18
    - 20
    - 22

steps:
  - name: test
    image: node:${NODE_VERSION}-alpine
    commands:
      - npm ci
      - npm test

Services

Database for Integration Tests

services:
  - name: database
    image: postgres:16
    environment:
      - POSTGRES_USER=test
      - POSTGRES_PASSWORD=test
      - POSTGRES_DB=testdb

steps:
  - name: test
    image: node:20-alpine
    environment:
      - DATABASE_URL=postgres://test:test@database:5432/testdb
    commands:
      - npm ci
      - npm test

Security Best Practices

Secure your Woodpecker installation:

Security Recommendations

  • Disable Open Registration: Set WOODPECKER_OPEN=false after initial setup
  • Configure User Allowlist: Use WOODPECKER_ORGS=your-organization
  • Use Repository Trust Wisely: Only mark repos as trusted when necessary
  • Rotate Secrets Regularly: Regenerate agent secret and OAuth credentials
  • Network Isolation: Place agent on internal network with limited access

Troubleshooting

Common Issues

  • Pipeline stuck in pending: Verify agent is connected and running
  • OAuth callback errors: Ensure callback URL matches exactly (including https and /authorize)
  • Agent cannot pull images: Confirm Docker is running and has socket access
  • SSL certificate issues: Verify Certbot renewal is working
  • Build containers cannot access network: Check Docker network and firewall rules

Maintenance Commands

# View logs
docker compose logs -f
docker compose logs -f woodpecker-server
docker compose logs -f woodpecker-agent

# Update Woodpecker
cd /opt/woodpecker
docker compose pull
docker compose up -d

# Monitor resource usage
docker stats woodpecker-server woodpecker-agent

# Backup data
docker run --rm -v woodpecker-server-data:/data -v $(pwd):/backup alpine tar czf /backup/woodpecker-backup-$(date +%Y%m%d).tar.gz /data

Next Steps

Your Woodpecker CI is now ready! Consider these next steps:

  • Add additional agents for parallel builds
  • Integrate with container registries for automated deployments
  • Connect multiple Git forges to centralize CI/CD
  • Set up notifications (Slack, Discord, email)
  • Configure cron jobs for scheduled builds

For advanced configurations, consult the official Woodpecker documentation.