Compare commits

...

3 commits

Author SHA1 Message Date
fdd9eadad1
docker(role): document gVisor issue with user-def. br. and provide help
Some checks failed
/ Ansible Lint (push) Successful in 3m53s
/ build (pull_request) Failing after 2m40s
/ Ansible Lint (pull_request) Successful in 2m41s
Document issue with containers on user-defined bridges and using the
gVisor runsc runtime. Also provide a helper resolv.conf as a workaround.
2026-06-23 21:00:33 +02:00
f956ed6f35
docker(role): provide option to set up gVisor (runsc runtime) 2026-06-23 21:00:33 +02:00
d4a1dee108
forgejo_runner(role): create role for setting up Forgejo Runner install 2026-06-23 21:00:33 +02:00
18 changed files with 357 additions and 19 deletions

View file

@ -16,7 +16,10 @@ None.
## Optional Arguments
None.
- `docker__gvisor_setup`: Whether or not to set up [gVisor](https://gvisor.dev/) (`runsc` runtime).
> Note: gVisor doesn't work with the embedded DNS server Docker forces for user-defined bridges (see the [relevant GitHub issue](https://github.com/google/gvisor/issues/7469)). A workaround would be to bind mount a `resolv.conf` not relying on localhost DNS (note however that this still doesn't provide local container name resolution). When enabling this option such a helper `resolv.conf` pointing to Quad9 gets deployed to `/etc/gvisor-helper-resolv.conf` for bind-mounting. See the file for usage instructions.
Defaults to `false`.
## Links & Resources

View file

@ -0,0 +1 @@
docker__gvisor_setup: false

View file

@ -0,0 +1,9 @@
# resolv.conf pointing to Quad9 for bind-mounting into containers on user-defined bridges and using the gVisor runsc runtime.
# Example: docker run --runtime runsc --mount type=bind,src=/etc/gvisor-helper-resolv.conf,dst=/etc/resolv.conf,ro=true --network your-user-defined-network -it --rm docker.io/library/debian /bin/bash
nameserver 9.9.9.9
nameserver 149.112.112.112
nameserver 2620:fe::fe
nameserver 2620:fe::9
options edns0

View file

@ -2,3 +2,9 @@
ansible.builtin.systemd_service:
daemon_reload: true
become: true
- name: restart the docker service
ansible.builtin.systemd:
name: docker.service
state: restarted
become: true

View file

@ -0,0 +1,6 @@
argument_specs:
main:
options:
docker__gvisor_setup:
type: bool
required: false

View file

@ -1,15 +1,36 @@
- name: Ensure Dockers GPG key is added
ansible.builtin.get_url:
url: https://download.docker.com/linux/debian/gpg
dest: /etc/apt/trusted.gpg.d/docker.asc
mode: "0644"
owner: root
group: root
become: true
- name: ensure Docker repo
block:
- name: Ensure Dockers GPG key is added
ansible.builtin.get_url:
url: https://download.docker.com/linux/debian/gpg
dest: /etc/apt/trusted.gpg.d/docker.asc
mode: "0644"
owner: root
group: root
become: true
- name: Ensure Docker APT repository is added
ansible.builtin.apt_repository:
repo: "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.asc] https://download.docker.com/linux/debian {{ ansible_facts['distribution_release'] }} stable"
filename: docker
state: present
become: true
- name: Ensure Docker APT repository is added
ansible.builtin.apt_repository:
repo: "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.asc] https://download.docker.com/linux/debian {{ ansible_facts['distribution_release'] }} stable"
filename: docker
state: present
become: true
- name: ensure gVisor repo
when: docker__gvisor_setup
block:
- name: Ensure gVisors GPG key is added
ansible.builtin.get_url:
url: https://gvisor.dev/archive.key
dest: /etc/apt/keyrings/gvisor.asc
mode: "0644"
owner: root
group: root
become: true
- name: Ensure gVisors APT repository is added
ansible.builtin.apt_repository:
repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/gvisor.asc] https://storage.googleapis.com/gvisor/releases release main"
filename: gvisor
state: present
become: true

View file

@ -9,3 +9,12 @@
state: present
update_cache: true
become: true
- name: Ensure gVisors packages are installed
when: docker__gvisor_setup
ansible.builtin.apt:
name:
- runsc
state: present
update_cache: true
become: true

