namesny-com/content/blog/gitea_actions_k3s_docker.md

88 lines
5.7 KiB
Markdown

---
title: "Building a Docker Container with Gitea Actions on K3s"
date: "2023-12-28"
tags:
- gitea
- k3s
- cicd
---
Building a Docker image and pushing it to the registry with GitHub Actions is incredibily easy. Since Gitea Actions are designed to be compatible with GitHub Actions, this should be easy, right?
<!--more-->
## Gitea Actions
Gitea Actions is a CI/CD solution tightly coupled with Gitea. They have been available since Gitea 1.19 and are designed to be mostly compatible with GitHub Actions. They are based on the [act](https://github.com/nektos/act), which allows you to run GitHub workflows locally. Gitea has soft forked it to create [act_runner](https://gitea.com/gitea/act_runner).
To use Gitea Actions on you instance, you need to first allow them in `app.ini`. Then create a token and deploy the runner. Once the runner is deployed and registered, you will also need to enable Actions for each repository separately. The Actions runner is a self-contained system - a docker container that, for each job, launches a new container inside which the action steps are run. For a full guide on setting up Actions, check the official [Gitea docs](https://docs.gitea.com/usage/actions/quickstart).
## Building and Pushing Docker Image with GitHub Actions
With GitHub Actions, you can make use of thousands of actions available in [GitHub Marketplace](https://github.com/marketplace?type=actions). If you want to build a Docker image on GitHub, you can just use the official Docker [build-and-push](https://github.com/marketplace/actions/build-and-push-docker-images) action. Just copy one of the examples and you are good to go.
## Building with Gitea
In order to enable Gitea Actions, you nedd to first deploy the Actions runner. I followed the Kubernetes example from [gitea/act_runner](https://gitea.com/gitea/act_runner/src/commit/f17cad1bbe0d4a84308a37fb4a5e64211ada7e8a/examples/kubernetes/rootless-docker.yaml) repository. The deployment is simple. The runner will register itself with your Gitea instance, and after you enable Actions globally and for each repository, you'll be able to try Actions.
The first thing I tried was the same workflow that I used on Github. That didn't work. The first step to fail was docker login action. It complained that it couldn't find the `docker` command. It turns out that the default container image in which the Actions runner runs the commands did not contain docker. I tried manually installing it, but a simpler solution was to just specify a different container by [catthehacker](https://github.com/catthehacker/docker_images), which already has docker preinstalled. After switch to the new container, the logging in worked fine.
The next problem was with setting up the docker buildx action. It couldn't connect to Docker daemon at `unix:///var/run/docker.sock`. After much debugging, trying different things, and searching the internet, I found out that because the docker-in-docker runner container is rootless, the Docker socket is at `unix:///var/run/user/1000/docker.sock` instead. I just needed to change the `DOCKER_HOST` environment variables. I also removed `DOCKER_TLS_VERIFY` and `DOCKER_CERT_PATH` environment variables since they weren't necessary.
Okay, so now, everything should work fine, right? Not so fast. Apparently the Docker buildx action makea some assumtions about the system, which work well in a well-defined environment of GitHub Actions but don't necessarily hold true for self-hosted K3s deployments. It complained that it couldn't mount `sysfs` to `rootfs` at `/sys` due to operation not permitted. The solution was to run docker commands directly instead of using `buildx` action.
The last hurdle was to pass the login secrets to the action. Gitea does not yet support an equivalent to `GITHUB_TOKEN`, so instead, I needed to manually create a token and add it to action secrets as `REGISTRY_TOKEN`.
This is a very condensed summary of many hours spent debugging, searching, and trying to make Gitea Actions build a Docker image on K3s. I've skiped a few different attempts that lead to nowhere, such as using RedHat's Buildah instead of Docker. In the end the actual solution was much simpler than any of my attempts.
## TL;DR
To build a Docker image using Gitea Actions on K3s deploy the dind-rootless Actions runner with these environment variables:
{{< highlight yaml >}}
env:
- name: DOCKER_HOST
value: unix:///var/run/user/1000/docker.sock
- name: GITEA_INSTANCE_URL
value: http://gitea-http.gitea.svc.cluster.local:3000
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: runner-secret
key: token
{{< / highlight >}}
Create `release.yaml` file in `.gitea/workflows` folder. For building and pushing the image, use `docker` commands directly. For example:
{{< highlight yaml >}}
name: Build docker container
on:
push:
branches:
- main
jobs:
build:
name: Build image
runs-on: ubuntu-latest
container: ghcr.io/catthehacker/ubuntu:act-latest
env:
IMAGE_NAME: example-image
REGISTRY: example.com
REPO_OWNER: test
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: example.com
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Build and push
run: |
TODAY=$(date +'%Y-%m-%d')
docker build -t ${REGISTRY}/${REPO_OWNER}/${IMAGE_NAME}:${TODAY} -t ${REGISTRY}/${REPO_OWNER}/${IMAGE_NAME}:latest .
docker push ${REGISTRY}/${REPO_OWNER}/${IMAGE_NAME}:${TODAY}
docker push ${REGISTRY}/${REPO_OWNER}/${IMAGE_NAME}:latest
{{< / highlight >}}