feat: add Gitea Actions runner on private compute
Adds a private runner server on the Hetzner private network with NAT through the gitea server for outbound internet access. Includes Terraform resources, Ansible playbooks, and iptables forwarding rules. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -108,6 +108,41 @@
|
||||
- docker-buildx-plugin
|
||||
- docker-compose-plugin
|
||||
|
||||
- name: Enable NAT for private network.
|
||||
hosts: server
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Enable IP forwarding.
|
||||
ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: "1"
|
||||
sysctl_set: true
|
||||
reload: true
|
||||
|
||||
- name: Add NAT masquerade rule.
|
||||
ansible.builtin.iptables:
|
||||
table: nat
|
||||
chain: POSTROUTING
|
||||
source: "10.0.1.0/24"
|
||||
jump: MASQUERADE
|
||||
state: present
|
||||
|
||||
- name: Allow forwarding from private network.
|
||||
ansible.builtin.iptables:
|
||||
chain: DOCKER-USER
|
||||
source: "10.0.1.0/24"
|
||||
jump: ACCEPT
|
||||
action: insert
|
||||
state: present
|
||||
|
||||
- name: Allow established/related return traffic.
|
||||
ansible.builtin.iptables:
|
||||
chain: DOCKER-USER
|
||||
ctstate: ESTABLISHED,RELATED
|
||||
jump: ACCEPT
|
||||
action: insert
|
||||
state: present
|
||||
|
||||
- name: Deploy artifact to instance.
|
||||
hosts: server
|
||||
tags:
|
||||
|
||||
131
playbooks/runner.yml
Normal file
131
playbooks/runner.yml
Normal file
@@ -0,0 +1,131 @@
|
||||
- name: Set up runner host via jumphost.
|
||||
gather_facts: false
|
||||
hosts: localhost
|
||||
vars_files:
|
||||
- ../vault.yml
|
||||
- ../dist/terraform_outputs.yml
|
||||
tasks:
|
||||
- name: Add gitea server as jumphost.
|
||||
ansible.builtin.add_host:
|
||||
name: server
|
||||
ansible_ssh_host: "{{ server_ip.value }}"
|
||||
ansible_user: root
|
||||
ansible_port: 2222
|
||||
ansible_private_key_file: "{{ secret.private_ssh_key_path }}"
|
||||
|
||||
- name: Add runner host (via jumphost).
|
||||
ansible.builtin.add_host:
|
||||
name: runner
|
||||
ansible_ssh_host: "{{ runner_ip.value }}"
|
||||
ansible_user: root
|
||||
ansible_private_key_file: "{{ secret.private_ssh_key_path }}"
|
||||
ansible_ssh_common_args: >-
|
||||
-o ProxyCommand="ssh -i {{ secret.private_ssh_key_path }} -p 2222 -W %h:%p root@{{ server_ip.value }}"
|
||||
|
||||
- name: Install Docker on runner.
|
||||
gather_facts: true
|
||||
hosts: runner
|
||||
vars_files:
|
||||
- ../vault.yml
|
||||
- ../dist/terraform_outputs.yml
|
||||
tasks:
|
||||
- name: Set DNS resolver.
|
||||
ansible.builtin.copy:
|
||||
content: "nameserver 185.12.64.2\n"
|
||||
dest: /etc/resolv.conf
|
||||
mode: "0644"
|
||||
|
||||
- name: Install PIP.
|
||||
ansible.builtin.apt:
|
||||
state: present
|
||||
update_cache: true
|
||||
name:
|
||||
- python3-pip
|
||||
|
||||
- name: Install needed packages.
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- packaging
|
||||
state: present
|
||||
break_system_packages: true
|
||||
|
||||
- name: Download Docker repository key.
|
||||
ansible.builtin.apt_key:
|
||||
url: https://download.docker.com/linux/debian/gpg
|
||||
state: present
|
||||
|
||||
- name: Download Docker repository.
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable"
|
||||
state: present
|
||||
|
||||
- name: Remove bad packages.
|
||||
ansible.builtin.apt:
|
||||
state: absent
|
||||
package:
|
||||
- docker.io
|
||||
- docker-doc
|
||||
- docker-compose
|
||||
- podman-docker
|
||||
- containerd
|
||||
- runc
|
||||
|
||||
- name: Download Docker dependencies.
|
||||
ansible.builtin.apt:
|
||||
state: present
|
||||
package:
|
||||
- ca-certificates
|
||||
- curl
|
||||
- jq
|
||||
|
||||
- name: Download Docker packages.
|
||||
ansible.builtin.apt:
|
||||
state: present
|
||||
update_cache: true
|
||||
package:
|
||||
- docker-ce
|
||||
- docker-ce-cli
|
||||
- containerd.io
|
||||
- docker-buildx-plugin
|
||||
- docker-compose-plugin
|
||||
|
||||
- name: Register and start Gitea runner.
|
||||
hosts: runner
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- ../vault.yml
|
||||
- ../dist/terraform_outputs.yml
|
||||
vars:
|
||||
gitea_internal_url: "https://{{ server_fqdn.value }}"
|
||||
tasks:
|
||||
- name: Create runner data volume.
|
||||
community.docker.docker_volume:
|
||||
name: runner-data
|
||||
state: present
|
||||
|
||||
- name: Generate runner config.
|
||||
ansible.builtin.copy:
|
||||
dest: /root/runner-config.yaml
|
||||
mode: "0644"
|
||||
content: |
|
||||
runner:
|
||||
insecure: true
|
||||
|
||||
- name: Start Gitea runner container.
|
||||
community.docker.docker_container:
|
||||
name: gitea-runner
|
||||
image: gitea/act_runner:latest
|
||||
state: started
|
||||
recreate: true
|
||||
restart_policy: unless-stopped
|
||||
etc_hosts:
|
||||
"{{ server_fqdn.value }}": "10.0.1.2"
|
||||
volumes:
|
||||
- runner-data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /root/runner-config.yaml:/config.yaml:ro
|
||||
env:
|
||||
GITEA_INSTANCE_URL: "{{ gitea_internal_url }}"
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ secret.runner_registration_token }}"
|
||||
GITEA_RUNNER_NAME: "runner-01"
|
||||
CONFIG_FILE: "/config.yaml"
|
||||
Reference in New Issue
Block a user