Running Gitea Actions Without Docker on Kubernetes
Use containerd directly with kaniko for building images and avoid DIND complexities.
Use containerd directly with kaniko for building images and avoid DIND complexities.
Diagnosis
Running Gitea Actions on Kubernetes without Docker typically fails due to:
- Missing containerd integration in runners
- Image building reliance on Docker daemon
- Container execution expecting Docker-specific features
Repair Workflow
1. Install Kaniko for Image Building
# Deploy kaniko as a sidecar or standalone tool
kubectl apply -f https://raw.githubusercontent.com/chainguard-forks/kaniko/master/kaniko-sa.yaml
2. Configure Kubernetes Runner to Use Containerd
Update runner config.toml:
[[runners]]
name = "k8s-containerd"
url = "https://gitea.example.com"
token = "your-token"
executor = "kubernetes"
[runners.docker]
# Disable Docker
enabled = false
[runners.kubernetes]
image = "gitea/kaniko:latest"
containerd_socket = "/var/run/containerd/containerd.sock"
3. Build Images with Kaniko
Example Gitea workflow step:
- name: Build container image
uses: docker://build
with:
context: .
push: true
tags: my-registry/my-image:latest
4. Execute Containers Without Docker
Use nerdctl or containerd directly for runtime:
nerdctl run --rm -it my-registry/my-image:latest
Policy Example
Restrict container execution to specific images and enforce read-only root filesystems:
apiVersion: v1
kind: Pod
metadata:
labels:
app: gitea-actions
spec:
securityContext:
runAsNonRoot: true
containers:
- name: build
image: gitea/kaniko:latest
imagePullPolicy: IfNotPresent
securityContext:
readOnlyRootFilesystem: true
Tooling
- kaniko: Image building without Docker daemon (Chainguard fork recommended)
- containerd: Native Kubernetes container runtime
- nerdctl: CLI for testing container execution outside Gitea
Tradeoffs
- kaniko: Slower than Docker due to tarball-based builds, lacks live debugging
- containerd: Requires manual configuration for image pushing/pulling
- No Docker: Breaks workflows relying on Docker-specific features (e.g., BuildKit)
Troubleshooting
Common Failures
-
Containerd socket permission denied
- Fix: Add runner service account to
containerdgroup:usermod -aG containerd gitea-runner
- Fix: Add runner service account to
-
Image pull errors for private registries
- Fix: Configure containerd to use registry credentials via
config.toml:[auths] https://my-registry.com = { username = "user" password = "pass" }
- Fix: Configure containerd to use registry credentials via
-
Kaniko failing with “no build context”
- Fix: Ensure source code is mounted correctly in the runner pod:
kubectl exec -it <pod-name> -- ls /workspace
- Fix: Ensure source code is mounted correctly in the runner pod:
Prevention
- Use init containers to validate containerd connectivity before job execution
- Enforce image signing with Cosign for built artifacts
- Monitor runner node disk usage (kaniko builds can bloat node storage)
Avoid DIND (Docker-in-Docker) entirely—it’s fragile, insecure, and incompatible with modern Kubernetes security defaults. Kaniko + containerd provides a cleaner, more maintainable pipeline.
Source thread: Gitea Actions runner on Kubernetes/containerd — how should I handle job containers without Docker?

Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Pinterest
Email