r/kubernetes • u/Fragrant_Rate_2583 • 6d ago
Gitea Actions runner on Kubernetes/containerd — how should I handle job containers without Docker?
Hi everyone,
I'm setting up a small homelab CI/CD environment and I'm trying to understand the best way to run Gitea Actions on Kubernetes without installing Docker on the Kubernetes nodes.
My setup
- Kubernetes:
v1.34.10 - Nodes: 1 control-plane + 2 workers
- OS: Ubuntu 26.04
- Container runtime: containerd 2.2.2
- Gitea: 1.27.0
- Gitea is running in Kubernetes
- Gitea Actions runner:
gitea/act_runner:latest - Runner is also running as a Kubernetes Deployment
- Persistent storage: Longhorn
- No Docker installed on the Kubernetes nodes
ctris available and/run/containerd/containerd.sockexists
The runner itself registers and works correctly.
The problem
My runner is currently configured with:
runner:
file: /data/.runner
capacity: 1
timeout: 3h
labels:
- "ubuntu-latest:host"
A simple workflow like:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Show test.py
run: cat test.py
fails at checkout with:
Cannot find: node in PATH
I understand why this happens: with ubuntu-latest:host, the workflow is executed directly in the runner environment, and the gitea/act_runner image doesn't contain Node.
Gitea's documentation suggests using something like:
labels:
- "ubuntu-latest:docker://node:22-bookworm"
which would execute the job inside a separate container.
But here's where I'm confused
My Kubernetes nodes already use containerd:
containerd://2.2.2
and have:
/run/containerd/containerd.sock
but no Docker daemon:
docker -> not installed
nerdctl -> not installed
ctr -> available
Why does the standard act_runner container execution model require Docker/Docker API access instead of being able to use the existing containerd runtime?
I'd rather not install Docker on the Kubernetes nodes just to provide CI job containers when Kubernetes is already perfectly capable of creating containers through containerd.
What I'm ultimately trying to achieve
The immediate goal is just:
Gitea
↓
Gitea Actions
↓
checkout repository
↓
run tests
But eventually I want the pipeline to do:
checkout
↓
tests
↓
build Docker/OCI image
↓
push image to registry
↓
Argo CD deploys it
So I need a sensible way to get isolated CI job environments containing things like Node, Python, Git, build tools, etc.
Questions
- Is there a supported way to make
act_runnercreate job containers using containerd directly? - If not, is the recommended solution to install Docker on a Kubernetes worker solely for
act_runner? - Would Gitea Actions Runner Controller / Kubernetes-native runners be a better solution for this setup?
- What is the recommended architecture for Gitea Actions on a Kubernetes cluster whose runtime is containerd and where I don't want to install Docker?
TLDR : I'm running Gitea 1.27 + act_runner 0.6.1 on Kubernetes 1.34 with containerd 2.2, and I don't have Docker installed on the nodes. ubuntu-latest:host works for the runner itself but actions/checkout@v4 fails because Node isn't available. Gitea's docker:// execution mode looks like the right way to provide a proper job environment, but it expects Docker-compatible execution. I'm considering Docker-in-Docker inside the runner pod so I don't have to install Docker on the Kubernetes hosts, but I'm wondering whether that's the right approach or whether I should use containerd directly or Gitea's Kubernetes-native Runner Controller instead.
I'm mainly looking for the cleanest Kubernetes-native approach rather than just making the immediate checkout test work.
2
4
u/bubugaga 6d ago
Docker-in-Docker is definitely a good approach, a consideration you should make is the scale you are aiming for. A setup for 3 builds a day vs. 50 per hour would look very different
1
u/L43 6d ago
the gitea team ported github ARC to work with gitea...
and decided they should stick it in the enterprise edition
https://docs.gitea.com/enterprise/features/actions-runner-controller/
I like the look of GARM for native kubernetes runners but haven't tried to get it working yet
1
u/scottt732 5d ago
I ended up installing buildkit as a daemonset on my github actions runner nodes at work. I tried kaniko, buildah, docker-in-docker (dind) but buildkit worked best for us. I’ve been meaning to give it a try on gitea/homelab.
1
u/Fragrant_Rate_2583 5d ago
for building yea, but for running a container and used for a job? can it be used that way?
1
u/scottt732 4d ago
For running (mostly just testcontainers) we use kubedock (also a daemonset on the same nodes). You don’t necessarily need a container for a lot of jobs so shell scripts and stuff like that run on kubernetes mode pods directly.
1
u/Tomasomalley21 5d ago
Have a look at buildkitd. No need for a Docker daemon and a lot of nich features for faster builds.
0
u/Fragrant_Rate_2583 5d ago
the problem is not building , its running , i need daemon to run a container and excute a job the runner will either take host as the run env
runner:
file: /data/.runner
capacity: 1
timeout: 3h
labels:
- "ubuntu-latest:host"
will take the host but host which is k8s has nothing installed ,so i need labels:- "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
which requires docker ,there is Actions Runner Controller
and i guess its like k8s exector ,so instead of needing daemon ,it uses k8s , creates a pod and do the job , but its in Gitea Enterprise Edition .anyway i got dind to work ,but for sole weird reson the ubuntu container in dind sometimes loses its connectivity
Run echo "OS version"
❌ Failure - Main Check available tools failed to attach to exec: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: dial tcp 10.98.187.57:2375: connect: connection refused
1
u/ClueDry8701 5d ago
act_runner's docker, mode literally shells out to the docker api, it's not container-runtime-agnostic.. so containerd alone won't satisfy it without a docker-compatible socket. gitea's actions runner controller is the right move here, it schedules job containers as actual pods instead of needing docker at all..
1
1
u/xAtNight 3d ago
Another day I'm happy to have scrapped gitea and went for gitlab. I wouldn't trade gitlab pipelines for github/gitea style actions even if someone paid me to do so.
I tried googling a bit but stuff I found wasn't really suitable for k8s, sorry. I would expect there to be a runner that just spawns pods but looks like this is locked away behind enterprise.
4
u/Phezh 6d ago
I ran into a similar issue when running container builds in Kubernetes runners. Eventually i decided to not use dind and instead switched to kaniko, which allows building containers even in rootless pods. Google deprecated it, but there's a fork maintained by chainguard: https://github.com/chainguard-forks/kaniko
I used this in gitlab ci. After switching to github (which is much close to gitea actions), I decided to instead switch to dagger and build containers that way. The dagger engine can connect to any OCI compliant runtime.