fix: build fails with debian:trixie-slim

This commit is contained in:
sebthom 2025-08-14 19:12:55 +02:00
parent f66589a163
commit b4966687a3
3 changed files with 173 additions and 14 deletions

151
README.md
View File

@ -50,7 +50,7 @@ Running from the command line:
-e GITEA_INSTANCE_URL=https://gitea.example.com \
-e GITEA_RUNNER_REGISTRATION_TOKEN=<INSERT_TOKEN_HERE> \
--name gitea_act_runner \
--privileged
--privileged \
vegardit/gitea-act-runner:dind-latest
```
@ -60,7 +60,9 @@ Running from the command line:
-e GITEA_INSTANCE_URL=https://gitea.example.com \
-e GITEA_RUNNER_REGISTRATION_TOKEN=<INSERT_TOKEN_HERE> \
--name gitea_act_runner \
--privileged
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
--security-opt systempaths=unconfined \
vegardit/gitea-act-runner:dind-rootless-latest
```
@ -97,7 +99,7 @@ Example `docker-compose.yml`:
gitea_act_runner:
image: vegardit/gitea-act-runner:dind-latest
#image: ghcr.io/vegarditgitea-act-runner:dind-latest
#image: ghcr.io/vegardit/gitea-act-runner:dind-latest
privileged: true
restart: always
volumes:
@ -110,6 +112,145 @@ Example `docker-compose.yml`:
# or: GITEA_RUNNER_REGISTRATION_TOKEN: '<INSERT_TOKEN_HERE>'
```
- Docker-in-Docker rootless approach
```yaml
# https://docs.docker.com/compose/compose-file/
services:
gitea_act_runner:
image: vegardit/gitea-act-runner:dind-rootless-latest
#image: ghcr.io/vegardit/gitea-act-runner:dind-rootless-latest
restart: always
security_opt:
- seccomp:unconfined
- apparmor:unconfined
- systempaths=unconfined
volumes:
- /my/path/to/data/dir:/data:rw # the config file is located at /data/.runner and needs to survive container restarts
environment:
TZ: "Europe/Berlin"
# config parameters for initial runner registration:
GITEA_INSTANCE_URL: 'https://gitea.example.com' # required
GITEA_RUNNER_REGISTRATION_TOKEN_FILE: 'path/to/file' # one-time registration token, only required on first container start
# or: GITEA_RUNNER_REGISTRATION_TOKEN: '<INSERT_TOKEN_HERE>'
```
### Kubernetes Deployment
Example deployment for Kubernetes:
- Docker-out-of-Docker approach (requires access to host Docker socket)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea-act-runner
spec:
replicas: 1
selector:
matchLabels:
app: gitea-act-runner
template:
metadata:
labels:
app: gitea-act-runner
spec:
containers:
- name: runner
image: vegardit/gitea-act-runner:latest
env:
- name: GITEA_INSTANCE_URL
value: "https://gitea.example.com"
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: gitea-runner-secret
key: registration-token
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
- name: data
mountPath: /data
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
type: Socket
- name: data
persistentVolumeClaim:
claimName: gitea-runner-pvc
---
apiVersion: v1
kind: Secret
metadata:
name: gitea-runner-secret
type: Opaque
stringData:
registration-token: "<INSERT_TOKEN_HERE>"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-runner-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
```
- Docker-in-Docker approach (more secure, doesn't require host Docker access)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea-act-runner-dind
spec:
replicas: 1
selector:
matchLabels:
app: gitea-act-runner-dind
template:
metadata:
labels:
app: gitea-act-runner-dind
spec:
containers:
- name: runner
image: vegardit/gitea-act-runner:dind-latest
securityContext:
privileged: true
env:
- name: GITEA_INSTANCE_URL
value: "https://gitea.example.com"
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: gitea-runner-secret
key: registration-token
volumeMounts:
- name: data
mountPath: /data
- name: docker-storage
mountPath: /var/lib/docker
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-runner-data-pvc
- name: docker-storage
emptyDir: {}
```
**Notes for Kubernetes deployments:**
- For production, prefer the **DinD (rootful)** approach over DooD because it avoids exposing the host Docker socket and provides better isolation from the host.
- **DinD-rootless** is generally **not recommended** in Kubernetes because:
- It often requires permissive settings (`seccompProfile: Unconfined`, AppArmor `unconfined`) that many clusters disallow under their Pod Security Standards.
- It provides limited additional security at the pod boundary compared to rootful DinD, while still needing relaxed sandboxing.
- It has practical limitations (user-mode networking via `slirp4netns`, port publishing quirks, performance trade-offs, storage driver constraints such as `fuse-overlayfs`).
- If you need "rootless" semantics, consider using **native Kubernetes Jobs** (or a Kubernetes-native runner/executor) instead of running a Docker daemon inside the pod.
### Additional environment variables
The following environment variables can be specified to further configure the service.
@ -117,7 +258,7 @@ The following environment variables can be specified to further configure the se
#### Runner registration:
Name|Default Value|Description
----|-------------|-----------
GITEA_INSTANCE_INSECURE|`false`|It `true` don't verify the TLS certificate of the Gitea instance
GITEA_INSTANCE_INSECURE|`false`|If `true` don't verify the TLS certificate of the Gitea instance
GITEA_RUNNER_NAME|`<empty>`|If not specified the container's hostname is used
GITEA_RUNNER_REGISTRATION_FILE|`/data/.runner`|The JSON file that holds the result from the runner registration with the Gitea instance
GITEA_RUNNER_REGISTRATION_TIMEOUT|`30`|In case of failure, registration is retried until this timeout in seconds is reached
@ -138,7 +279,7 @@ The following environment variables are referenced in the `/opt/config.template.
Name|Default Value|Description
----|-------------|-----------
GITEA_RUNNER_LABELS|`<empty>`|Comma-separated list of labels in the format of `label[:schema[:args]]`.<br>If not specified the following labels are used<ol><li>`ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest`<li>`ubuntu-24.04:docker://ghcr.io/catthehacker/ubuntu:act-24.04<li>`ubuntu-22.04:docker://ghcr.io/catthehacker/ubuntu:act-22.04`<li>`ubuntu-20.04:docker://ghcr.io/catthehacker/ubuntu:act-20.04`</ol>
GITEA_RUNNER_LABELS|`<empty>`|Comma-separated list of labels in the format of `label[:schema[:args]]`.<br>If not specified the following labels are used<ol><li>`ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest`<li>`ubuntu-24.04:docker://ghcr.io/catthehacker/ubuntu:act-24.04`<li>`ubuntu-22.04:docker://ghcr.io/catthehacker/ubuntu:act-22.04`<li>`ubuntu-20.04:docker://ghcr.io/catthehacker/ubuntu:act-20.04`</ol>
GITEA_RUNNER_LOG_LEVEL|`info`|The level of logging, can be trace, debug, info, warn, error, fatal
GITEA_RUNNER_ENV_FILE|`/data/.env`|Extra environment variables to run jobs from a file
GITEA_RUNNER_FETCH_TIMEOUT|`5s`|The timeout for fetching the job from the Gitea instance

View File

@ -63,7 +63,7 @@ RUN --mount=type=secret,id=github_token,required=false --mount=type=bind,source=
echo "#################################################"
echo "Installing required packages..."
echo "#################################################"
apt-get install --no-install-recommends -y binutils ca-certificates curl sudo tini
apt-get install --no-install-recommends -y adduser binutils ca-certificates curl sudo tini
if [[ $UPX_COMPRESS == "true" ]]; then
echo "#################################################"
@ -157,22 +157,21 @@ RUN --mount=type=secret,id=github_token,required=false --mount=type=bind,source=
# https://docs.docker.com/engine/security/rootless/
(set -x; apt-get install --no-install-recommends -y \
dbus-user-session \
`# docker-ce-rootless-extras` \
docker-ce-rootless-extras \
kmod \
iproute2 \
slirp4netns \
uidmap)
# workaround for "[rootlesskit:parent] error: failed to start the child: fork/exec /proc/self/exe: operation not permitted"
# see https://github.com/rootless-containers/rootlesskit/issues/425
(set -x; apt-get install --no-install-recommends -y docker-ce-rootless-extras=5:25.0.3-1~debian.12~bookworm --allow-downgrades)
(set -x; rootlesskit --version)
(set -x; runuser -u act -g act -- /usr/bin/dockerd-rootless-setuptool.sh install --skip-iptables)
# workaround "failed to load plugin io.containerd.internal.v1.opt error="mkdir /opt/containerd: permission denied"
mkdir /opt/containerd
chown act:act /opt/containerd
# set up subuid/subgid for act user
echo 'act:100000:65536' | tee -a /etc/subuid
echo 'act:100000:65536' | tee -a /etc/subgid
else
docker_version=$(docker --version | cut -d ' ' -f3 | cut -d ',' -f1)
curl "https://raw.githubusercontent.com/moby/moby/v${docker_version}/hack/dind" -o /usr/local/bin/dind-hack
@ -253,7 +252,7 @@ USER act
VOLUME /data
# only for dind relevant
# Docker data volume - only used for dind mode (not dind-rootless which stores data in $HOME/.docker)
VOLUME /var/lib/docker
ENTRYPOINT ["/usr/bin/tini", "--"]

View File

@ -40,6 +40,25 @@ fi
if [[ -f /usr/bin/dockerd-rootless.sh ]]; then
export DOCKER_MODE=dind-rootless
log INFO "Starting Docker engine (rootless)..."
# Detect whether this container allows RootlessKit to start.
# Rootless BuildKit/Rootless Docker need seccomp & apparmor unconfined
# (or --privileged) and often systempaths=unconfined for /proc masks.
# See: BuildKit rootless docs. (seccomp/appamor/systempaths rationale)
if [[ -r /proc/$$/status ]]; then
seccomp=$(awk '/^Seccomp:/{print $2}' /proc/$$/status 2>/dev/null)
fi
if [[ -r /proc/$$/attr/current ]]; then
apparmor=$(< /proc/$$/attr/current)
fi
# Seccomp: 0 == unconfined; 2 == filtered by default profile
if [[ "${seccomp:-}" != "0" || "${apparmor:-}" != "unconfined" ]]; then
log WARN "Rootless Docker/BuildKit may be blocked by container sandbox (seccomp=${seccomp:-unknown} apparmor=${apparmor:-unknown})."
log WARN "Run with: --security-opt seccomp=unconfined --security-opt apparmor=unconfined"
log WARN "Optionally add: --security-opt systempaths=unconfined (to relax /proc masking)."
log WARN "Compose: security_opt: ['seccomp:unconfined','apparmor:unconfined','systempaths=unconfined']"
fi
export DOCKER_HOST=unix://$HOME/.docker/run/docker.sock
if [[ ! -f "$HOME/.config/docker/daemon.json" ]]; then
# workaround for "Not using native diff for overlay2, this may cause degraded performance for building images: running in a user namespace storage-driver=overlay2"
@ -56,7 +75,7 @@ if [[ -f /usr/bin/dockerd-rootless.sh ]]; then
while ! docker stats --no-stream &>/dev/null; do
log INFO "Waiting for Docker engine to start..."
sleep 2
tail -n 1 /data/.docker/docker.log
tail -n 1 "$HOME/.docker/docker.log"
done
echo "==========================================================="
docker info