Initial move to consolidate services on ryzen host

This commit is contained in:
2026-05-29 22:50:28 +01:00
parent 3ff5a4c677
commit 5d09ebda34
12 changed files with 365 additions and 137 deletions
+23 -5
View File
@@ -1,21 +1,39 @@
# Ansible scripte
## Setup
```bash
# Ensure `ansible-core` is installed using pipx
sudo apt remove ansible-core
# Install pipx and ansible-core
sudo apt-get install pipx
pipx install ansible-core
# Ensure your path is correct for pipx apps
pipx ensurepath
# Ensure any shell caching of paths is reset
hash -r
```
## Scripts
```bash ```bash
# install roles and collections # install roles and collections
ansible-galaxy install -r requirements.yml ansible-galaxy install -r requirements.yml
# Install the frontend # Install the frontend
ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass frontend.yaml ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass frontend.yaml -K
# Github runner # Github runner
ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass github-runner.yaml ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass github-runner.yaml -K
# gitea server # gitea server
ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass gitea.yaml ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass gitea.yaml -K
# graphana + prometheus # graphana + prometheus
ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass monitor.yaml ansible-playbook -i inventory.yaml -e @secrets.enc --ask-vault-pass monitor.yaml -K
# apt-cacheer-ng # apt-cacheer-ng
ansible-playbook -i inventory.yaml --ask-become-pass apt-cacher-ng.yaml ansible-playbook -i inventory.yaml --ask-become-pass apt-cacher-ng.yaml -K
``` ```
To make use of the apt cache, ensure you have a file like this with CACHE_HOST changes to your actual host To make use of the apt cache, ensure you have a file like this with CACHE_HOST changes to your actual host
@@ -22,7 +22,7 @@ server {
} }
location / { location / {
proxy_pass http://rpi4-2:3000; proxy_pass http://website:3000;
} }
} }
@@ -42,7 +42,7 @@ server {
# } # }
location / { location / {
proxy_pass http://rpi5-2:3000; proxy_pass http://gitea:3000;
} }
} }
@@ -62,44 +62,44 @@ server {
} }
location / { location / {
proxy_pass http://rpi4-2:3001; proxy_pass http://apptabulous_website:3000;
} }
} }
# Container registry # Container registry
server { # server {
listen 80; # listen 80;
listen [::]:80; # listen [::]:80;
listen 443 ssl; # listen 443 ssl;
listen [::]:443 ssl; # listen [::]:443 ssl;
server_name hub.apptabulous.co.uk; # server_name hub.apptabulous.co.uk;
ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem; # ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem; # ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem;
# disable any limits to avoid HTTP 413 for large image uploads # # disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0; # client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) # # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on; # chunked_transfer_encoding on;
location / { # location / {
proxy_pass http://rpi4-2:5000; # proxy_pass http://rpi4-2:5000;
} # }
} # }
# Watchtower # # Watchtower
server { # server {
listen 80; # listen 80;
listen [::]:80; # listen [::]:80;
listen 443 ssl; # listen 443 ssl;
listen [::]:443 ssl; # listen [::]:443 ssl;
server_name watchtower.apptabulous.co.uk; # server_name watchtower.apptabulous.co.uk;
ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem; # ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem; # ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem;
location / { # location / {
proxy_pass http://rpi4-2:8080; # proxy_pass http://rpi4-2:8080;
} # }
} # }
+8 -6
View File
@@ -1,7 +1,9 @@
# Stream the ssh connections for gitea # Stream the ssh connections for gitea
server { # The gitea container is running on the same machine as the reverse proxy for now,
listen 2222; # so we don't need to stream the ssh connection to another machine.
proxy_pass rpi5-2:2222; # the machine where sshd runs (often same as gitea) # server {
proxy_timeout 1h; # listen 2222;
proxy_connect_timeout 10s; # proxy_pass rpi5-2:2222; # the machine where sshd runs (often same as gitea)
} # proxy_timeout 1h;
# proxy_connect_timeout 10s;
# }
+206
View File
@@ -0,0 +1,206 @@
---
- name: Frontend setup
hosts: frontend-cockpit
vars:
username: matt
certbot_install_method: package
certbot_create_method: standalone
# certbot_install_method: source
# certbot_repo: https://github.com/certbot/certbot.git
# certbot_version: master
certbot_keep_updated: true
# certbot_dir: /opt/certbot
certbot_create_extra_args: "--http-01-port 8080"
certbot_auto_renew_user: "root"
certbot_auto_renew_hour: "3"
certbot_auto_renew_minute: "30"
certbot_create_if_missing: true
certbot_admin_email: matthew@thespencers.me.uk
certbot_certs:
- domains:
- "apptabulous.co.uk"
- "www.apptabulous.co.uk"
- "hub.apptabulous.co.uk"
- "watchtower.apptabulous.co.uk"
webroot: "/var/www/html"
- domains:
- "m5p3nc3r.co.uk"
- "www.m5p3nc3r.co.uk"
- "gitea.m5p3nc3r.co.uk"
webroot: "/var/www/html"
cockpit_plugins:
- cockpit-podman
cockpit_core_packages:
- cockpit
- cockpit-bridge
- cockpit-ws
- cockpit-ws-selinux
- cockpit-system
roles:
- role: geerlingguy.git
become: true
- role: geerlingguy.certbot
become: true
pre_tasks:
- name: Install python3-libdnf5 for DNF5 support on Fedora 41+
become: true
ansible.builtin.raw: dnf install -y python3-libdnf5
when: ansible_facts['os_family'] == 'RedHat'
changed_when: false
tasks:
- name: Reload systemd daemon
become: true
ansible.builtin.systemd:
daemon_reload: true
- name: Install Cockpit
include_role:
name: linux-system-roles.cockpit
apply:
become: true
vars:
# Prometheus is currently running on port 9090
cockpit_port: 9091
cockpit_packages: default
- name: Gather package facts
ansible.builtin.package_facts:
manager: auto
- name: Remove unwanted Cockpit plugins
become: true
ansible.builtin.package:
name: "{{ ansible_facts.packages | dict2items
| selectattr('key', 'match', '^cockpit-')
| map(attribute='key')
| reject('in', cockpit_plugins + cockpit_core_packages)
| list }}"
state: absent
when: >
ansible_facts.packages | dict2items
| selectattr('key', 'match', '^cockpit-')
| map(attribute='key')
| reject('in', cockpit_plugins + cockpit_core_packages)
| list | length > 0
- name: Install Podman
become: true
ansible.builtin.package:
name: podman
state: present
- name: Install Cockpit plugins
become: true
ansible.builtin.package:
name: "{{ cockpit_plugins }}"
state: present
- name: Grant {{ username }} read access to letsencrypt certificates
become: true
ansible.posix.acl:
path: /etc/letsencrypt
entity: "{{ username }}"
etype: user
permissions: rX
recursive: true
state: present
- name: Override default certbot start/stop jobs
become: true
ansible.builtin.copy:
src: letsencrypt
dest: /etc
- name: Copy reverse proxy configuration to host
become: true
ansible.builtin.copy:
src: apptabulous/reverseproxy
dest: /etc
- name: Create shared container network
containers.podman.podman_network:
name: webservices
state: present
- name: Start reverse proxy container
containers.podman.podman_container:
name: reverse_proxy
image: docker.io/library/nginx:alpine
restart_policy: always
network: webservices
volumes:
- /etc/reverseproxy/nginx.conf:/etc/nginx/nginx.conf
- /etc/reverseproxy/conf.d:/etc/nginx/conf.d
- /etc/reverseproxy/stream.d:/etc/nginx/stream.d
- /etc/letsencrypt:/etc/letsencrypt
ports:
- "8080:80"
- "8443:443"
state: started
# - name: Start docker registry
# community.docker.docker_container:
# name: registry
# image: registry:2
# restart_policy: always
# ports:
# - "5000:5000"
# state: started
- name: Log into ghcr.io registry
# become: true
containers.podman.podman_login:
registry: ghcr.io
username: "{{ secrets.GITHUB_ACTOR }}"
password: "{{ secrets.GITHUB_TOKEN }}"
- name: Open firewall ports for web services
become: true
ansible.posix.firewalld:
port: "{{ item }}/tcp"
permanent: true
state: enabled
immediate: true
loop:
- 8080
- 8443
- 2222
- name: Start m5p3nc3r website
containers.podman.podman_container:
name: website
image: ghcr.io/m5p3nc3r/website:main
restart_policy: always
network: webservices
label:
io.containers.autoupdate: registry
volumes:
- /home/matt/public/apps:/app/public/apps:Z
env:
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY: "{{ secrets.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY }}"
state: started
- name: Start Apptabulous website
containers.podman.podman_container:
name: apptabulous_website
image: ghcr.io/m5p3nc3r/apptabulous_website:main
restart_policy: always
network: webservices
label:
io.containers.autoupdate: registry
state: started
- name: Enable podman auto-update timer
become: true
ansible.builtin.systemd:
name: podman-auto-update.timer
enabled: true
state: started
-1
View File
@@ -62,7 +62,6 @@
community.docker.docker_container: community.docker.docker_container:
name: reverse_proxy name: reverse_proxy
image: nginx:alpine image: nginx:alpine
#image: ghcr.io/m5p3nc3r/nginx-keyval:main
restart_policy: always restart_policy: always
volumes: volumes:
- /etc/reverseproxy/nginx.conf:/etc/nginx/nginx.conf - /etc/reverseproxy/nginx.conf:/etc/nginx/nginx.conf
+51 -56
View File
@@ -1,5 +1,5 @@
--- ---
- name: Frontend setup - name: Gitea setup
hosts: gitea hosts: gitea
vars: vars:
@@ -17,59 +17,37 @@
local: "/mnt/gitea_backups" local: "/mnt/gitea_backups"
remote: "/var/nfs/shared/gitea_backups" remote: "/var/nfs/shared/gitea_backups"
docker_add_repo: true
docker_users:
- "{{ username }}"
roles:
- role: geerlingguy.git
become: true
- role: geerlingguy.docker
become: true
tasks: tasks:
- name: Create myapp directory in home - name: Install Podman
ansible.builtin.file: become: true
path: "{{ ansible_env.HOME }}/gitea" ansible.builtin.package:
state: directory name: podman
mode: "0755" state: present
- name: Copy the gitea compose file to the host - name: Allow containers to access NFS mounts
ansible.builtin.copy: become: true
src: gitea/compose.yaml ansible.posix.seboolean:
dest: "{{ ansible_env.HOME }}/gitea/compose.yaml" name: virt_use_nfs
state: true
# - name: Install NFS client persistent: true
# ansible.builtin.apt:
# name: nfs-common
# state: present
# update_cache: true
# become: true
- name: Stop gitea services if running
community.docker.docker_compose_v2:
project_src: "{{ ansible_env.HOME }}/gitea/"
state: absent
ignore_errors: true
- name: Unmount NFS volumes before creating mountpoint directories - name: Unmount NFS volumes before creating mountpoint directories
become: true
ansible.posix.mount: ansible.posix.mount:
path: "{{ item.value.local }}" path: "{{ item.value.local }}"
state: unmounted state: unmounted
loop: "{{ mounts | dict2items }}" loop: "{{ mounts | dict2items }}"
become: true
- name: Create mountpoint directories for gitea - name: Create mountpoint directories for gitea
become: true
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.value.local }}" path: "{{ item.value.local }}"
state: directory state: directory
mode: "0755" mode: "0755"
loop: "{{mounts | dict2items }}" loop: "{{ mounts | dict2items }}"
become: true
- name: Mount an NFS volume for repositories - name: Mount NFS volumes for gitea
become: true
ansible.posix.mount: ansible.posix.mount:
src: "192.168.1.160:{{ item.value.remote }}" src: "192.168.1.160:{{ item.value.remote }}"
path: "{{ item.value.local }}" path: "{{ item.value.local }}"
@@ -77,29 +55,46 @@
state: mounted state: mounted
fstype: nfs fstype: nfs
loop: "{{ mounts | dict2items }}" loop: "{{ mounts | dict2items }}"
- name: Open firewall ports for gitea
become: true become: true
ansible.posix.firewalld:
port: "{{ item }}/tcp"
permanent: true
state: enabled
immediate: true
loop:
- 3002
- 2222
- name: Create shared container network
- name: Create and start services containers.podman.podman_network:
community.docker.docker_compose_v2: name: webservices
project_src: "{{ ansible_env.HOME }}/gitea/"
state: present state: present
- name: Start watchtower - name: Start gitea
community.docker.docker_container: containers.podman.podman_container:
name: watchtower name: gitea
image: nickfedor/watchtower image: docker.io/gitea/gitea:latest
restart_policy: always restart_policy: always
network: webservices
label:
io.containers.autoupdate: registry
env:
USER_UID: "977"
USER_GID: "988"
TZ: Europe/London
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /mnt/gitea_data:/data:z
- /home/matt/.docker/config.json:/config.json - /mnt/gitea_repos:/data/git/repositories:z
command:
- --cleanup
- --http-api-update
- --http-api-token={{ secrets.WATCHTOWER_HTTP_API_TOKEN }}
- --http-api-periodic-polls
ports: ports:
- "8080:8080" - "3002:3000"
- "2222:22"
state: started state: started
- name: Enable podman auto-update timer
become: true
ansible.builtin.systemd:
name: podman-auto-update.timer
enabled: true
state: started
+5 -14
View File
@@ -11,23 +11,14 @@ services:
- TZ=Europe/London - TZ=Europe/London
volumes: volumes:
# Local: app.ini, database (sqlite by default), queues (LevelDB), sessions, etc. # NAS: configuration and repositories
# - gitea-data:/data-old - /mnt/gitea_data:/data:z
- /mnt/gitea_data:/data - /mnt/gitea_repos:/data/git/repositories:z
# NAS: only repositories (best practice)
- /mnt/gitea_repos:/data/git/repositories
# Optional: put LFS on NAS too # Optional: put LFS on NAS too
# - /mnt/gitea-lfs:/data/git/lfs # - /mnt/gitea-lfs:/data/git/lfs:z
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports: ports:
- "3000:3000" # Web - "3002:3000" # Web
- "2222:22" # SSH (container 22 -> host 2222) - "2222:22" # SSH (container 22 -> host 2222)
# volumes:
# gitea-data:
# driver: local
+8 -17
View File
@@ -4,7 +4,6 @@
vars: vars:
username: matt username: matt
docker_add_repo: true docker_add_repo: true
docker_users: docker_users:
- "{{ username }}" - "{{ username }}"
@@ -13,22 +12,14 @@
- role: geerlingguy.docker - role: geerlingguy.docker
become: true become: true
- role: compscidr.github_runner.github_runner tasks:
- name: Register GitHub runners
ansible.builtin.include_role:
name: compscidr.github_runner.github_runner
vars: vars:
github_runner_install_docker: false github_runner_install_docker: false
github_runner_personal_access_token: "{{ secrets.GITHUB_ACTIONS_TOKEN }}" github_runner_personal_access_token: "{{ secrets.GITHUB_ACTIONS_TOKEN }}"
github_runner_name: "aarch64-rpi5-runner" github_runner_name: "{{ item.name }}"
github_runner_repo: "m5p3nc3r/website" github_runner_repo: "{{ item.repo }}"
github_runner_lables: "aarch64, rpi5" github_runner_labels: "{{ item.labels }}"
loop: "{{ runner_configs }}"
tasks:
- name: Start watchtower
community.docker.docker_container:
name: watchtower
image: containrrr/watchtower
restart_policy: always
command:
- --cleanup
volumes:
- /var/run/docker.sock:/var/run/docker.sock
state: started
+5
View File
@@ -0,0 +1,5 @@
---
runner_configs:
- name: aarch64-rpi5-runner
repo: m5p3nc3r/website
labels: "aarch64,rpi5"
+8
View File
@@ -0,0 +1,8 @@
---
runner_configs:
- name: amd64-ryzen7-runner
repo: m5p3nc3r/website
labels: "amd64,x86_64,ryzen7"
- name: arm64-ryzen7-runner
repo: m5p3nc3r/website
labels: "arm64,aarch64,ryzen7"
+12 -5
View File
@@ -1,13 +1,15 @@
all: all:
hosts: hosts:
rpi4-1: # rpi4-1:
ansible_host: rpi4-1.local # ansible_host: rpi4-1.local
rpi4-2: rpi4-2:
ansible_host: rpi4-2.local ansible_host: rpi4-2.local
rpi5-1: rpi5-1:
ansible_host: rpi5-1.local ansible_host: rpi5-1.local
rpi5-2: rpi5-2:
ansible_host: rpi5-2.local ansible_host: rpi5-2.local
ryzen7:
ansible_host: ryzen7
children: children:
monitored: monitored:
hosts: hosts:
@@ -19,13 +21,18 @@ all:
rpi4-2: {} rpi4-2: {}
frontend: frontend:
hosts: hosts:
rpi4-1: {} rpi4-2: {}
frontend-cockpit:
hosts:
ryzen7: {}
github-runners: github-runners:
hosts: hosts:
rpi5-1: {} # rpi5-2: {}
ryzen7: {}
gitea: gitea:
hosts: hosts:
rpi5-2: {} # rpi5-2: {}
ryzen7: {}
apt-cacher-ng: apt-cacher-ng:
hosts: hosts:
rpi4-2: {} rpi4-2: {}
+7 -1
View File
@@ -1,10 +1,16 @@
--- ---
collections: collections:
- community.docker - community.docker
- community.general
- ansible.posix
- containers.podman
- compscidr.github_runner - compscidr.github_runner
roles: roles:
- geerlingguy.certbot - name: geerlingguy.certbot
src: https://github.com/geerlingguy/ansible-role-certbot
version: master
- geerlingguy.git - geerlingguy.git
- geerlingguy.nginx - geerlingguy.nginx
- geerlingguy.docker - geerlingguy.docker
- linux-system-roles.cockpit