DEV Community

Alex Spinov
Alex Spinov

Posted on

Woodpecker CI Has a Free API: Self-Hosted CI/CD That's Actually Simple

What is Woodpecker CI?

Woodpecker CI is a community fork of Drone CI — a lightweight, container-based CI/CD system. It's simple, fast, and self-hosted. Every pipeline step runs in a Docker container.

No YAML complexity of GitHub Actions. No vendor lock-in.

Setup with Docker Compose

# docker-compose.yml
version: '3'
services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:latest
    ports:
      - 8000:8000
    volumes:
      - woodpecker-server-data:/var/lib/woodpecker/
    environment:
      WOODPECKER_OPEN: true
      WOODPECKER_HOST: https://ci.myserver.com
      WOODPECKER_GITHUB: true
      WOODPECKER_GITHUB_CLIENT: ${GITHUB_CLIENT}
      WOODPECKER_GITHUB_SECRET: ${GITHUB_SECRET}
      WOODPECKER_ADMIN: myuser

  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:latest
    depends_on: [woodpecker-server]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      WOODPECKER_SERVER: woodpecker-server:9000
      WOODPECKER_AGENT_SECRET: ${AGENT_SECRET}

volumes:
  woodpecker-server-data:
Enter fullscreen mode Exit fullscreen mode
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Pipeline Configuration

# .woodpecker.yml
steps:
  - name: install
    image: node:20
    commands:
      - npm ci

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

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

  - name: build
    image: node:20
    commands:
      - npm run build
    when:
      branch: main

  - name: deploy
    image: plugins/docker
    settings:
      repo: myorg/my-app
      tags: latest
      username:
        from_secret: docker_username
      password:
        from_secret: docker_password
    when:
      branch: main
      event: push
Enter fullscreen mode Exit fullscreen mode

The REST API

export WP_URL="https://ci.myserver.com/api"
export WP_TOKEN="your-token"

# List repos
curl -s "$WP_URL/user/repos" \
  -H "Authorization: Bearer $WP_TOKEN" | jq '.[].full_name'

# Get pipeline status
curl -s "$WP_URL/repos/myorg/my-app/pipelines/latest" \
  -H "Authorization: Bearer $WP_TOKEN" | jq '.status'

# Trigger a build
curl -X POST "$WP_URL/repos/myorg/my-app/pipelines" \
  -H "Authorization: Bearer $WP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"branch": "main"}'

# List secrets
curl -s "$WP_URL/repos/myorg/my-app/secrets" \
  -H "Authorization: Bearer $WP_TOKEN" | jq '.[].name'

# Add secret
curl -X POST "$WP_URL/repos/myorg/my-app/secrets" \
  -H "Authorization: Bearer $WP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "deploy_key", "value": "secret-value"}'
Enter fullscreen mode Exit fullscreen mode

Services (Databases in CI)

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

services:
  - name: postgres
    image: postgres:16
    environment:
      POSTGRES_DB: test
      POSTGRES_PASSWORD: test

  - name: redis
    image: redis:7
Enter fullscreen mode Exit fullscreen mode

Services run alongside your pipeline — real databases for integration tests.

Matrix Builds

matrix:
  NODE_VERSION:
    - 18
    - 20
    - 22

steps:
  - name: test
    image: node:${NODE_VERSION}
    commands:
      - npm ci
      - npm test
Enter fullscreen mode Exit fullscreen mode

Woodpecker vs Others

Feature Woodpecker GitHub Actions Jenkins
Self-hosted Yes No (runners yes) Yes
Config YAML (simple) YAML (complex) Groovy
Container-native Yes Partial Plugin
Resource usage ~50MB RAM N/A 1GB+ RAM
UI Clean, modern GitHub-integrated Dated

Need CI/CD setup or DevOps automation?

📧 spinov001@gmail.com
🔧 My tools on Apify Store

What CI/CD do you self-host? Comment below!

Top comments (0)