← All chapters

Chapter 5 Sidequest

Sidequest: Self-Hosted CI with Woodpecker

Run your own CI/CD server on your homelab.

⚠️Advanced Territory

This sidequest requires:

  • A server you control (the one running your Minecraft server works!)
  • Comfort with Docker and Docker Compose
  • About an hour of setup time

If you're just learning CI/CD, start with GitHub Actions in the main chapter. Come back here when you want more control.

GitHub Actions is great, but it runs on GitHub's computers. What if you want CI/CD that runs on your hardware? Maybe for privacy, maybe for cost (free tiers have limits), maybe just because you can?

That's where self-hosted CI comes in. We'll use Woodpecker—it's lightweight, Docker-native, and designed for homelabs.

Why Self-Hosted?

🧐
Max

Why would I run my own CI server when GitHub does it for free?

"A few reasons," I said.

"First: privacy. With GitHub Actions, your code and builds run on Microsoft's servers. That's fine for most things, but some people want everything to stay local."

"Second: limits. GitHub's free tier gives you 2,000 minutes per month. For a small project, plenty. For a homelab with lots of repos, you'll hit it."

"Third: learning. Running your own infrastructure teaches you how these systems actually work, not just how to use them."

Setting Up Woodpecker

Woodpecker has two parts:

  1. Server: The brain that manages workflows
  2. Agent: The worker that runs jobs

For a homelab, you'll run both on the same machine.

docker-compose.woodpecker.yml(yaml)
⚠️You Need GitHub OAuth

Woodpecker needs to connect to GitHub to watch your repos. You'll need to create a GitHub OAuth app:

  1. Go to GitHub → Settings → Developer Settings → OAuth Apps
  2. Create a new app with callback URL: http://your-server:8000/authorize
  3. Copy the Client ID and Client Secret
  4. Put them in a .env file (don't commit this!)
.env(text)
$Start Woodpecker

Open http://your-server:8000 in your browser. Log in with GitHub. You should see your repositories!

Woodpecker Pipelines

Woodpecker pipelines look similar to GitHub Actions, but with some differences. The config goes in .woodpecker.yml in your repo.

.woodpecker.yml(yaml)
🤔
Max

It looks similar but... where's the runs-on part?

"In Woodpecker, each step runs in a Docker container you specify. Instead of 'runs-on: ubuntu-latest', you say 'image: alpine' or 'image: docker'. It's more explicit about what environment you're using."

Key Differences from GitHub Actions

ℹ️Woodpecker vs GitHub Actions
FeatureGitHub ActionsWoodpecker
Config file.github/workflows/*.yml.woodpecker.yml
Environmentruns-on: ubuntu-latestimage: alpine
Pre-built actionsuses: actions/checkout@v4Not as common
CloningNeeds checkout actionAuto-clones by default
CostFree tier with limitsFree (you pay for server)

"The biggest difference is that Woodpecker auto-clones your repo at the start of each pipeline. You don't need a checkout step."

A Complete Example

.woodpecker.yml(yaml)

When to Use Self-Hosted

"So should I use Woodpecker instead of GitHub Actions?" Max asked.

"Not instead—it depends on what you need."

💡When to Self-Host

Use GitHub Actions when:

  • You're just starting out
  • Your project is on GitHub anyway
  • You don't want to manage infrastructure
  • You're under the free tier limits

Use Woodpecker when:

  • You want full control
  • You need unlimited build minutes
  • You want to keep everything on your network
  • You're learning how CI systems actually work
  • You have a homelab and want to use it!

"For your Minecraft server project, GitHub Actions is fine. But if you ever run a homelab with a dozen repos, self-hosted CI starts making sense."

Type a command below or scroll through content...
$
Vol
0/4
Ch
0/1
Cmd
0
Egg
0/7
LVL 1
Newbie
0 XP