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

Screwdriver CI vs Agola vs Prow: Self-Hosted CI/CD Platforms 2026

Compare three powerful self-hosted CI/CD platforms: Screwdriver CI (Yahoo), Agola (Sorint.lab), and Prow (Kubernetes SIGs). Deployment guides, feature comparison, and Docker Compose configs for building your own build infrastructure.

OS
Editorial Team

Why Self-Host Your CI/CD Platform?

Public CI/CD services like GitHub Actions, CircleCI, and GitLab.com are convenient, but they come with limitations: per-minute billing, shared runners with unpredictable performance, and vendor lock-in. For teams running hundreds of builds daily, the costs add up quickly.

Self-hosted CI/CD platforms give you full control over your build infrastructure. You choose the hardware, manage the scheduling, and keep your source code and build artifacts on-premises. This is especially critical for organizations with compliance requirements (SOC 2, HIPAA, FedRAMP) that restrict where build artifacts can be processed.

Three mature open-source CI/CD platforms stand out in 2026: Screwdriver CI (developed and maintained by Yahoo), Agola (created by Sorint.lab), and Prow (the Kubernetes SIGs project that builds Kubernetes itself). Each takes a fundamentally different approach to continuous delivery.

Screwdriver CI: The Yahoo Build Platform

Screwdriver began as an internal tool at Yahoo in 2012 to replace Jenkins, which had become unstable at their build scale. It was open-sourced in 2016 and rebuilt from scratch with modern architecture. Screwdriver is a pluggable, executor-agnostic service built on Node.js.

Architecture

Screwdriver follows a microservices architecture with distinct components:

ComponentPurposeDocker Image
APIREST API, build orchestration, webhooksscrewdrivercd/screwdriver
UIWeb dashboard for pipelines and buildsscrewdrivercd/ui
StoreArtifact and log storagescrewdrivercd/store
LauncherBuild job entrypointscrewdrivercd/launcher
ExecutorRuns builds (Docker, Kubernetes, or Nomad)screwdrivercd/executor-docker

Configuration

Screwdriver is configured via a screwdriver.yaml file in your repository root, similar to GitHub Actions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
shared:
  image: node:20

jobs:
  main:
    requires: [~commit]
    steps:
      - install: npm install
      - test: npm test
      - build: npm run build
    environment:
      NODE_ENV: production

Deployment with Docker Compose

A minimal Screwdriver deployment requires the API, UI, and a database:

 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
40
41
42
43
44
45
46
47
48
49
50
51
version: "3.8"

services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_DB: screwdriver
      POSTGRES_USER: sd
      POSTGRES_PASSWORD: sd-password
    volumes:
      - pg-data:/var/lib/postgresql/data

  screwdriver-api:
    image: screwdrivercd/screwdriver:latest
    ports:
      - "8080:8080"
    environment:
      SECRET: "your-secret-here"
      ECOSYSTEM_UI: "http://localhost:4200"
      STORE_URI: "http://localhost:8081"
      EXECUTOR_TYPE: "docker"
      SCM_GITHUB_ENABLED: "true"
      SCM_GITHUB_CLIENT: "your-github-oauth-client-id"
      SCM_GITHUB_SECRET: "your-github-oauth-secret"
      DATABASE_TYPE: "sequelize"
      DATABASE_DIALECT: "postgres"
      DATABASE_HOST: "postgres"
      DATABASE_PORT: 5432
      DATABASE_DATABASE: "screwdriver"
      DATABASE_USERNAME: "sd"
      DATABASE_PASSWORD: "sd-password"
    depends_on:
      - postgres

  screwdriver-ui:
    image: screwdrivercd/ui:latest
    ports:
      - "4200:80"
    environment:
      SDAPI_URI: "http://localhost:8080"

  screwdriver-store:
    image: screwdrivercd/store:latest
    ports:
      - "8081:8081"
    volumes:
      - store-data:/tmp/store

volumes:
  pg-data:
  store-data:

Key considerations: Screwdriver requires OAuth setup with your SCM provider (GitHub, GitLab, or Bitbucket). The SECRET environment variable must be a strong random string. For production, use the Kubernetes executor and the official Helm chart (screwdriver-cd/screwdriver-chart).

Agola: CI/CD Redefined

Agola takes a radically different approach to CI/CD. Created by Sorint.lab, it is designed from the ground up as a distributed, highly available system where every component can scale independently. The core concept is Runs — containerized task workflows that support fan-in, fan-out, and matrix execution patterns.

  • GitHub: agola-io/agola — 1,610 stars, last updated September 2025
  • Language: Go
  • License: Apache 2.0
  • Website: agola.io

