← Back to posts
comparison guide self-hosted · · 9 min read

Woodpecker CI vs Drone CI vs Gitea Actions: Self-Hosted CI/CD Guide 2026

Complete comparison of Woodpecker CI, Drone CI, and Gitea Actions for self-hosted CI/CD pipelines. Docker deployment, feature comparison, and configuration guides.

OS
Editorial Team

Self-hosted CI/CD platforms give you full control over your build infrastructure, pipeline execution, and artifact storage. When you can’t (or don’t want to) rely on cloud services like GitHub Actions, GitLab CI, or CircleCI, open-source alternatives let you run pipelines on your own servers with no usage limits or data leaving your infrastructure.

In this guide, we compare three leading self-hosted CI/CD engines: Woodpecker CI, Drone CI, and gitea Actions. All three run as docker containers, support YAML-based pipeline definitions, and integrate with popular git forges.

Why Self-Host Your CI/CD Pipeline?

Running CI/CD on your own infrastructure offers several advantages over managed cloud services:

  • Complete data privacy — your source code, build artifacts, and secrets never leave your servers
  • No per-minute pricing — unlimited builds without worrying about cloud CI billing
  • Custom build environments — install any tool, use any base image, access internal network resources
  • Compliance and audit — meet regulatory requirements that forbid third-party build services
  • Faster local builds — no queue times when builds run on your own dedicated hardware

For teams already self-hosting their git repositories (see our Gitea vs Forgejo vs GitLab CE comparison), running CI/CD on the same infrastructure creates a fully independent development stack.

Project Overview and Stats

FeatureWoodpecker CIDrone CIGitea Actions
GitHub Stars6,83634,97254,980 (Gitea)
LanguageGoGoGo
Last UpdatedApril 2026April 2026April 2026
LicenseApache 2.0Apache 2.0MIT
ArchitectureServer + AgentServer + RunnerIntegrated (Gitea)
Pipeline FormatYAML (native)YAML (native)GitHub Actions-compatible
Docker NativeYesYesVia act_runner
Matrix BuildsYesYesYes
Pipeline ApprovalYesYesYes (via Gitea)
Shared SecretsYesYesYes (via Gitea)

Woodpecker CI

Woodpecker CI is a community-driven fork of the original Drone CI (v1.x era). It was created when Drone CI’s development shifted direction under Harness. Woodpecker focuses on simplicity, extensibility, and maintaining the clean plugin-based architecture that made the original Drone popular. It uses a server-agent architecture where the server manages pipelines and agents execute builds in isolated containers.

Drone CI (Harness)

Drone CI is the original self-hosted CI/CD platform, now developed by Harness. Drone pioneered the container-native CI/CD approach where every pipeline step runs inside a Docker container. It has a mature plugin ecosystem and supports multiple source control providers. The Harness version adds enterprise features while keeping the core open-source under an Apache 2.0 license.

Gitea Actions

