Self-Hosted vs Cloud CI/CD - Choosing Where Your Pipeline Lives
Status: Active
Last Updated: 2026-08-14
Category: CI/CD - Phase 1: CI/CD Fundamentals
Prerequisites: cicd-concepts, manual-vs-automated
Time: 1 hour
Tags: self-hosted, github-actions, gitlab-ci, woodpecker-ci, privacy, cost-comparison
Summary
Before installing Forgejo and Woodpecker, you should understand what you're choosing between. This article compares the dominant options โ GitHub Actions, GitLab CI/CD, and a self-hosted Forgejo + Woodpecker stack โ across cost, privacy, control, maintenance burden, and lock-in, so you can make the decision deliberately rather than by default.
๐ฏ What You'll Learn
By the end of this article, you'll be able to:
- โ Compare GitHub Actions vs Woodpecker and GitLab CI/CD vs self-hosted stacks feature-by-feature
- โ Model the true costs of each option including hidden ones
- โ Evaluate privacy and control implications for your code
- โ Decide which option fits your team size and threat model
- โ Understand what you give up in either direction
The Contenders
Option A: Cloud SaaS Option B: Single-vendor Option C: Self-hosted
GitHub + GitHub Actions GitLab (CE or SaaS) Forgejo + Woodpecker CI
โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโ
Zero ops, fastest start All-in-one, heavier Full control, full ownership
Metered pricing Tiered pricing Hardware + electricity only
Code on MS servers Code on GitLab or yours Code always on your metal
Proprietary platform Open core 100% open source (MIT/GPL)
This course builds Option C, but you should know exactly why.
GitHub Actions vs Woodpecker
| Dimension | GitHub Actions | Woodpecker CI |
|---|---|---|
| Hosting | Microsoft/Azure cloud | Your hardware |
| Pricing | Free tier (2,000 min/mo public; limited private), then per-minute | Free software; your compute |
| Config format | YAML (.github/workflows/) |
YAML (.woodpecker.yml) |
| Runner model | Ephemeral Azure VMs | Ephemeral containers on your agents |
| Marketplace | Huge ecosystem of actions | Smaller plugin registry (Drone-compatible plugins) |
| Matrix builds | First-class (strategy.matrix) |
First-class (matrix: key) |
| Secrets | Org/repo/environment-scoped | Org/repo-scoped, from_secret syntax |
| Self-hosted runners | Possible but awkward licensing-wise | Native design โ agents are the architecture |
| Pipeline debugging | Re-run, live logs | Live logs, step-level re-run, local CLI testing |
| Vendor coupling | Deep (actions ecosystem assumes GitHub) | None โ works with Gitea, Forgejo, GitHub, GitLab |
Key insight: Woodpecker's whole architecture is "self-hosted first." Agents are just Docker hosts that poll the server for work. There's no awkward bolt-on runner story because the runner is the product.
Syntax Taste Test
The same pipeline in both systems:
# .github/workflows/ci.yaml
name: ci
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci && npm test
# .woodpecker.yml
when:
- event: push
steps:
- name: test
image: node:22
commands:
- npm ci
- npm test
Woodpecker is flatter: every step declares its container image explicitly, which makes pipelines more portable and predictable โ there is no hidden VM with pre-installed magic.
GitLab CI/CD vs Self-Hosted
GitLab deserves separate treatment because it bundles hosting + registry + CI + issue tracking:
| Dimension | GitLab (self-managed CE) | Forgejo + Woodpecker |
|---|---|---|
| Footprint | Heavy โ recommended 8GB+ RAM, omnibus bundle | Light โ ~3GB RAM total for full stack |
| Architecture | Monolithic Ruby app + services | Small Go binaries, compose-friendly |
| Feature breadth | Massive (built-in registry, pages, security scanning) | Focused; integrate Harbor/Traefik yourself |
| Upgrade path | Versioned upgrade rails required | Simple image bumps |
| License history cautionary tale | MIT core โ proprietary tiers; features move up tiers | Forgejo is a community-governed Gitea fork under Copyleft/AGPL-style governance |
The GitLab lesson many homelabbers learned: running CE means operating a resource-hungry monolith to use maybe 20% of its features, while its open-core boundary keeps shifting. The Forgejo + Woodpecker pair does one thing per component, cheaply.
Privacy and Control
Ask three questions about any code that leaves your machine:
- Who can read it? On GitHub/GitLab SaaS: the vendor (and, per their terms, processing infrastructure). Private repos are contractually private, not cryptographically private.
- Who runs your build? Actions executes your code on Azure VMs. If your project has secrets, they transit and live in a third party's secret store.
- What happens on policy change? Pricing changes, free-tier cuts, ToS updates, sanctions-based account closures โ all have precedent. You accept these as externalities.
Self-hosting answers all three identically: you, you, nothing you don't choose.
For some projects this is mandatory rather than preferable:
- Client work under NDA
- Pre-launch IP you don't want indexed or processed off-site
- Regulated data that can't touch foreign clouds
- Sanctions-resilience / jurisdiction concerns
Cost Comparison
Cloud (GitHub Team-tier example, small private org)
Base: $4/user/month ร 5 users = $20/mo
Actions minutes: beyond included quota, ~$0.008/min
Typical small-team usage (~1,500 extra min/mo) = $12/mo
Artifacts/storage overages = $5โ10/mo
Total โ $37โ42/month, scaling with usage
Self-hosted (Forgejo + Woodpecker)
Existing homelab server slice (or $10/mo VPS):
Forgejo: 1GB RAM slice โโ
Woodpecker svr: 512MB โโ ~6GB total
Agent: 2GB โโ
Electricity/amortization: โ $5โ15/month flat
Your time: see below
Total โ flat cost, unlimited minutes
The honest ledger includes your time: expect ~4โ8 hours initial setup and ~1 hour/month maintenance (updates, backups). At hobby scale that trade favors self-hosting if you value learning + privacy; at pure-dollar scale with zero spare time, SaaS wins until minute counts get large.
Break-even intuition: heavy CI users (long test suites, many commits/day) burn through cloud minutes fast โ self-hosting pays back quickly. Light users with no privacy constraints may never recoup setup time.
What You Give Up
Going self-hosted, you lose
- โ Zero-ops reliability โ your CI goes down when your server does
- โ The massive marketplace; you'll write more shell and fewer
uses:lines - โ Global runner elasticity โ a 40-minute parallel test matrix needs you to provision agents
- โ Built-in Pages/registry/security scanning โ you assemble Harbor, Traefik, etc.
- โ Someone else's compliance certifications (SOC2 etc.)
Going cloud, you lose
- โ Data residency guarantees you control
- โ Fixed, predictable cost at scale
- โ Freedom from account-closure/policy risk
- โ The deep operational skills this course teaches
Decision Framework
Is the code sensitive (NDA, regulated, pre-release IP)?
โโ Yes โ Self-hosted. Non-negotiable.
โโ No โ
Do you already run servers/homelab infrastructure?
โโ Yes โ Self-hosted (Forgejo + Woodpecker). Marginal cost tiny,
learning compounds with the rest of your stack.
โโ No, and you don't want to learn ops โ
GitHub Actions. Spend your time on the product.
Hybrid note: Woodpecker speaks to github.com too โ you can adopt
the CI tool before migrating the forge, or run both indefinitely.
๐ ๏ธ Troubleshooting & Common Issues
Decision-stage mistakes worth avoiding:
| Mistake | Consequence | Better move |
|---|---|---|
| Choosing SaaS "temporarily" for private code, forever | Slow meter creep, migration debt later | Set a review date for the decision |
| Choosing self-hosting without backup plan | Disk dies โ all history gone | Automate forgejo dump + repo mirrors from day one |
| Running CI agent on the same host as prod workloads | A runaway build starves production | Isolate agents (see woodpecker-installation.md) |
| Ignoring egress/ingress requirements | Webhooks can't reach your CI behind NAT | Plan reverse proxy + DNS before installing (see forgejo-installation.md) |
๐ Related
- Previous: manual-vs-automated
- Next: forgejo-introduction โ meeting your new Git forge
- Secrets handling either way: secrets-management
- Costs of the components: README resource table
Change Log
- 2026-08-14 โ Initial version written as part of the KB course build-out (cicd directory).
Next Steps / Ops Actions
- Decide Option C (self-hosted) deliberately: set a calendar review date for 90 days in case costs or maintenance grow unexpectedly.
- Automate
forgejo dump+ repo mirrors from day one per the decision table's backup column. - Isolate CI agents from production hosts (see woodpecker-installation) before running any build that could starve workloads.
- Plan reverse-proxy + DNS before installing Forgejo; retrofitting HTTPS and routing breaks clone URLs.