Architecture

Agola’s architecture is unique — it can run as a single process for small deployments or scale to a distributed cluster:

ComponentPurpose
Config StoreDistributed configuration management
SchedulerOrchestrates run execution across executors
ExecutorRuns tasks in containers (Docker or Kubernetes)
GatewayWeb UI and API gateway
NotifierHandles notifications and webhooks

Run Definition

Agola uses a .agola/config.yml file in your repository:

 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
runs:
  - name: test
    when:
      branch:
        - main
        - develop
    tasks:
      - name: unit-test
        runtime:
          type: pod
          containers:
            - image: golang:1.22
        steps:
          - type: clone
          - type: run
            command: |
              go mod download
              go test ./...
      - name: build
        depends:
          - unit-test
        runtime:
          type: pod
          containers:
            - image: golang:1.22
        steps:
          - type: clone
          - type: run
            command: go build -o myapp ./cmd/main.go

Deployment with Docker Compose

Agola ships with an official agolademo that includes both Agola and Gitea for a complete self-contained CI/CD environment:

 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
40
41
42
43
44
45
46
47
48
49
50
name: agolademo

services:
  agola:
    image: "sorintlab/agolademo"
    command: serve --components all-base,executor
    configs:
      - source: agola
        target: /config.yml
    networks:
      net1:
        ipv4_address: 172.30.0.2
    ports:
      - "8000:8000"
    volumes:
      - agola-data:/data/agola
      - /var/run/docker.sock:/var/run/docker.sock

  gitea:
    image: gitea/gitea:1.21.6
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
    configs:
      - source: gitea
        target: /data/gitea/conf/app.ini
    networks:
      net1:
        ipv4_address: 172.30.0.3
    volumes:
      - gitea-data:/data

networks:
  net1:
    ipam:
      driver: default
      config:
        - subnet: 172.30.0.0/16
          gateway: 172.30.0.1

volumes:
  agola-data:
  gitea-data:

configs:
  agola:
    file: ./agola/config.yml
  gitea:
    file: ./gitea/app.ini

Key considerations: Agola’s all-base,executor mode combines all control plane components with the executor in a single process — ideal for small teams. For larger deployments, split these into separate services. Agola supports GitHub, GitLab, and Gitea as SCM providers simultaneously in a single installation.

Prow: Kubernetes-Native CI/CD

Prow is the CI/CD system that builds the Kubernetes project itself. Developed by the Kubernetes SIGs, it is a Kubernetes-native system that runs as a set of microservices within a Kubernetes cluster. Prow uses GitHub pull requests as its primary interface — commenting /test on a PR triggers the build.

Architecture

Prow is a collection of Kubernetes-native microservices, each with a specific responsibility:

ComponentPurpose
DeckWeb UI for viewing jobs and status
HorologiumTriggers periodic and cron jobs
PlankCreates and manages ProwJobs (Kubernetes CRDs)
SinkerCleans up completed and orphaned ProwJobs
HookReceives GitHub webhooks and triggers jobs
TideManages the merge queue with automatic retesting
DeckDashboard and job log viewer

Pipeline Definition

Prow uses prow.yaml files in your repository or a centralized config.yaml:

 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
presubmits:
  - name: pull-myproject-test
    always_run: true
    decorate: true
    spec:
      containers:
        - image: golang:1.22
          command:
            - make
          args:
            - test
          resources:
            requests:
              cpu: 500m
              memory: 512Mi

postsubmits:
  - name: post-myproject-deploy
    branches:
      - main
    decorate: true
    spec:
      containers:
        - image: golang:1.22
          command:
            - make
          args:
            - deploy

Deployment on Kubernetes

Prow is designed to run on Kubernetes. A minimal deployment requires applying the Prow manifests:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Install Prow CRDs
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/prow/main/cluster/deck_deployment.yaml

# Deploy core Prow components
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/prow/main/cluster/hook_deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/prow/main/cluster/plank_deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/prow/main/cluster/sinker_deployment.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/prow/main/cluster/horologium_deployment.yaml

# Configure Prow (create prow configmap)
kubectl create configmap config \
  --from-file=config.yaml=./prow-config.yaml \
  --namespace=prow

# Deploy Tide for PR management
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/prow/main/cluster/tide_deployment.yaml

