## Overview This container image is built daily from this `Containerfile`, and made available as: * `registry.gitlab.com/qontainers/pipglr:latest` -or- * `registry.gitlab.com/qontainers/pipglr:` It's purpose is to provide an easy method to execute a GitLab runner, to service CI/CD jobs for groups and/or repositories on [gitlab.com](https://gitlab.com). It comes pre-configured to utilize the gitlab-runner app to execute within a rootless podman container, nested inside a rootless podman container. This is intended to provide additional layers of security for the host, when running potentially arbitrary CI/CD code. Though, the ultimate responsibility still rests with the end-user to review the setup and configuration relative to their own security situation/environment. ### Operation This image supports `podman container runlabel`, or if your version lacks this feature, Several labels are set on the image to support easy registration and execution of a runner container using a special bash command. See the examples below for more information. #### [Volume setup] Since podman inside the container runs as user `podman`, the volumes used by it need to be pre-created with ownership information. While, we're at it, might as well add the performance-improving `noatime`, option as well. ```bash $ VOLOPTS="o=uid=1000,gid=1000,noatime"; \ for VOLUME in pipglr-podman-root pipglr-config pipglr-podman-cache; do \ podman volume create --opt $VOLOPTS $VOLUME || true ; \ VOLPTH=$(podman unshare podman volume mount $VOLUME) podman unshare chown -c -R 1000:1000 $VOLPTH && \ podman unshare chmod -c 02770 $VOLPTH && \ podman unshare podman volume unmount $VOLUME ; \ done ``` If you get `podman system service` startup permission-denied errors, or errors from gitlab-runner, unable to connect to the podman socket, this is likely the cause. You can fix it after-the-fact using the same commands above. #### Runner registration Each time the registration command is run, a new runner is added into the configuration. If however, you simply need to update/modify the configuration, please edit the `config.toml` file directly after mounting (default) `pipglr-runner-config` (`/home/podman/.gitlab-runner/`) volume. For modern versions of podman, registration can be performed with the following commands: ```bash $ IMAGE="registry.gitlab.com/qontainers/pipglr:latest" $ echo '' | podman secret create REGISTRATION_TOKEN - $ podman container runlabel register $IMAGE ``` Where `` is the value obtained from the "runners" settings page of a gitlab group or project. When you're finished registering as many runners as you want, the secret is no-longer needed and may be removed: ```bash $ podman secret rm REGISTRATION_TOKEN ``` ##### Note Some versions of podman don't support the `container runlabel` sub-command. If this is the case, you may simulate it with the following command (in addition to the other example commands above): ```bash $ eval $(podman inspect --format=json $IMAGE | jq -r .[].Labels.register) ``` #### Runner Startup With one or more runners successfully registered and configured, the GitLab runner container may be launched with the following commands: ```bash $ podman container runlabel run $IMAGE ``` ##### Note As above, if you're missing the `container runlabel` sub-command, the following may be used instead (assuming `$IMAGE` remains set): ```bash $ eval $(podman inspect --format=json $IMAGE | jq -r .[].Labels.run) ``` #### Runner configuration You may inspect/modify the gitlab-runner configuration as you see fit, just be sure to use the `podman unshare` command-wrapper to enter the usernamespace. For example, to display the config: ```bash $ podman unshare cat $(podman unshare podman volume mount pipglr-config)/config.toml ``` Edit the config with your favorite `$EDITOR`: ```bash $ podman unshare $EDITOR $(podman unshare podman volume mount pipglr-config)/config.toml ``` #### Debugging The first thing to check is the container output: ```bash $ podman logs --since 0 pipglr ``` Next, try running pipglr after an `export PODMAN_RUNNER_DEBUG=debug` to enable debugging on the inner-podman. If more runner detail is needed, you can instead/additionally set `export LOG_LEVEL=debug` to debug the gitlab-runner itself. ## Building This image may be built simply with: ```bash $ podman build -t registry.gitlab.com/qontainers/pipglr:latest . ``` This will utilize the latest stable version of podman and the latest stable version of the gitlab runner. ### Notes * If you wish to use the `testing` or `upstream` flavors of the podman base image, simply build with `--build-arg FLAVOR=testing` (or `upstream`). * Additionally or alternatively, you may specify a specific podman base image tag with `--build-arg BASE_TAG=`. Where `` is either `latest`, the podman image version (e.g. `v4`, `v4.2`, `v4.2.0`, etc.) ### Build-args Several build arguments are available to control the output image: * `FLAVOR` - Choose from 'stable', 'testing', or 'upstream'. These select the podman base-image to utilize - which may affect the podman version, features, and stability. For more information see [the podmanimage README](https://github.com/containers/podman/blob/main/contrib/podmanimage/README.md). * `BASE_TAG` - When `FLAVOR="stable"`, allows granular choice over the exact podman version. Possible values include, `latest`, `vX`, `vX.Y`, and `vX.Y.Z` (where, `X`, `Y`, and `Z` represent the podman semantic version numbers). It's also possible to specify an image SHA. * `CLEAN_INTERVAL` - A `sleep` (command) compatible time-argument that determines how often to clean out podman storage of disused containers and images. Defaults to 24-hours, but should be adjusted based on desired caching-effect versus available storage space and rate of job execution. * `EXCLUDE_PACKAGES` - A space-separated list of RPM packages to prevent their existence in the final image. This is intended as a security measure to limit the attack-surface should a gitlab-runner process escape it's inner-container. * `RUNNER_VERSION` - Allows specifying an exact gitlab runner version. By default the `latest` is used, assuming the user is building a tagged image anyway. Valid versions may be found on the [runner release page](https://gitlab.com/gitlab-org/gitlab-runner/-/releases). * `DNFCMD` - By default this is set to `dnf --setopt=tsflags=nodocs -y`. However, if you'd like to volume-mount in `/var/cache/dnf` then you'll need to use `--build-arg DNFCMD="dnf --setopt=tsflags=nodocs -y --setopt keepcache=true`" Note: Changing `DNFCMD` will cause build-time cache cleanup to be disabled. * `TARGETARCH` - Supports inclusion of non-x86_64 gitlab runners. This value is assumed to match the image's architecture. If using the `--platform` build argument, it will be set automatically. * `RUNNER_LISTEN_ADDRESS` - Disabled by default, setting this to the FQDN and port supports various observability and debugging features of the gitlab runner. For more information see the [gitlab runner advanced configuration documentation](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section). * `PRIVILEGED_RUNNER` - Defaults to 'true', may be set 'true' if you're brave. However this may result in the gitlab-runner failing to launch inner-containers. Setting it false will also prevent building container images using the runner. * `RUNNER_TAGS` - Defaults to `podman_in_podman`, may be set to any comma-separated list (with no spaces!) of tags. These show up in GitLab (not the runner configuration), and determines where jobs are run. * `RUNNER_UNTAGED` - Defaults to `true`, may be set to `false`. Allows the runner to service jobs without any tags on them at all. ### Environment variables Nearly every option to every gitlab-runner sub-command may be specified via environment variable. Many important/required options are set in the `Containerfile`. However it's entirely possible to pass them in via either of the `podman container runlabel...` container commands. To discover them, simply append `--help` to the end of the command. For example: ```bash podman container runlabel $IMAGE register --help ```