Gitea Actions is a built-in CI/CD system integrated directly into the Gitea git forge. Its key advantage is GitHub Actions compatibility — existing .github/workflows/*.yml files work with minimal changes. Instead of requiring a separate CI server, Gitea Actions uses act_runner agents that execute workflows using the same runtime as GitHub Actions (nektos/act). If you’re already running Gitea, enabling Actions is nearly instant.

For teams managing CI agents across multiple platforms, see our detailed guide on self-hosted CI runners.

Feature Comparison

Pipeline Syntax

Woodpecker CI uses a straightforward YAML format with steps that map directly to container images:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# .woodpecker.yml
steps:
  test:
    image: golang:1.22
    commands:
      - go test ./...
      - go build -o myapp .

  docker-build:
    image: plugins/docker
    settings:
      repo: myregistry/myapp
      tags: [latest, "${CI_COMMIT_SHA:0:7}"]
      username:
        from_secret: docker_user
      password:
        from_secret: docker_pass

Drone CI uses nearly identical YAML syntax (both projects share common ancestry):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# .drone.yml
kind: pipeline
type: docker
name: default

steps:
- name: test
  image: golang:1.22
  commands:
  - go test ./...
  - go build -o myapp .

- name: publish
  image: plugins/docker
  settings:
    repo: myregistry/myapp
    tags: [latest]
    username:
      from_secret: docker_username
    password:
      from_secret: docker_password

Gitea Actions uses GitHub Actions-compatible syntax, making migration seamless:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# .gitea/workflows/ci.yml
name: Build and Test
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: "1.22"
      - run: go test ./...
      - run: go build -o myapp .

Deployment with Docker Compose

Woodpecker CI deployment requires a server and at least one agent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
version: "3"

services:
  woodpecker-server:
    image: woodpeckerci/woodpecker-server:v3
    ports:
      - "8000:8000"
    volumes:
      - woodpecker-data:/var/lib/woodpecker
    environment:
      - WOODPECKER_OPEN=true
      - WOODPECKER_HOST=http://ci.example.com:8000
      - WOODPECKER_GITHUB=true
      - WOODPECKER_GITHUB_CLIENT=${GITHUB_CLIENT_ID}
      - WOODPECKER_GITHUB_SECRET=${GITHUB_CLIENT_SECRET}
      - WOODPECKER_AGENT_SECRET=${AGENT_SECRET}
    networks:
      - ci-network

  woodpecker-agent:
    image: woodpeckerci/woodpecker-agent:v3
    depends_on:
      - woodpecker-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WOODPECKER_SERVER=woodpecker-server:9000
      - WOODPECKER_AGENT_SECRET=${AGENT_SECRET}
      - WOODPECKER_MAX_WORKFLOWS=4
    networks:
      - ci-network

volumes:
  woodpecker-data:

networks:
  ci-network:
    driver: bridge

Drone CI server with a runner (Gitea integration shown):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
version: "3"

services:
  drone-server:
    image: drone/drone:3
    ports:
      - "8080:80"
    volumes:
      - drone-data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_SERVER_HOST=ci.example.com
      - DRONE_SERVER_PROTO=http
      - DRONE_GITEA=true
      - DRONE_GITEA_SERVER=https://gitea.example.com
      - DRONE_GITEA_CLIENT_ID=${GITEA_CLIENT_ID}
      - DRONE_GITEA_CLIENT_SECRET=${GITEA_CLIENT_SECRET}
      - DRONE_RPC_SECRET=${RPC_SECRET}
      - DRONE_USER_CREATE=username:admin,admin:true
    restart: always

  drone-runner-docker:
    image: drone/drone-runner-docker:1
    ports:
      - "3000:3000"
    environment:
      - DRONE_RUNNER_NAME=runner-01
      - DRONE_RUNNER_CAPACITY=4
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=drone-server
      - DRONE_RPC_SECRET=${RPC_SECRET}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    restart: always
    depends_on:
      - drone-server

volumes:
  drone-data:

Gitea Actions requires act_runner — the official Gitea runner:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
version: "3"

services:
  gitea:
    image: gitea/gitea:1.22
    ports:
      - "3000:3000"
      - "222:22"
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      - GITEA__actions__ENABLED=true
    restart: always

  act-runner:
    image: gitea/act_runner:nightly
    depends_on:
      - gitea
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - CONFIG_FILE=/config.yaml
    restart: always

volumes:
  gitea-data:

Create a config.yaml for the act_runner:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
log:
  level: info

cache:
  enabled: true
  dir: /tmp/.cache

host: http://gitea:3000
secret: ${RUNNER_SECRET_TOKEN}
labels:
  - ubuntu-latest:node:18-bullseye
  - ubuntu-22.04:node:18-bullseye

Integration with Git Forges

ForgeWoodpecker CIDrone CIGitea Actions
GitHubNativeNativeN/A (GitHub has own Actions)
GiteaPluginNativeNative (built-in)
ForgejoPluginPluginNative
GitLabPluginPluginNot supported
BitbucketPluginPluginNot supported
GogsPluginPluginNot supported

Plugin Ecosystem

Drone CI has the largest plugin marketplace with hundreds of official and community plugins covering Docker builds, Slack kubernetesons, S3 uploads, Kubernetes deployments, and more. The plugin registry at plugins.drone.io serves as the central directory.

Woodpecker CI maintains compatibility with most Drone plugins, giving it access to the same ecosystem. It also develops native extensions for newer integrations. The project publishes a curated list at woodpecker-ci.org/docs/extensions.

Gitea Actions leverages the entire GitHub Actions marketplace — any action published on GitHub Marketplace works in Gitea without modification. This gives it instant access to tens of thousands of reusable workflow components.

Choosing the Right CI/CD Platform

Choose Woodpecker CI if:

  • You want the original Drone CI experience with active community development
  • You need a lightweight, standalone CI server that works with any git forge
  • You value transparency and community governance over corporate backing
  • You’re migrating from an older Drone CI installation

Choose Drone CI (Harness) if:

  • You want the most mature plugin ecosystem available
  • You need enterprise-grade support and features
  • Your team already uses other Harness platform products
  • You need advanced features like approval gates, compliance checks, and audit logging

Choose Gitea Actions if:

  • You already run Gitea or Forgejo as your git forge
  • You want GitHub Actions compatibility without leaving self-hosted infrastructure
  • You prefer an integrated solution over managing separate CI servers
  • Your team has existing GitHub Actions workflows to migrate

For webhook-based integrations between your CI/CD and other services, consider our guide to self-hosted webhook management.

Performance and Resource Usage

All three platforms use a container-based execution model, so resource consumption depends primarily on the number of concurrent builds and the workloads themselves:

  • Woodpecker CI: Server uses ~100MB RAM idle. Each agent process adds ~50MB plus container overhead. Recommended minimum: 2 CPU cores, 4GB RAM for moderate workloads (5-10 concurrent builds).

  • Drone CI: Server uses ~150MB RAM idle. Docker runners use ~50MB plus container overhead. The Drone server includes an embedded SQLite database by default. Recommended minimum: 2 CPU cores, 4GB RAM.

  • Gitea Actions: The runner (act_runner) uses ~200MB RAM idle plus the Gitea server itself (~300MB). Each concurrent job spins up a Docker container. Recommended minimum: 4 CPU cores, 8GB RAM (shared with Gitea).

FAQ

Which self-hosted CI/CD is easiest to set up?

Gitea Actions is the simplest if you already run Gitea — just enable the actions feature flag and register a runner. Woodpecker CI is the easiest standalone option with clear Docker Compose examples. Drone CI requires slightly more configuration but has excellent documentation.

Can I migrate from Drone CI to Woodpecker CI?

Yes. Woodpecker CI was created as a community fork of the Drone CI codebase and maintains near-complete YAML compatibility. Most .drone.yml files work as .woodpecker.yml with minimal or no changes. The plugin ecosystem is largely shared, so your existing build pipelines should transfer smoothly.

Do these platforms support multi-architecture builds?

All three support building for multiple architectures (amd64, arm64, etc.) through their container-based execution. Woodpecker CI and Drone CI can run agents on different CPU architectures simultaneously. Gitea Actions supports this via matrix builds in the workflow YAML.

Can I use these CI/CD platforms without a git forge integration?

Woodpecker CI and Drone CI require a git forge connection (GitHub, Gitea, GitLab, etc.) for triggering builds on push/PR events. Gitea Actions is inherently tied to Gitea. However, all three support manual pipeline triggers via API for ad-hoc builds.

How do secrets management work in self-hosted CI/CD?

Each platform supports secret storage at the repository or organization level. Secrets are injected as environment variables during pipeline execution and are masked in build logs. Woodpecker CI and Drone CI store secrets server-side. Gitea Actions uses Gitea’s built-in secret management, accessible through workflow settings.

Is Gitea Actions fully compatible with GitHub Actions?

Gitea Actions uses the nektos/act runtime, which provides high but not 100% GitHub Actions compatibility. Most common actions (actions/checkout, actions/setup-node, actions/setup-go, etc.) work correctly. Some GitHub-specific features like GitHub Packages or advanced caching may require adjustments.

Advertise here