Key considerations: Prow requires a running Kubernetes cluster — it cannot run on plain Docker. It is tightly integrated with GitHub and uses GitHub App or OAuth for authentication. The Tide component provides automatic PR merging when all tests pass, similar to GitHub’s branch protection merge queue.

Feature Comparison

FeatureScrewdriver CIAgolaProw
LanguageNode.jsGoGo
GitHub Stars1,0421,610282
Last UpdatedApril 2026September 2025April 2026
LicenseBSD 3-ClauseApache 2.0Apache 2.0
Minimum InfraDocker ComposeDocker ComposeKubernetes required
Web UIFull-featuredBuilt-inDeck dashboard
SCM SupportGitHub, GitLab, BitbucketGitHub, GitLab, GiteaGitHub (primary)
ExecutorDocker, K8s, NomadDocker, KubernetesKubernetes pods
Pipeline Configscrewdriver.yaml.agola/config.ymlprow.yaml / configmap
PR-based TriggerVia webhooksVia webhooksNative (/test comments)
Auto-mergeNoNoYes (Tide)
Cron JobsYesYesYes (Horologium)
Matrix BuildsVia parallel jobsNative fan-in/fan-outVia ProwJob templates
Artifact StorageBuilt-in StoreVolumesExternal (GCS, S3)
ScalabilityHorizontal (services)Distributed clusterKubernetes-native
Best ForEnterprise teamsSmall to medium teamsKubernetes projects

When to Choose Each Platform

Choose Screwdriver CI if:

  • You need a mature, enterprise-grade platform with Yahoo-scale battle testing
  • Your team prefers Node.js-based tooling and configuration
  • You want flexible executor options (Docker, Kubernetes, Nomad)
  • You need multi-SCM support with a unified dashboard

Choose Agola if:

  • You want a Go-based system that can run as a single binary or scale to a cluster
  • You value the “runs” model with native fan-in/fan-out task workflows
  • You want a quick start with the agolademo (includes Gitea)
  • Your team prefers declarative, Git-tracked configuration

Choose Prow if:

  • Your infrastructure is already on Kubernetes
  • You want GitHub PR-native CI with /test comment triggers
  • You need automatic PR merging with Tide
  • You want to run the same CI system that builds Kubernetes itself

For teams looking at simpler CI/CD alternatives, our Woodpecker CI vs Drone CI vs Gitea Actions guide covers lighter-weight options. If you need Kubernetes-native workflows, see our Tekton vs Argo Workflows vs Jenkins X comparison for alternatives. For portable pipeline engines, Dagger offers a different approach.

FAQ

Can I run all three platforms on a single server?

Screwdriver CI and Agola both support Docker Compose deployments and can run on a single server with 4+ GB RAM. Prow requires a Kubernetes cluster, which adds significant overhead — it is not suitable for single-server deployments. If you have a small team and limited infrastructure, Agola’s single-process mode is the most resource-efficient option.

Which platform is easiest to set up?

Agola’s agolademo is the fastest path to a working CI/CD system — it bundles Agola with Gitea in a single Docker Compose file. Screwdriver requires separate configuration of OAuth credentials, database, and multiple services. Prow has the steepest learning curve as it requires Kubernetes knowledge and a running cluster.

Do these platforms support self-hosted Git servers?

Yes. Screwdriver supports self-hosted GitHub Enterprise and GitLab instances. Agola supports self-hosted Gitea, GitLab, and GitHub Enterprise. Prow primarily targets github.com but can work with GitHub Enterprise Server through the same webhook mechanism.

How do these handle secrets?

Screwdriver has a built-in secrets plugin with per-pipeline secret storage. Agola supports encrypted variables in its configuration. Prow relies on Kubernetes Secrets mounted into test pods — you manage them through Kubernetes RBAC. For teams needing dedicated secret management, see our Vault vs Infisical vs Passbolt guide.

Which platform has the most active development?

Screwdriver CI has the most consistent commit activity (last update April 2026) with active maintenance by Yahoo’s team. Prow is also actively maintained by the Kubernetes SIGs (last update April 2026). Agola’s last commit was in September 2025, but the project is considered stable for production use.

Can I migrate from GitHub Actions to any of these?

Screwdriver’s screwdriver.yaml syntax is closest to GitHub Actions — both use step-based job definitions with environment variables. Agola’s run model is conceptually different with its fan-in/fan-out task graphs. Prow’s configuration is Kubernetes-native and requires the most adaptation from GitHub Actions workflows.

Advertise here
Advertise here