View file

@ -2,10 +2,21 @@
# - log to systemd journal
# https://docs.docker.com/engine/logging/drivers/journald/
- name: Ensure Docker daemon configuration
ansible.builtin.copy:
src: daemon.json
ansible.builtin.template:
src: daemon.json.j2
dest: /etc/docker/daemon.json
owner: root
group: root
mode: "0644"
become: true
notify: restart the docker service
- name: Ensure helper gVisor resolv.conf is deployed
when: docker__gvisor_setup
ansible.builtin.copy:
src: gvisor-helper-resolv.conf
dest: /etc/gvisor-helper-resolv.conf
owner: root
group: root
mode: "0644"
become: true

View file

@ -1,7 +1,7 @@
{
"log-driver": "journald",
"log-opts": {
"tag": "{{.Name}}"
"tag": "{{ '{{.Name}}' }}"
},
"ipv6": true,
"ip6tables": true,
@ -10,5 +10,10 @@
"bridge": {
"com.docker.network.enable_ipv6":"true"
}
}
}{% if docker__gvisor_setup %},
"runtimes": {
"runsc": {
"path": "/usr/bin/runsc"
}
}{% endif %}
}

View file

@ -0,0 +1,9 @@
# `forgejo_runner`
Ensures Forgejo Runner is installed and set up.
See: https://forgejo.org/docs/latest/admin/actions/
## Required Arguments
- `forgejo_runner__config`: The configuration to run the Forgejo Runner with.
A configuration can be generated using `forgejo-runner generate-config`. Also see the [relevant docs](https://forgejo.org/docs/latest/admin/actions/configuration/).

View file

@ -0,0 +1,71 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: EB11 4F5E 6C0D C2BC DD18 3550 A4B6 1A2D C592 3710
Comment: Forgejo <contact@forgejo.org>
Comment: Forgejo Releases <release@forgejo.org>
xjMEY3T/yhYJKwYBBAHaRw8BAQdAVxqCQrSbpDNrx8CiTM8PUAVqdCyv2UmBDhpP
HZIpoIDNHUZvcmdlam8gPGNvbnRhY3RAZm9yZ2Vqby5vcmc+wsB+BBMWCgDmAhsD
BQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAhkBFiEE6xFPXmwNwrzdGDVQpLYaLcWS
NxAFAmSc08VBFIAAAAAAEAAocHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vY29kZWJl
cmcub3JnL2Zvcmdlam8vZ2l0ZWFfcHJvb2Y2FIAAAAAAEAAdcHJvb2ZAYXJpYWRu
ZS5pZGh0dHBzOi8vZmxvc3Muc29jaWFsL0Bmb3JnZWpvMRSAAAAAABAAGHByb29m
QGFyaWFkbmUuaWRkbnM6Zm9yZ2Vqby5vcmc/dHlwZT1UWFQACgkQpLYaLcWSNxDM
2wEA6bOel3R25z3YUXL4hI2S8jRkJbOQawq0vgUnYNgS9hcBAK2zq4Zt4ctvSB+x
TqhR6Zi6aqSD3QrRnUVvV1xZhdkEwsCABBMWCgDoAhsDBQsJCAcDBRUKCQgLBRYC
AwEAAh4BAheAAhkBFiEE6xFPXmwNwrzdGDVQpLYaLcWSNxAFAmScz7JDFIAAAAAA
EAAqcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vY29kZWJlcmcub3JnL2Zvcmdlam8v
Zm9yZ2Vqb19wcm9vZjYUgAAAAAAQAB1wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9m
bG9zcy5zb2NpYWwvQGZvcmdlam8xFIAAAAAAEAAYcHJvb2ZAYXJpYWRuZS5pZGRu
czpmb3JnZWpvLm9yZz90eXBlPVRYVAAKCRCkthotxZI3EBJ1AP9UeN1HFGz90r34
PGrOj1225HfJzdWgamEUkEKEwShcIQD+K/o7sLJM+C/mJXaCixAZgvRd9/rYq27T
9Y2rTQybSwnCwH4EExYKAOYCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4ACGQEW
IQTrEU9ebA3CvN0YNVCkthotxZI3EAUCY3spkjYUgAAAAAAQAB1wcm9vZkBhcmlh
ZG5lLmlkaHR0cHM6Ly9mbG9zcy5zb2NpYWwvQGZvcmdlam8xFIAAAAAAEAAYcHJv
b2ZAYXJpYWRuZS5pZGRuczpmb3JnZWpvLm9yZz90eXBlPVRYVEEUgAAAAAAQAChw
cm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9jb2RlYmVyZy5vcmcvZm9yZ2Vqby9naXRl
YV9wcm9vZgAKCRCkthotxZI3EC+hAQCxsUupyqMChFMqk/74PqzSlmCd6RXtbezP
W66YostSbgD9G+N+c9or1cBkcSejREOSy7TFrDrvek+ZhdZVhCp1UALCwEcEExYK
AK8CGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4ACGQEWIQTrEU9ebA3CvN0YNVCk
thotxZI3EAUCY3inA0EUgAAAAAAQAChwcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9j
b2RlYmVyZy5vcmcvZm9yZ2Vqby9naXRlYV9wcm9vZjEUgAAAAAAQABhwcm9vZkBh
cmlhZG5lLmlkZG5zOmZvcmdlam8ub3JnP3R5cGU9VFhUAAoJEKS2Gi3FkjcQNV8B
AJfcHBzskW78lJVJeQwCI70qorOhC/QUp80jjNzs5lO7AQCujYgrae3vZb/476sc
wM33ufSpBguNwTLbCI6C5g8+B80mRm9yZ2VqbyBSZWxlYXNlcyA8cmVsZWFzZUBm
b3JnZWpvLm9yZz7CkAQTFgoAOAIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgBYh
BOsRT15sDcK83Rg1UKS2Gi3FkjcQBQJjeKH0AAoJEKS2Gi3FkjcQC5YBAKwCGFDD
SpX0JwBrzIP8W8ElwHvdBz2XDg8LwyQgr722AP9r01rbFwY4axDxpNj+BUFxwD5F
hza1cE3932eTsSOPDsKQBBMWCAA4FiEE6xFPXmwNwrzdGDVQpLYaLcWSNxAFAmN4
k+kCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQpLYaLcWSNxBHrQD+PFo/
ii8p72HP0KsJbHPGnS/Sk9pFGd16fs1Hd88JHj0A/10XNyGQgwbe+X+K/a97vWW8
vAzA1EtFIMfCGhIO8EoIzjMEY3UANBYJKwYBBAHaRw8BAQdAKvAs2Ij2RamYUzz4
sBgsc2J+4fEwvSMcTp6rPZizRhfCwDUEGBYIACYWIQTrEU9ebA3CvN0YNVCkthot
xZI3EAUCY3UANAIbAgUJAeEzgACBCRCkthotxZI3EHYgBBkWCAAdFiEE98vwIJTn
Zl4X7WxE44G/PlDVNwcFAmN1ADQACgkQ44G/PlDVNwdIlgD+K15nuEec+VTFdP7Y
Y3SxM8Rjg2EtXk007+LM7XQfN9sBAOLjBTzIdaaKOpoAkGQ9Th/IphSUOnPYZVO5
a6cN+wAM458A/itf3urQehI5SbKtbRqIDhqQZQVAcEeG2eQFunuofjDWAQDt/gE5
XgTiQgnkTcqAX7GQeE74O/Q5vDtX10NjbzV7D84zBGeOav0WCSsGAQQB2kcPAQEH
QI2JXHjIx25g9WZHNyjkdUiRBPl5Y1JjjJCPvXM0/9RjwsA1BBgWCAAmFiEE6xFP
XmwNwrzdGDVQpLYaLcWSNxAFAmeOav0CGwIFCQO1OAAAgQkQpLYaLcWSNxB2IAQZ
FggAHRYhBA9SfPk6PQ0JJdPFXtCoIAUOFgnlBQJnjmr9AAoJENCoIAUOFgnljUwA
+wSjU/mk4xGIlwzJdPnnNzIsiMeqtuYokbSrOIxXIhP1AP93qtVr+kOu3pDs9JC+
8CYG0DK1QD1LmlGP59WRGevSCXChAQDy6SCfnfcr5P4fYaz04+Tl0CDUkFOGP+sV
S/isPTssbAD9H2hKJKEmwuAd2MeFA3Bo3z5rUVWkfAcnv7Oy7u+OWQfOMwRlfHnh
FgkrBgEEAdpHDwEBB0DGoKPPOOx7rnqT318eykUkMJbk83MhcBqrecOADO3i2sLA
NQQYFggAJhYhBOsRT15sDcK83Rg1UKS2Gi3FkjcQBQJlfHnhAhsCBQkCx+oAAIEJ
EKS2Gi3FkjcQdiAEGRYIAB0WIQTfMxnqNtWZwdSmg9SzsfYKxXfyogUCZXx54QAK
CRCzsfYKxXfyoocRAP48OQpiBTkwC7kLLyuqVlP1t0hBQddr4i4rIV8Ug5tHzwEA
pl8Q+S4k/ROQS5FOhy7GBC337SncJFJYDD0pTcSecw+J3AEAn4qax72Oyfb0vaPY
m+WdqsfVBd2Hd2vJIwCjglp55B0BALIJE6nvACcKzTRUj7AQSLGvELGfJfM320xX
E0ZVBZkKzjMEaUFtxRYJKwYBBAHaRw8BAQdA1AZR9j6PksmArHjaoqOHIOQ4H1iw
0KZyLKLgu1onR8fCwDUEGBYIACYWIQTrEU9ebA3CvN0YNVCkthotxZI3EAUCaUFt
xQIbAgUJAsfqAACBCRCkthotxZI3EHYgBBkWCAAdFiEEO/ToE/hIEkEdoB5bxBht
9m9LZ1AFAmlBbcUACgkQxBht9m9LZ1DQHAD9EUEM23tJJUae0L1DbGnWEp3GnZOQ
G3Z34uWv16wRV3EA+gJuHa9Zr1TXAEXXBwQzZIrAFby+7I5smWPVM84c7xYA/qEA
/2dQMMZcRelFC0fIPvGQMGfYeBr8bkHKlJBQOTdukeSPAQCcd9rqJT7NNZlPtJ1T
wNAfAa3L23bdp/dEtKhE+d09CM44BGN0/8oSCisGAQQBl1UBBQEBB0CZnRfIHxTV
hOF8kdhbe4YJsePyVFi8USfuDXy4HgIHRgMBCAfCeAQYFggAIBYhBOsRT15sDcK8
3Rg1UKS2Gi3FkjcQBQJjdP/KAhsMAAoJEKS2Gi3FkjcQdroA/jHFqt7y/r/5zdK4
TYYp+5jlOgM5ZI7pNhWhtIFbqmx9AQCKSJf2YgPBLNJSL/86vpE9b6IvTE/8ENR/
7xYaIA7oAg==
=D+4T
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,19 @@
# Source: https://code.forgejo.org/forgejo/runner/src/branch/main/contrib/forgejo-runner.service
[Unit]
Description=Forgejo Runner
Documentation=https://forgejo.org/docs/latest/admin/actions/
After=docker.service
Requires=docker.service
[Service]
ExecStart=/usr/local/bin/forgejo-runner daemon -c /etc/forgejo-runner-config.yaml
ExecReload=/bin/kill -s HUP $MAINPID
User=runner
WorkingDirectory=/home/runner
Restart=on-failure
TimeoutSec=0
RestartSec=10
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,10 @@
- name: systemd daemon reload
ansible.builtin.systemd_service:
daemon_reload: true
become: true
- name: restart the forgejo-runner service
ansible.builtin.systemd:
name: forgejo-runner.service
state: restarted
become: true

View file

@ -0,0 +1,6 @@
argument_specs:
main:
options:
forgejo_runner__config:
type: str
required: true

View file

@ -0,0 +1,3 @@
---
dependencies:
- role: docker

View file

@ -0,0 +1,7 @@
- name: Ensure Forgejo Runner is installed
ansible.builtin.import_tasks:
file: main/01_install.yaml
- name: Ensure Forgejo Runner is set up
ansible.builtin.import_tasks:
file: main/02_setup.yaml

View file

@ -0,0 +1,96 @@
- name: get latest release info
ansible.builtin.uri:
url: "https://data.forgejo.org/api/v1/repos/forgejo/runner/releases/latest"
return_content: true
register: forgejo_runner__latest_release_info
- name: set latest version
ansible.builtin.set_fact:
forgejo_runner__latest_version: "{{ forgejo_runner__latest_release_info.json.name | replace('v', '') }}"
- name: set latest version forgejo-runner binary path
ansible.builtin.set_fact:
forgejo_runner__latest_version_binary_path: "/usr/local/bin/forgejo-runner-{{ forgejo_runner__latest_version }}"
- name: check if latest version forgejo-runner binary is installed already
ansible.builtin.stat:
path: "{{ forgejo_runner__latest_version_binary_path }}"
register: forgejo_runner_latest_version_binary_stat
- name: download and install latest version, if not already present
when: not forgejo_runner_latest_version_binary_stat.stat.exists
block:
- name: set download url
ansible.builtin.set_fact:
forgejo_runner__download_url: "https://code.forgejo.org/forgejo/runner/releases/download/v{{ forgejo_runner__latest_version }}/forgejo-runner-{{ forgejo_runner__latest_version }}-linux-amd64"
- name: temporary directory for download
ansible.builtin.tempfile:
state: directory
suffix: forgejo_runner_download
become: true
register: forgejo_runner__download_tempdir
- name: download the forgejo-runner binary
ansible.builtin.get_url:
url: "{{ forgejo_runner__download_url }}"
dest: "{{ forgejo_runner__download_tempdir.path }}/forgejo-runner"
owner: root
group: root
mode: "0755"
become: true
- name: download the signature
ansible.builtin.get_url:
url: "{{ forgejo_runner__download_url }}.asc"
dest: "{{ forgejo_runner__download_tempdir.path }}/forgejo-runner.asc"
owner: root
group: root
mode: "0644"
become: true
- name: copy key for verification
ansible.builtin.copy:
src: "EB114F5E6C0DC2BCDD183550A4B61A2DC5923710.asc"
dest: "{{ forgejo_runner__download_tempdir.path }}/forgejo-runner-key.asc"
owner: root
group: root
mode: "0644"
become: true
- name: ensure sq (Sequoia-PGP) is installed
ansible.builtin.apt:
name: sq
become: true
- name: verify signature
ansible.builtin.command:
cmd: /usr/bin/sq verify --signer-file ./forgejo-runner-key.asc --signature-file forgejo-runner.asc --signatures 1 forgejo-runner
chdir: "{{ forgejo_runner__download_tempdir.path }}"
become: true
changed_when: false
- name: install forgejo-runner binary of this latest version
ansible.builtin.copy:
remote_src: true
src: "{{ forgejo_runner__download_tempdir.path }}/forgejo-runner"
dest: "{{ forgejo_runner__latest_version_binary_path }}"
owner: root
group: root
mode: "0755"
become: true
- name: ensure symlink points to binary of this latest version
ansible.builtin.file:
src: "{{ forgejo_runner__latest_version_binary_path }}"
dest: "/usr/local/bin/forgejo-runner"
state: link
owner: root
group: root
become: true
always:
- name: delete temporary download directory
ansible.builtin.file:
path: "{{ forgejo_runner__download_tempdir.path }}"
state: absent
become: true

View file

@ -0,0 +1,46 @@
- name: ensure runner group exists
ansible.builtin.group:
name: runner
system: true
become: true
- name: ensure runner user exists
ansible.builtin.user:
name: runner
group: runner
password: '!'
system: true
create_home: true
groups:
- docker
become: true
- name: ensure the configuration is deployed
ansible.builtin.copy:
content: "{{ forgejo_runner__config }}"
dest: /etc/forgejo-runner-config.yaml
owner: root
group: runner
mode: "0640"
become: true
notify:
- restart the forgejo-runner service
- name: ensure systemd service exists
ansible.builtin.copy:
src: forgejo-runner.service
dest: /etc/systemd/system/forgejo-runner.service
owner: root
group: root
mode: "0644"
become: true
notify:
- systemd daemon reload
- restart the forgejo-runner service
- name: ensure systemd service is started and enabled
ansible.builtin.systemd_service:
name: forgejo-runner.service
state: started
enabled: true
become: true