fix: build fails with debian:trixie-slim
This commit is contained in:
parent
f66589a163
commit
b4966687a3
151
README.md
151
README.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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", "--"]
|
||||
|
|
|
|||
21
image/run.sh
21
image/run.sh
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue