Files
grm/ansible/roles/gitea_runner/tasks/rootless_docker.yml
T
Emil SimeonovandDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 9ccdc4d6dc
CI / molecule-tests (1) (pull_request) Has been skipped
CI / molecule-tests (3) (pull_request) Has been skipped
CI / molecule-tests (2) (pull_request) Has been skipped
CI / molecule-tests (4) (pull_request) Has been skipped
CI / molecule-tests (6) (pull_request) Has been skipped
CI / molecule-tests (5) (pull_request) Has been skipped
CI / auto-merge (pull_request) Has been skipped
CI / validate (pull_request) Waiting to run
fix: load tun module and pre-configure systemd override for Arch rootless Docker
- Load the tun kernel module before running dockerd-rootless-setuptool.sh,
  as both slirp4netns and pasta drivers require /dev/net/tun inside a user
  namespace. On Arch Linux CONFIG_TUN=m so the module must be loaded
  explicitly. If modprobe fails (kernel mismatch after pacman -Syu without
  reboot), warn but don't fail — a reboot will fix it.
- Create the systemd override directory and override.conf BEFORE running
  the setuptool, so when the setuptool starts docker.service it picks up
  the pasta network driver instead of defaulting to slirp4netns.
- Pass DOCKERD_ROOTLESS_ROOTLESSKIT_NET env var to the setuptool command
  as well, for belt-and-suspenders coverage.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-16 19:12:37 +02:00

249 lines
9.2 KiB
YAML

---
- name: Ensure keyrings directory exists (Debian/Ubuntu)
ansible.builtin.file:
path: "/etc/apt/keyrings"
state: directory
mode: "0755"
when: ansible_facts['os_family'] == 'Debian'
- name: Download and dearmor Docker GPG key (Debian/Ubuntu)
ansible.builtin.shell: |
set -o pipefail
curl -fsSL "https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}/gpg" \
| gpg --dearmor --yes -o {{ gitea_runner_docker_gpg_key_path }}
args:
creates: "{{ gitea_runner_docker_gpg_key_path }}"
executable: /bin/bash
when: ansible_facts['os_family'] == 'Debian'
- name: Add Docker APT repository (Debian/Ubuntu)
ansible.builtin.copy:
dest: /etc/apt/sources.list.d/docker.list
content: "{{ gitea_runner_docker_apt_source_line }}\n"
mode: "0644"
register: gitea_runner_docker_apt_repo
when: ansible_facts['os_family'] == 'Debian'
- name: Update apt cache after adding Docker repo (Debian/Ubuntu)
ansible.builtin.apt:
update_cache: true
when:
- ansible_facts['os_family'] == 'Debian'
- gitea_runner_docker_apt_repo is changed
- name: Install rootless Docker dependencies (Debian/Ubuntu)
ansible.builtin.apt:
name:
- uidmap
- slirp4netns
- passt
- fuse-overlayfs
- docker-ce
- docker-ce-cli
- docker-ce-rootless-extras
- containerd.io
- docker-compose-plugin
- rsync
state: present
when: ansible_facts['os_family'] == 'Debian'
- name: Update pacman cache (Arch Linux)
community.general.pacman:
update_cache: true
when: ansible_facts['os_family'] == 'Archlinux'
changed_when: false
- name: Install rootless Docker dependencies (Arch Linux)
community.general.pacman:
name:
- docker
- docker-compose
- slirp4netns
- passt
- fuse-overlayfs
- rsync
# rootlesskit is the userspace networking/namespace driver for rootless Docker.
# It is NOT a dependency of the "docker" package on Arch and must be installed explicitly.
- rootlesskit
state: present
when: ansible_facts['os_family'] == 'Archlinux'
# The tun kernel module is required by rootlesskit (both slirp4netns and pasta
# drivers create a tap device inside a user namespace). On Arch Linux, CONFIG_TUN=m
# so the module must be loaded. If the running kernel doesn't match the installed
# kernel (e.g. after a pacman -Syu that upgraded linux but didn't reboot), modprobe
# will fail — in that case we warn but don't fail, as a reboot will fix it.
- name: Load tun kernel module for rootless networking
community.general.modprobe:
name: tun
state: present
ignore_errors: true
register: gitea_runner_tun_module
when: ansible_facts['os_family'] == 'Archlinux'
- name: Warn if tun module could not be loaded (kernel mismatch — reboot needed)
ansible.builtin.debug:
msg: >-
WARNING: Could not load the tun kernel module. This is likely because the
running kernel ({{ ansible_facts['kernel'] }}) does not match the installed
kernel modules. A reboot is required before rootless Docker can start.
when:
- ansible_facts['os_family'] == 'Archlinux'
- gitea_runner_tun_module is failed
# Arch Linux's "docker" package does not ship the rootless setup scripts (dockerd-rootless-setuptool.sh
# and dockerd-rootless.sh), unlike Debian/Ubuntu's docker-ce-rootless-extras. No official Arch package
# provides them, so fetch them from the upstream moby/moby contrib/ directory. They are installed
# alongside the docker binaries (/usr/bin) because dockerd-rootless-setuptool.sh derives its BIN
# directory from its own location and expects docker/dockerd/rootlesskit to be co-located there.
- name: Fetch rootless Docker setup scripts (Arch Linux)
ansible.builtin.get_url:
url: "https://raw.githubusercontent.com/moby/moby/{{ gitea_runner_rootless_scripts_ref }}/contrib/{{ item.name }}"
dest: "{{ gitea_runner_rootless_scripts_install_dir }}/{{ item.name }}"
mode: "0755"
owner: root
group: root
loop:
- name: dockerd-rootless-setuptool.sh
- name: dockerd-rootless.sh
when: ansible_facts['os_family'] == 'Archlinux'
- name: Check if rootless Docker is already set up
ansible.builtin.stat:
path: "{{ gitea_runner_home }}/.config/systemd/user/docker.service"
register: gitea_runner_rootless_docker_check
# Create the systemd override BEFORE running the setuptool so that when
# the setuptool starts docker.service, it picks up the pasta network driver
# instead of the default slirp4netns (which may fail on some kernels).
- name: Ensure systemd user override directory exists
ansible.builtin.file:
path: "{{ gitea_runner_home }}/.config/systemd/user/docker.service.d"
state: directory
mode: "0755"
owner: "{{ gitea_runner_service_user }}"
group: "{{ gitea_runner_service_user }}"
when:
- gitea_runner_docker_rootless_setup
- not gitea_runner_rootless_docker_check.stat.exists
- name: Pre-configure rootless Docker network driver override
ansible.builtin.copy:
dest: "{{ gitea_runner_home }}/.config/systemd/user/docker.service.d/override.conf"
content: |
[Service]
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET={{ gitea_runner_docker_rootless_net_driver }}"
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=implicit"
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=--ipv6"
mode: "0644"
owner: "{{ gitea_runner_service_user }}"
group: "{{ gitea_runner_service_user }}"
when:
- gitea_runner_docker_rootless_setup
- not gitea_runner_rootless_docker_check.stat.exists
- name: Set up rootless Docker for runner user
ansible.builtin.command: dockerd-rootless-setuptool.sh install
args:
creates: "{{ gitea_runner_home }}/.config/systemd/user/docker.service"
become: true
become_user: "{{ gitea_runner_service_user }}"
environment:
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
DOCKERD_ROOTLESS_ROOTLESSKIT_NET: "{{ gitea_runner_docker_rootless_net_driver }}"
when:
- gitea_runner_docker_rootless_setup
- not gitea_runner_rootless_docker_check.stat.exists
- name: Start rootless Docker daemon (systemd user service)
ansible.builtin.command: systemctl --user start docker
become: true
become_user: "{{ gitea_runner_service_user }}"
environment:
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
changed_when: true
when: gitea_runner_docker_rootless_setup
- name: Enable rootless Docker daemon (systemd user service)
ansible.builtin.command: systemctl --user enable docker
become: true
become_user: "{{ gitea_runner_service_user }}"
environment:
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
changed_when: true
when: gitea_runner_docker_rootless_setup
- name: Ensure Docker config directory exists
ansible.builtin.file:
path: "{{ gitea_runner_home }}/.config/docker"
state: directory
mode: "0755"
owner: "{{ gitea_runner_service_user }}"
group: "{{ gitea_runner_service_user }}"
when: gitea_runner_docker_rootless_setup
- name: Configure rootless Docker to use pasta with IPv6
ansible.builtin.copy:
dest: "{{ gitea_runner_home }}/.config/systemd/user/docker.service.d/override.conf"
content: |
[Service]
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_NET={{ gitea_runner_docker_rootless_net_driver }}"
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=implicit"
Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=--ipv6"
mode: "0644"
owner: "{{ gitea_runner_service_user }}"
group: "{{ gitea_runner_service_user }}"
register: gitea_runner_docker_network_override
when: gitea_runner_docker_rootless_setup
- name: Reload systemd user daemon if network config changed
ansible.builtin.command: systemctl --user daemon-reload
become: true
become_user: "{{ gitea_runner_service_user }}"
environment:
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
changed_when: true
when:
- gitea_runner_docker_rootless_setup
- gitea_runner_docker_network_override is changed
- name: Configure rootless Docker daemon with IPv6 enabled
ansible.builtin.copy:
dest: "{{ gitea_runner_home }}/.config/docker/daemon.json"
content: |
{
"ipv6": true,
"ip6tables": true,
"fixed-cidr-v6": "{{ gitea_runner_docker_ipv6_cidr }}"
}
mode: "0644"
owner: "{{ gitea_runner_service_user }}"
group: "{{ gitea_runner_service_user }}"
register: gitea_runner_docker_ipv6_config
when: gitea_runner_docker_rootless_setup
- name: Restart rootless Docker if config changed
ansible.builtin.command: systemctl --user restart docker
become: true
become_user: "{{ gitea_runner_service_user }}"
environment:
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
changed_when: true
when:
- gitea_runner_docker_rootless_setup
- gitea_runner_docker_ipv6_config is changed or gitea_runner_docker_network_override is changed
- name: Wait for rootless Docker daemon to be ready
ansible.builtin.command: docker version
become: true
become_user: "{{ gitea_runner_service_user }}"
environment:
DOCKER_HOST: "unix:///run/user/{{ gitea_runner_uid }}/docker.sock"
XDG_RUNTIME_DIR: "/run/user/{{ gitea_runner_uid }}"
register: gitea_runner_docker_ready
until: gitea_runner_docker_ready.rc == 0
retries: 10
delay: 2
changed_when: false
when: gitea_runner_docker_rootless_setup