2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00
2026-08-27 10:46:36 +02:00

Build Docker images on k3s with Gitea Actions → push to Harbor

This repository contains a complete, reproducible configuration that lets you:

  1. Run a Gitea Actions runner (act_runner) on a k3s node.
  2. Build Docker/OCI container images inside the CI pipeline using a Docker-in-Docker (DinD) sidecar (so plain docker build / docker push work).
  3. Push the built images to a Harbor registry.

The whole pipeline is driven by Gitea Actions (Gitea's built-in, GitHub-Actions-compatible CI/CD), so no external CI system (Jenkins/Drone/etc.) is required.

┌──────────────┐    registers    ┌─────────────────────────────────────┐
│    Gitea     │◄────────────────│  act_runner  (Deployment on k3s)     │
│  (Actions)   │  job dispatch   │  ┌───────────────┐  ┌──────────────┐ │
│              │────────────────►│  │  act_runner   │  │  dockerd     │ │
└──────────────┘                 │  │  container    │─►│  (DinD side- │ │
        ▲                        │  └───────────────┘  │   car,       │ │
        │ git push               │        docker build │   privileged)│ │
   ┌────┴─────┐                  │        docker push  └──────────────┘ │
   │ developer│                  └───────────────────────────┬─────────┘
   └──────────┘                                              │ push image
                                                             ▼
                                                    ┌──────────────────┐
                                                    │   Harbor registry │
                                                    └──────────────────┘

Repository layout

File Purpose
k3s/00-namespace.yaml Dedicated gitea-runner namespace.
k3s/10-runner-secret.yaml.example Gitea registration token secret (copy & fill in).
k3s/20-runner-config.yaml act_runner config (config.yaml) as a ConfigMap.
k3s/30-runner-deployment.yaml The act_runner + DinD Deployment.
k3s/40-harbor-secret.yaml.example Optional cluster-side Harbor pull secret.
workflows/build-and-push.yaml Example Gitea Actions workflow (put in your app repo).
examples/Dockerfile Minimal sample image to build.
scripts/deploy.sh Helper to apply all manifests.
.gitea/workflows/build-and-push.yaml Same workflow, pre-placed so this repo self-builds.

Prerequisites

  • A running k3s cluster and kubectl access to it (~/.kube/config or /etc/rancher/k3s/k3s.yaml).
  • A reachable Gitea instance (>= 1.20) with Actions enabled ([actions] ENABLED = true in Gitea's app.ini).
  • A running Harbor registry and a robot account (recommended) with push permission on the target project.

Step 1 — Enable Gitea Actions (on the Gitea server)

In Gitea's app.ini:

[actions]
ENABLED = true

Restart Gitea. Then get a runner registration token:

  • Instance level: Site Administration → Actions → Runners → Create new Runner → copy the token.
  • Org/Repo level: Settings → Actions → Runners → Create new Runner.

Step 2 — Create the runner registration secret

cp k3s/10-runner-secret.yaml.example k3s/10-runner-secret.yaml
# edit k3s/10-runner-secret.yaml and paste your GITEA_INSTANCE_URL + token
kubectl apply -f k3s/10-runner-secret.yaml

Step 3 — Deploy the runner on k3s

./scripts/deploy.sh
# or manually:
kubectl apply -f k3s/00-namespace.yaml
kubectl apply -f k3s/20-runner-config.yaml
kubectl apply -f k3s/30-runner-deployment.yaml

Verify the runner appears online in Gitea (Actions → Runners) and that both containers are ready:

kubectl -n gitea-runner rollout status deploy/act-runner
kubectl -n gitea-runner get pods

Step 4 — Configure Harbor credentials for the pipeline

In your Gitea repository (or org) → Settings → Actions → Secrets, add:

Secret name Value
HARBOR_REGISTRY e.g. harbor.example.com
HARBOR_USERNAME Harbor user / robot account, e.g. robot$ci
HARBOR_PASSWORD the robot account token / password

Using a Harbor robot account (Project → Robot Accounts) instead of a personal login is strongly recommended.

Step 5 — Add the workflow to your app repo

Copy workflows/build-and-push.yaml into your application repository at .gitea/workflows/build-and-push.yaml, commit, and push. Gitea will dispatch the job to your k3s runner, which builds the image via DinD and pushes it to Harbor.


How image building works (no Docker on k3s needed)

k3s uses containerd, not Docker, and has no image-build capability. This setup therefore runs a dockerd DinD sidecar next to act_runner. The runner container talks to it over tcp://localhost:2376 (TLS), so inside jobs the standard docker CLI works transparently — docker build, docker login, docker push all behave like on a normal Docker host.

If you prefer a rootless / non-privileged approach (Kaniko or Buildah), see the "Alternative: rootless builds" section at the bottom of workflows/build-and-push.yaml.

Security notes

  • The DinD sidecar requires privileged: true. Keep this runner in its own namespace and, ideally, on a dedicated node (see the nodeSelector/tolerations comments in the Deployment).
  • Prefer Harbor robot accounts with the least privilege (push to one project only).
  • Store all credentials as Kubernetes/Gitea secrets — never commit the filled-in *.yaml (non-.example) files. See .gitignore.
S
Description
No description provided
Readme
33 KiB
Languages
Shell 100%