Skip to content

Instantly share code, notes, and snippets.

@kathoef
Last active October 22, 2024 15:59
Show Gist options
  • Save kathoef/ecc61ee6566221bdd84c481da7725bfd to your computer and use it in GitHub Desktop.
Save kathoef/ecc61ee6566221bdd84c481da7725bfd to your computer and use it in GitHub Desktop.
Gitlab runner: Rootless Docker Executor on Ubuntu 22.04

Setup a rootless Docker build compatible Gitlab runner

Install Docker engine (tested with v20.10.17) and Gitlab runner (tested with v15.2.1) as described here and here.

Identify the UID of the gitlab-runner user.

$ id gitlab-runner
uid=999(gitlab-runner) gid=998(gitlab-runner) groups=998(gitlab-runner)

Do not forget to install the namespace packages described here and to specify UID ranges for the gitlab-runner user.

$ cat /etc/subuid
gitlab-runner:100000:65536
$ cat /etc/subgid
gitlab-runner:100000:65536

Install a rootless Docker service for a user. Take the rootless Docker service configuration file from this user (/home/the-user/.config/systemd/user/docker.service) and extend it by the following options.

User=gitlab-runner
Group=gitlab-runner
Environment=XDG_RUNTIME_DIR=/run/user/999
Environment=HOME=/home/gitlab-runner

Then, install it as a Docker rootless service in a system location.

$ cat /etc/systemd/system/docker-rootless.service 
[Unit]
Description=Docker Application Container Engine (Rootless)
Documentation=https://docs.docker.com/go/rootless/

[Service]
Environment=PATH=/usr/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
ExecStart=/usr/bin/dockerd-rootless.sh 
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
Type=simple
KillMode=mixed
User=gitlab-runner
Group=gitlab-runner
Environment=XDG_RUNTIME_DIR=/run/user/999
Environment=HOME=/home/gitlab-runner

[Install]
WantedBy=default.target

Make sure that the gitlab-runner is always "logged in" so that XDG_RUNTIME_DIR expected by the Docker rootless daemon does exist. (I do not know if the loginctl-approach "survives" machine restarts.)

$ sudo loginctl enable-linger gitlab-runner

Finally, "patch" the Gitlab runner systemd service using the following options.

User=gitlab-runner
Group=gitlab-runner
Environment=DOCKER_HOST=unix:///run/user/999/docker.sock
ExecStart=/usr/bin/gitlab-runner "run" "--working-directory" "/home/gitlab-runner" "--config" "/home/gitlab-runner/config.toml" "--service" "gitlab-runner" "--user" "gitlab-runner"

Which leads to this configuration in a system location.

$ cat /etc/systemd/system/gitlab-runner.service 
[Unit]
Description=GitLab Runner
ConditionFileIsExecutable=/usr/bin/gitlab-runner
 
After=syslog.target network.target 

[Service]
StartLimitInterval=5
StartLimitBurst=10
User=gitlab-runner
Group=gitlab-runner
Environment=DOCKER_HOST=unix:///run/user/999/docker.sock
ExecStart=/usr/bin/gitlab-runner "run" "--working-directory" "/home/gitlab-runner" "--config" "/home/gitlab-runner/config.toml" "--service" "gitlab-runner" "--user" "gitlab-runner"

Restart=always

RestartSec=120
EnvironmentFile=-/etc/sysconfig/gitlab-runner

[Install]
WantedBy=multi-user.target

You can then proceed to register Gitlab runners (sudo gitlab-runner register) that will use the rootless Docker daemon as their Docker executor.

$ sudo cat /home/gitlab-runner/config.toml
concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "docker-build-rootless"
  url = "..."
  token = "..."
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:20.10.17"
    privileged = true # for docker-service approach
    #privileged = false # for docker.sock approach
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    #volumes = ["/run/user/999/docker.sock:/var/run/docker.sock", "/cache"] # for docker.sock approach
    shm_size = 0

Note, these rootless Docker limitations, which in terms of functionality might not be a problem for the Docker build use case considered here.

.gitlab-ci.yml example

image: docker:20.10.17

variables:
  DOCKER_HOST: tcp://dockerservice:2375
  DOCKER_TLS_CERTDIR: ""

services:
  - name: docker:20.10.17-dind
    alias: dockerservice

explore_the_docker_host_system:
  script:
    - docker run -v /:/root/host ubuntu:22.04 ls -la /root/host

build_some_docker_image:
  script:
    - docker build --no-cache -t test-unpriv-docker-ci .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment