diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7475e96..8beaa8e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,13 +28,20 @@ defaults: env: DOCKER_IMAGE_REPO: vegardit/gitea-act-runner - DOCKER_IMAGE_TAG: latest TRIVY_CACHE_DIR: ~/.trivy/cache jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + include: + - DOCKER_FILE: Dockerfile + DOCKER_IMAGE_TAG: latest + - DOCKER_FILE: DinD.Dockerfile + DOCKER_IMAGE_TAG: dind-latest + fail-fast: true steps: - name: Show environment variables run: env | sort @@ -63,6 +70,8 @@ jobs: DOCKER_REGISTRY: docker.io DOCKER_REGISTRY_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} + DOCKER_IMAGE_TAG: ${{ matrix.DOCKER_IMAGE_TAG }} + DOCKER_FILE: ${{ matrix.DOCKER_FILE }} TRIVY_GITHUB_TOKEN: ${{ github.token }} run: | set -eu @@ -74,13 +83,15 @@ jobs: - name: Publish Docker image to GH registry if: ${{ github.ref_name == 'main' && github.event_name != 'pull_request' && !env.ACT }} # https://github.com/nektos/act#skipping-steps + env: + DOCKER_IMAGE_TAG: ${{ matrix.DOCKER_IMAGE_TAG }} run: | set -eux echo "${{ github.token }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin - docker image tag $DOCKER_IMAGE_REPO ghcr.io/$DOCKER_IMAGE_REPO - docker push ghcr.io/$DOCKER_IMAGE_REPO + docker image tag $DOCKER_IMAGE_REPO:$DOCKER_IMAGE_TAG ghcr.io/$DOCKER_IMAGE_REPO:$DOCKER_IMAGE_TAG + docker push ghcr.io/$DOCKER_IMAGE_REPO:$DOCKER_IMAGE_TAG - name: Delete untagged images uses: actions/github-script@v6 diff --git a/README.md b/README.md index 485060c..af2a0a4 100644 --- a/README.md +++ b/README.md @@ -24,41 +24,76 @@ ## Usage +The docker image comes in two flavors: +- `vegardit/gitea-act-runner:latest`: only contains the Gitea act_runner and executes workflows in containers of the docker engine running act_runner itself (DooD / Docker-out-of-Docker approach) +- `vegardit/gitea-act-runner:dind-latest`: executes workflows using an embedded docker engine (DinD / Docker-in-Docker approach) providing better process isolation + ### Docker Run Running from the command line: -```sh - docker run \ - -e GITEA_INSTANCE_URL=https://gitea.example.com \ - -e GITEA_RUNNER_REGISTRATION_TOKEN= \ - -v /var/run/docker.sock:/var/run/docker.sock:rw \ - --name gitea_act_runner \ - vegardit/gitea-act-runner:latest -``` +- Docker-out-of-Docker approach + ```sh + docker run \ + -e GITEA_INSTANCE_URL=https://gitea.example.com \ + -e GITEA_RUNNER_REGISTRATION_TOKEN= \ + -v /var/run/docker.sock:/var/run/docker.sock:rw \ + --name gitea_act_runner \ + vegardit/gitea-act-runner:latest + ``` + +- Docker-in-Docker approach + ```sh + docker run \ + -e GITEA_INSTANCE_URL=https://gitea.example.com \ + -e GITEA_RUNNER_REGISTRATION_TOKEN= \ + --privileged + --name gitea_act_runner \ + vegardit/gitea-act-runner:dind-latest + ``` ### Docker Compose Example `docker-compose.yml`: -```yaml -version: '3.8' # https://docs.docker.com/compose/compose-file/compose-versioning/ +- Docker-out-of-Docker approach + ```yaml + version: '3.8' # https://docs.docker.com/compose/compose-file/compose-versioning/ -services: + services: - gitea_act_runner: - image: vegardit/gitea-act-runner:latest - #image: ghcr.io/vegardit/gitea-act-runner:latest - volumes: - - /var/run/docker.sock:/var/run/docker.sock:rw - - /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: '' -``` + gitea_act_runner: + image: vegardit/gitea-act-runner:latest + #image: ghcr.io/vegardit/gitea-act-runner:latest + volumes: + - /var/run/docker.sock:/var/run/docker.sock:rw + - /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: '' + ``` + +- Docker-in-Docker approach + ```yaml + version: '3.8' # https://docs.docker.com/compose/compose-file/compose-versioning/ + + services: + + gitea_act_runner: + image: vegardit/gitea-act-runner:dind-latest + privileged: true + 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: '' + ``` ### Additional environment variables diff --git a/build-image.sh b/build-image.sh index 3ab013e..d6b36de 100644 --- a/build-image.sh +++ b/build-image.sh @@ -28,7 +28,7 @@ if [[ $OSTYPE == "cygwin" || $OSTYPE == "msys" ]]; then fi DOCKER_BUILDKIT=1 docker build "$project_root" \ - --file "image/Dockerfile" \ + --file "image/$DOCKER_FILE" \ --progress=plain \ --pull \ --build-arg INSTALL_SUPPORT_TOOLS=${INSTALL_SUPPORT_TOOLS:-0} \ diff --git a/image/DinD.Dockerfile b/image/DinD.Dockerfile new file mode 100644 index 0000000..c9ed0bb --- /dev/null +++ b/image/DinD.Dockerfile @@ -0,0 +1,201 @@ +#syntax=docker/dockerfile:1.4 +# see https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md +# see https://docs.docker.com/engine/reference/builder/#syntax +# +# SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com) +# SPDX-FileContributor: Sebastian Thomschke +# SPDX-License-Identifier: Apache-2.0 +# SPDX-ArtifactOfProjectHomePage: https://github.com/vegardit/docker-gitea-act-runner +# +# https://hub.docker.com/_/debian?tab=tags&name=stable-slim + +FROM debian:stable-slim as runtime-base-image + +LABEL maintainer="Vegard IT GmbH (vegardit.com)" + +USER root + +SHELL ["/bin/bash", "-c"] + +ARG DEBIAN_FRONTEND=noninteractive +ARG LC_ALL=C + +ARG INSTALL_SUPPORT_TOOLS=0 + +ARG ACT_RUNNER_DOWNLOAD_URL +ARG UPX_COMPRESS=true + +ARG BASE_LAYER_CACHE_KEY + +RUN --mount=type=bind,source=.shared,target=/mnt/shared <> /etc/sudoers + + echo "#################################################" + echo "Installing docker engine..." + echo "#################################################" + # https://docs.docker.com/engine/install/debian/#install-using-the-repository + apt-get install --no-install-recommends -y gnupg + install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg + chmod a+r /etc/apt/keyrings/docker.gpg + echo \ + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ + "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" > /etc/apt/sources.list.d/docker.list + apt-get update + apt-get install --no-install-recommends -y docker-ce docker-ce-cli containerd.io fuse-overlayfs + + minimize /usr/bin/containerd* /usr/bin/ctr /usr/bin/docker* /usr/bin/runc + + docker --version + runc --version + + # https://github.com/docker/for-linux/issues/1437#issuecomment-1293818806 + update-alternatives --set iptables /usr/sbin/iptables-legacy + update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy + + # set up subuid/subgid so that "--userns-remap=default" works out-of-the-box + sudo addgroup --system dockremap + sudo adduser --system --ingroup dockremap dockremap + echo 'dockremap:165536:65536' | sudo tee -a /etc/subuid + echo 'dockremap:165536:65536' | sudo tee -a /etc/subgid + + usermod -aG docker act + + apt-get remove -y gnupg + + echo "#################################################" + echo "Cleanup..." + echo "#################################################" + apt-get remove -y binutils curl + rm -rf /opt/upx + /mnt/shared/cmd/debian-cleanup.sh + +EOF + +ARG BUILD_DATE +ARG GIT_BRANCH +ARG GIT_COMMIT_HASH +ARG GIT_COMMIT_DATE +ARG GIT_REPO_URL + +LABEL \ + org.label-schema.schema-version="1.0" \ + org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.vcs-ref=$GIT_COMMIT_HASH \ + org.label-schema.vcs-url=$GIT_REPO_URL + +# Default configuration: can be overridden at the docker command line +ENV \ + INIT_SH_FILE='' \ + # + GITEA_RUNNER_CONFIG_TEMPLATE_FILE='/opt/config.template.yaml' \ + # + GITEA_RUNNER_NAME='' \ + GITEA_RUNNER_LABELS='' \ + GITEA_RUNNER_LABELS_DEFAULT='\ +ubuntu-latest:docker://catthehacker/ubuntu:runner-22.04,\ +ubuntu-22.04:docker://catthehacker/ubuntu:runner-22.04,\ +ubuntu-20.04:docker://catthehacker/ubuntu:runner-20.04' \ + GITEA_RUNNER_UID=1000 \ + GITEA_RUNNER_GID=1000 \ + # + GITEA_RUNNER_REGISTRATION_FILE='/data/.runner' \ + GITEA_RUNNER_REGISTRATION_TIMEOUT=30\ + GITEA_RUNNER_REGISTRATION_RETRY_INTERVAL=5s \ + # + GITEA_RUNNER_LOG_LEVEL='info' \ + GITEA_RUNNER_MAX_PARALLEL_JOBS=1 \ + GITEA_RUNNER_JOB_TIMEOUT='3h' \ + GITEA_RUNNER_ENV_FILE='/data/.env' \ + GITEA_RUNNER_FETCH_TIMEOUT='5s' \ + GITEA_RUNNER_FETCH_INTERVAL='2s' \ + # + GITEA_INSTANCE_INSECURE='false' \ + # + GITEA_RUNNER_JOB_CONTAINER_NETWORK='bridge' \ + GITEA_RUNNER_JOB_CONTAINER_OPTIONS='' \ + GITEA_RUNNER_JOB_CONTAINER_PRIVILEGED='false' \ + GITEA_RUNNER_ACTION_CACHE_DIR='/data/cache/actions' \ + # + ACT_CACHE_SERVER_ENABLED='true' \ + ACT_CACHE_SERVER_DIR='/data/cache/server' \ + ACT_CACHE_SERVER_HOST='' \ + ACT_CACHE_SERVER_PORT=0 + +RUN </opt/build_info + cat /opt/build_info + +EOF + +COPY image/*.sh /opt/ +COPY image/config.template.yaml /opt/ +COPY .shared/lib/bash-init.sh /opt/bash-init.sh + +USER act + +VOLUME /data +VOLUME /var/lib/docker + +ENTRYPOINT ["/usr/bin/tini", "--"] + +CMD ["/bin/bash", "/opt/run.sh"] diff --git a/image/Dockerfile b/image/Dockerfile index 40d4840..7f2a147 100644 --- a/image/Dockerfile +++ b/image/Dockerfile @@ -9,9 +9,6 @@ # # https://hub.docker.com/_/debian?tab=tags&name=stable-slim -###################### -# runtime image base -###################### FROM debian:stable-slim as runtime-base-image LABEL maintainer="Vegard IT GmbH (vegardit.com)" @@ -20,20 +17,59 @@ USER root SHELL ["/bin/bash", "-c"] -ARG BASE_LAYER_CACHE_KEY ARG DEBIAN_FRONTEND=noninteractive ARG LC_ALL=C +ARG INSTALL_SUPPORT_TOOLS=0 + +ARG ACT_RUNNER_DOWNLOAD_URL +ARG UPX_COMPRESS=true + +ARG BASE_LAYER_CACHE_KEY + RUN --mount=type=bind,source=.shared,target=/mnt/shared <> /etc/sudoers + echo "#################################################" + echo "Cleanup..." + echo "#################################################" + apt-get remove -y binutils curl + rm -rf /opt/upx /mnt/shared/cmd/debian-cleanup.sh EOF - -###################### -# build image -###################### - -# https://hub.docker.com/_/python?tab=tags&name=3-slim -FROM debian:stable-slim AS build-image - -USER root - -SHELL ["/bin/bash", "-c"] - -ARG BASE_LAYER_CACHE_KEY -ARG DEBIAN_FRONTEND=noninteractive -ARG LC_ALL=C -ARG INSTALL_SUPPORT_TOOLS=0 - -ARG ACT_RUNNER_DOWNLOAD_URL -ARG UPX_COMPRESS=true - -RUN --mount=type=bind,source=.shared,target=/mnt/shared <