How to Set Up Woodpecker CI on Raspberry Pi for Automated Builds
Woodpecker CI is a lightweight, community-driven continuous integration engine that integrates natively with Gitea and other Git forges. It uses a simple YAML-based pipeline syntax and runs build steps inside Docker containers. This makes it an excellent fit for a Raspberry Pi home lab where you want automated builds without heavy resource usage.
Prerequisites
Before starting, make sure you have the following:
- A Raspberry Pi 3 or newer running Raspberry Pi OS (64-bit recommended).
- Docker and Docker Compose installed. If you need help, see our Docker setup guide.
- A running Gitea instance. If you haven't set one up yet, see our Gitea guide.
- SSH access to your Raspberry Pi.
Step 1: Create an OAuth2 Application in Gitea
Woodpecker authenticates with Gitea using OAuth2. You need to register an application in Gitea first:
- Log in to your Gitea instance as an admin.
- Go to Site Administration > Applications.
- Click Create a new OAuth2 Application.
- Fill in the following:
- Application Name:
Woodpecker CI - Redirect URI:
http://<your-pi-ip>:8000/authorize
- Application Name:
- Click Create Application.
- Copy the Client ID and Client Secret. You will need these in the next step.
Step 2: Create the Project Directory and Docker Compose File
mkdir -p ~/woodpecker && cd ~/woodpecker
Create a docker-compose.yml file with the following content. Replace the placeholder values with your actual Gitea URL, OAuth2 credentials, and a random secret string:
version: "3"
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker-server
restart: always
ports:
- "8000:8000"
volumes:
- ./server-data:/var/lib/woodpecker
environment:
- WOODPECKER_HOST=http://<your-pi-ip>:8000
- WOODPECKER_OPEN=true
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=http://<your-pi-ip>:3000
- WOODPECKER_GITEA_CLIENT=<your-gitea-oauth-client-id>
- WOODPECKER_GITEA_SECRET=<your-gitea-oauth-client-secret>
- WOODPECKER_SECRET=<a-random-secret-string>
- WOODPECKER_LOG_LEVEL=info
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
container_name: woodpecker-agent
restart: always
depends_on:
- woodpecker-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_SECRET=<a-random-secret-string>
- WOODPECKER_LOG_LEVEL=info
- WOODPECKER_MAX_WORKFLOWS=2
Important: WOODPECKER_SECRET must be the same value in both the server and agent services. The agent mounts the Docker socket so it can spin up containers for each pipeline step. WOODPECKER_MAX_WORKFLOWS=2 limits concurrent pipelines, which is sensible for a Pi's resources.
Generate a random secret string with:
openssl rand -hex 32
Step 4: Start the Containers
cd ~/woodpecker
docker compose up -d
Verify both containers are running:
docker compose ps
You should see woodpecker-server and woodpecker-agent both with a status of "Up".
Step 5: Log In to Woodpecker
Open your browser and go to http://<your-pi-ip>:8000. You will be redirected to Gitea for OAuth2 authentication. Log in with your Gitea credentials and authorize the Woodpecker application.
After authorization, you will be redirected back to the Woodpecker dashboard. Your Gitea repositories will be listed and available to activate.
Step 6: Activate a Repository
In the Woodpecker dashboard, find the repository you want to set up CI for and click on it. Click the Settings gear icon, then toggle Enable to activate the webhook. Woodpecker will automatically configure a webhook in Gitea so that pushes and pull requests trigger builds.
Step 7: Create a Pipeline File
In your Gitea repository, create a file called .woodpecker.yml in the root directory. Here is a simple example pipeline:
steps:
- name: greeting
image: alpine:latest
commands:
- echo "Hello from Woodpecker CI!"
- echo "Running on $(uname -m)"
- name: test
image: alpine:latest
commands:
- echo "Running tests..."
- exit 0
When you push this file to your repository, Woodpecker will automatically run the pipeline. For a more practical example, here is a pipeline that builds a Docker image and pushes it to a local registry:
steps:
- name: build
image: plugins/docker
settings:
repo: <your-pi-ip>:5000/my-app
registry: <your-pi-ip>:5000
tag: latest
insecure: true
Step 8: View Build Results
After pushing a commit, go back to the Woodpecker dashboard and click on your repository. You will see the pipeline running in real time. Green indicates a successful build, red indicates a failure. Click on any step to view its log output.
Updating Woodpecker
To update Woodpecker to the latest version:
cd ~/woodpecker
docker compose pull
docker compose up -d
Troubleshooting
- OAuth2 redirect error: Make sure the redirect URI in your Gitea OAuth2 application exactly matches
http://<your-pi-ip>:8000/authorize. The trailing path must be/authorize. - Agent not connecting: Verify that
WOODPECKER_SECRETis identical in both the server and agent environment variables. Check agent logs withdocker compose logs woodpecker-agent. - Pipelines not triggering: Confirm the webhook was created in Gitea by going to your repository's Settings > Webhooks. The Woodpecker webhook should be listed and active.
- Build steps fail to pull images: The agent needs internet access to pull Docker images.
- Out of memory during builds: Reduce
WOODPECKER_MAX_WORKFLOWSto1or use lighter base images. - Permission denied on Docker socket: Ensure the agent container has the Docker socket mounted.
Conclusion
Woodpecker CI gives you a fully self-hosted CI/CD system that pairs naturally with Gitea. Running both on a Raspberry Pi means you have an energy-efficient, always-on development pipeline under your complete control.