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
# install roles and collections
ansible-galaxy install -r requirements.yml
# 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
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
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
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
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
@@ -22,7 +22,7 @@ server {
}
location / {
proxy_pass http://rpi4-2:3000;
proxy_pass http://website:3000;
}
}
@@ -42,7 +42,7 @@ server {
# }
location / {
proxy_pass http://rpi5-2:3000;
proxy_pass http://gitea:3000;
}
}
@@ -62,44 +62,44 @@ server {
}
location / {
proxy_pass http://rpi4-2:3001;
proxy_pass http://apptabulous_website:3000;
}
}
# Container registry
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name hub.apptabulous.co.uk;
# server {
# listen 80;
# listen [::]:80;
# listen 443 ssl;
# listen [::]:443 ssl;
# server_name hub.apptabulous.co.uk;
ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem;
# ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# # disable any limits to avoid HTTP 413 for large image uploads
# client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on;
# # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
# chunked_transfer_encoding on;
location / {
proxy_pass http://rpi4-2:5000;
}
}
# location / {
# proxy_pass http://rpi4-2:5000;
# }
# }
# Watchtower
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name watchtower.apptabulous.co.uk;
# # Watchtower
# server {
# listen 80;
# listen [::]:80;
# listen 443 ssl;
# listen [::]:443 ssl;
# server_name watchtower.apptabulous.co.uk;
ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem;
# ssl_certificate /etc/letsencrypt/live/apptabulous.co.uk/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/apptabulous.co.uk/privkey.pem;
location / {
proxy_pass http://rpi4-2:8080;
}
}
# location / {
# proxy_pass http://rpi4-2:8080;
# }
# }
+8 -6
View File
@@ -1,7 +1,9 @@
# Stream the ssh connections for gitea
server {
listen 2222;
proxy_pass rpi5-2:2222; # the machine where sshd runs (often same as gitea)
proxy_timeout 1h;
proxy_connect_timeout 10s;
}
# The gitea container is running on the same machine as the reverse proxy for now,
# so we don't need to stream the ssh connection to another machine.
# server {
# listen 2222;
# 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:
name: reverse_proxy
image: nginx:alpine
#image: ghcr.io/m5p3nc3r/nginx-keyval:main
restart_policy: always
volumes:
- /etc/reverseproxy/nginx.conf:/etc/nginx/nginx.conf
+50 -55
View File
@@ -1,5 +1,5 @@
---
- name: Frontend setup
- name: Gitea setup
hosts: gitea
vars:
@@ -17,59 +17,37 @@
local: "/mnt/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:
- name: Create myapp directory in home
ansible.builtin.file:
path: "{{ ansible_env.HOME }}/gitea"
state: directory
mode: "0755"
- name: Install Podman
become: true
ansible.builtin.package:
name: podman
state: present
- name: Copy the gitea compose file to the host
ansible.builtin.copy:
src: gitea/compose.yaml
dest: "{{ ansible_env.HOME }}/gitea/compose.yaml"
# - name: Install NFS client
# 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: Allow containers to access NFS mounts
become: true
ansible.posix.seboolean:
name: virt_use_nfs
state: true
persistent: true
- name: Unmount NFS volumes before creating mountpoint directories
become: true
ansible.posix.mount:
path: "{{ item.value.local }}"
state: unmounted
loop: "{{ mounts | dict2items }}"
become: true
- name: Create mountpoint directories for gitea
become: true
ansible.builtin.file:
path: "{{ item.value.local }}"
state: directory
mode: "0755"
loop: "{{ mounts | dict2items }}"
become: true
- name: Mount an NFS volume for repositories
- name: Mount NFS volumes for gitea
become: true
ansible.posix.mount:
src: "192.168.1.160:{{ item.value.remote }}"
path: "{{ item.value.local }}"
@@ -77,29 +55,46 @@
state: mounted
fstype: nfs
loop: "{{ mounts | dict2items }}"
- name: Open firewall ports for gitea
become: true
ansible.posix.firewalld:
port: "{{ item }}/tcp"
permanent: true
state: enabled
immediate: true
loop:
- 3002
- 2222
- name: Create and start services
community.docker.docker_compose_v2:
project_src: "{{ ansible_env.HOME }}/gitea/"
- name: Create shared container network
containers.podman.podman_network:
name: webservices
state: present
- name: Start watchtower
community.docker.docker_container:
name: watchtower
image: nickfedor/watchtower
- name: Start gitea
containers.podman.podman_container:
name: gitea
image: docker.io/gitea/gitea:latest
restart_policy: always
network: webservices
label:
io.containers.autoupdate: registry
env:
USER_UID: "977"
USER_GID: "988"
TZ: Europe/London
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/matt/.docker/config.json:/config.json
command:
- --cleanup
- --http-api-update
- --http-api-token={{ secrets.WATCHTOWER_HTTP_API_TOKEN }}
- --http-api-periodic-polls
- /mnt/gitea_data:/data:z
- /mnt/gitea_repos:/data/git/repositories:z
ports:
- "8080:8080"
- "3002:3000"
- "2222:22"
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
volumes:
# Local: app.ini, database (sqlite by default), queues (LevelDB), sessions, etc.
# - gitea-data:/data-old
- /mnt/gitea_data:/data
# NAS: only repositories (best practice)
- /mnt/gitea_repos:/data/git/repositories
# NAS: configuration and repositories
- /mnt/gitea_data:/data:z
- /mnt/gitea_repos:/data/git/repositories:z
# 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:
- "3000:3000" # Web
- "3002:3000" # Web
- "2222:22" # SSH (container 22 -> host 2222)
# volumes:
# gitea-data:
# driver: local
+8 -17
View File
@@ -4,7 +4,6 @@
vars:
username: matt
docker_add_repo: true
docker_users:
- "{{ username }}"
@@ -13,22 +12,14 @@
- role: geerlingguy.docker
become: true
- role: compscidr.github_runner.github_runner
tasks:
- name: Register GitHub runners
ansible.builtin.include_role:
name: compscidr.github_runner.github_runner
vars:
github_runner_install_docker: false
github_runner_personal_access_token: "{{ secrets.GITHUB_ACTIONS_TOKEN }}"
github_runner_name: "aarch64-rpi5-runner"
github_runner_repo: "m5p3nc3r/website"
github_runner_lables: "aarch64, rpi5"
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
github_runner_name: "{{ item.name }}"
github_runner_repo: "{{ item.repo }}"
github_runner_labels: "{{ item.labels }}"
loop: "{{ runner_configs }}"
+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:
hosts:
rpi4-1:
ansible_host: rpi4-1.local
# rpi4-1:
# ansible_host: rpi4-1.local
rpi4-2:
ansible_host: rpi4-2.local
rpi5-1:
ansible_host: rpi5-1.local
rpi5-2:
ansible_host: rpi5-2.local
ryzen7:
ansible_host: ryzen7
children:
monitored:
hosts:
@@ -19,13 +21,18 @@ all:
rpi4-2: {}
frontend:
hosts:
rpi4-1: {}
rpi4-2: {}
frontend-cockpit:
hosts:
ryzen7: {}
github-runners:
hosts:
rpi5-1: {}
# rpi5-2: {}
ryzen7: {}
gitea:
hosts:
rpi5-2: {}
# rpi5-2: {}
ryzen7: {}
apt-cacher-ng:
hosts:
rpi4-2: {}
+7 -1
View File
@@ -1,10 +1,16 @@
---
collections:
- community.docker
- community.general
- ansible.posix
- containers.podman
- compscidr.github_runner
roles:
- geerlingguy.certbot
- name: geerlingguy.certbot
src: https://github.com/geerlingguy/ansible-role-certbot
version: master
- geerlingguy.git
- geerlingguy.nginx
- geerlingguy.docker
- linux-system-roles.cockpit