Setting up self-hosted CI/CD on a UK VPS gives your team automated builds, tests and deployments without paying per-minute fees to a SaaS platform or shipping your source code to servers you do not control. For UK developers, DevOps engineers and agencies watching both costs and data residency, running your own pipeline on a modest virtual server is increasingly practical. This guide explains what self-hosting CI/CD really means, why teams choose it, and how three lightweight tools β Gitea Actions, Woodpecker CI and Drone CI β compare, install and secure on a UK VPS.
What Is Self-Hosted CI/CD?
CI/CD stands for continuous integration and continuous delivery (or deployment). In plain terms, it means automatically building, testing and deploying your code every time you push a commit or open a pull request. A CI/CD server watches your Git repository, and when something changes it runs a series of steps you have defined β install dependencies, run tests, build an artefact, and push it to a server.
The “self-hosted” part simply means you run that CI server and its build agents on your own infrastructure β a UK VPS, for example β rather than relying on a hosted service such as GitHub Actions or GitLab.com. Every build spins up a short-lived Docker container on a machine you own, so your build artefacts, environment variables and source code never leave your control. If you already run your own Git server, self-hosting the pipeline that sits on top of it is a natural next step.
Why Self-Host Your CI/CD Pipeline
The most common reason is cost. Hosted CI platforms bill by the build minute, and a busy team with frequent pushes and long test suites can burn through free tiers quickly. A self-hosted CI/CD pipeline on a fixed-price VPS removes per-minute billing entirely: you pay for the server, and you can run as many builds as the hardware allows.
- No per-minute fees β a flat monthly VPS cost instead of metered build minutes.
- UK data and code residency β source, secrets and build artefacts stay on UK-based servers, which matters for compliance and client contracts.
- Control β you choose the exact runtime, tooling versions, caching strategy and network access.
- Private runners β builds run on your own agents, so nothing touches a shared multi-tenant fleet.
- A clean GitHub Actions alternative that pairs with a Git server you also host.
What You Need for Self-Hosted CI/CD
Getting started with self-hosted CI/CD is refreshingly light. You need a UK VPS running a recent Linux distribution, Docker and Docker Compose installed, a Git server (self-hosted Gitea, Forgejo, GitLab CE, or a remote forge), and a domain with HTTPS so your CI web interface is reachable securely. Because each build runs in an ephemeral container, a 2 vCPU / 4 GB VPS is comfortable for small to mid-sized teams; heavy parallel builds simply want more RAM and CPU. If you are already running Docker Compose on a UK VPS, you have almost everything in place.
Gitea Actions vs Woodpecker vs Drone
All three tools share the same core model: pipelines are defined in a YAML file inside your repository, steps run as Docker containers on a runner, and you register that runner against the CI server with a token. Where they differ is heritage, syntax and how tightly they couple to your Git server.
- Gitea Actions is built directly into Gitea and Forgejo. It uses GitHub-Actions-compatible workflow syntax in
.gitea/workflows/*.ymland runs onact_runner. If you already self-host Gitea, it is the least additional software to manage. - Woodpecker CI is a lightweight open-source project with roots in the Drone codebase, now community-governed. Pipelines live in
.woodpecker.yml, steps are Docker-based, and it connects to Gitea, GitHub or GitLab as the “forge”. It is very light and well documented. - Drone CI is mature and container-native, with pipelines in
.drone.ymland a large plugin ecosystem. Its ownership moved under Harness, and while the open-source edition still exists, development focus shifted β which is partly why Woodpecker forked. Weigh that governance question against its plugin maturity.
| Tool | Pipeline file | Runner | Best when | Governance |
|---|---|---|---|---|
| Gitea Actions | .gitea/workflows/*.yml | act_runner | You already run Gitea/Forgejo | Gitea project (OSS) |
| Woodpecker CI | .woodpecker.yml | Woodpecker agent | Light standalone CI, clean YAML | Community-governed (OSS) |
| Drone CI | .drone.yml | Drone runner | You need mature plugins | Harness-owned |
How to Install Gitea Actions on UK VPS
If your Git server is Gitea, enabling Actions is the fastest route. First, switch the feature on in app.ini, then register a runner and start its daemon. The runner is what actually executes your Docker-based steps.
# In Gitea's app.ini
[actions]
ENABLED = true
# On the runner host (as a non-root user):
act_runner register
--instance https://git.example.co.uk
--token <REGISTRATION_TOKEN>
--name uk-vps-runner
--labels ubuntu-latest:docker://node:20-bookworm
act_runner daemon
The registration token comes from your Gitea admin or repository settings. Once the daemon is running, any workflow file under .gitea/workflows/ is picked up automatically. Because the syntax mirrors GitHub Actions, many existing workflow files run with little or no change, which makes Gitea Actions a comfortable GitHub Actions alternative for teams migrating in-house. For deeper background on standing up the Git server itself, the Woodpecker CI documentation is also a useful reference for how forges and CI servers connect, even if you ultimately choose Gitea Actions.
How to Set Up Woodpecker and Drone
Woodpecker and Drone both run as a server plus one or more agents, and both install cleanly with Docker Compose. The server handles the web UI and talks to your forge over OAuth; the agent runs the actual build containers. Below is a trimmed Woodpecker example pointing at a self-hosted Gitea.
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
environment:
- WOODPECKER_HOST=https://ci.example.co.uk
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://git.example.co.uk
- WOODPECKER_GITEA_CLIENT=<OAUTH_CLIENT_ID>
- WOODPECKER_GITEA_SECRET=<OAUTH_SECRET>
- WOODPECKER_AGENT_SECRET=<LONG_RANDOM_STRING>
ports:
- 8000:8000
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=<LONG_RANDOM_STRING>
volumes:
- /var/run/docker.sock:/var/run/docker.sock
You create the OAuth application inside Gitea, paste the client ID and secret into the server environment, and share one WOODPECKER_AGENT_SECRET between server and agent. Drone follows an almost identical pattern β a drone-server container with your forge OAuth details plus a drone-runner-docker container registered with an RPC secret. Self-hosting CI/CD this way keeps the whole toolchain β Git, CI server and runners β on one UK VPS.
Build Your First Pipeline
A CI/CD pipeline is just a YAML file committed to your repository. The example below, in Woodpecker’s format, clones the code, runs tests, builds the project and deploys on the main branch. Every step names a Docker image, so the runner pulls that image and runs your commands inside it.
steps:
test:
image: node:20-bookworm
commands:
- npm ci
- npm test
build:
image: node:20-bookworm
commands:
- npm run build
deploy:
image: appleboy/drone-ssh
settings:
host: deploy.example.co.uk
username: deployer
key:
from_secret: ssh_key
script:
- cd /srv/app && git pull && systemctl restart app
when:
branch: main
Notice that the SSH key is pulled from_secret rather than written into the file. The Gitea Actions equivalent uses the familiar jobs: and steps: structure with runs-on: ubuntu-latest. Once committed, the pipeline runs automatically on your next push. Pipelines like this can just as easily deploy containers, sync a self-hosted n8n instance, or roll out to an orchestrator if you have chosen one.
Secure Your Runners and Secrets
Runners execute arbitrary code from your repositories, so treat them as the most sensitive part of the system. A compromised or careless runner can expose secrets or take over the host. The safeguards are straightforward but non-negotiable.
- Isolate runners β run them on a dedicated user, ideally a separate VPS or an isolated container, never as root on the host.
- Use dedicated runner tokens β one token per runner, revocable independently.
- Store secrets in the CI secret store β reference them with
from_secret; never hard-code credentials in your YAML. - Keep the CI behind HTTPS β terminate TLS at a reverse proxy and restrict admin access.
- Harden the host β follow standard SSH hardening steps and firewall everything that does not need to be public.
Mounting the Docker socket into an agent gives it broad control of the host, so limit who can push pipeline changes and review pull-request builds from untrusted forks carefully.
Choose the Right CI/CD Tool
The decision usually comes down to what you already run and how much plugin ecosystem you need. All three are light enough for a small VPS because builds are ephemeral containers.
- Choose Gitea Actions if you already self-host Gitea or Forgejo β it is the least extra software and reuses GitHub Actions syntax.
- Choose Woodpecker CI if you want a light, standalone CI server with clean YAML and active community governance.
- Choose Drone CI if you rely on its mature plugin ecosystem, while keeping the Harness ownership question in mind.
If containers are central to your stack, it is also worth reading up on Kubernetes vs Docker Swarm, since your CI/CD pipeline will often be the thing that deploys to them.
Conclusion
Self-hosted CI/CD is no longer heavyweight or expensive. With Docker, a Git server and a modest UK VPS, any team can run private, fixed-cost pipelines that keep code and artefacts in the UK. Gitea Actions, Woodpecker and Drone each hit a slightly different sweet spot, but all three prove that owning your build automation is well within reach.
A UK Speed VPS gives you the fixed-price, UK-based foundation to run any of them comfortably.
- Provision a 2 vCPU / 4 GB UK VPS and install Docker and Docker Compose.
- Stand up or connect your Git server, then pick the CI tool that matches it.
- Register a runner with a dedicated token and put the web UI behind HTTPS.
- Commit a small pipeline YAML and watch your first automated build run.
Run your CI/CD on a UK Speed VPS
Get the CPU, RAM and full root access to run Gitea Actions, Woodpecker or Drone on high-performance AMD EPYC hardware, hosted in the UK with no per-minute billing.
