feat: activate Rocky server profile for prometheus

This commit is contained in:
Fabio Scotto di Santolo
2026-09-07 23:52:56 +02:00
parent e0a81d6a70
commit 4dd3d65267
16 changed files with 85 additions and 273 deletions

View File

@@ -1,7 +1,7 @@
# AGENTS.md
Ansible-driven personal infrastructure repo for Fedora and Void desktops, FreeBSD transition targets,
WSL, an Ubuntu server, and a dormant Rocky Linux 9 server profile.
WSL, a Rocky Linux 9 server, and an Atlas NAS.
## Source Of Truth
- Main orchestration: `ansible/site.yml`
@@ -16,8 +16,7 @@ WSL, an Ubuntu server, and a dormant Rocky Linux 9 server profile.
- Current laptop: `nymph = platform_fedora + graphical_desktop + desktop_gnome`
- Void desktop profile is also the base for other future/reference hosts via `platform_void + graphical_desktop`
- Workstation: `deadalus` is Windows + Fedora WSL.
- Ubuntu server: `prometheus`
- Dormant Rocky server: `rocky_server` is empty until a migration target is explicitly assigned.
- Rocky server: `prometheus` belongs to `rocky_server`.
- NAS: `atlas` (Rocky Linux 9, reached through SSH)
- Hosts intentionally belong to multiple groups; trust `ansible/site.yml` over hostname assumptions.
- Inventory axes are independent: `platform_*`, `role_*`, and `desktop_*`. Legacy `void` and `desktop` remain compatibility parents.
@@ -81,7 +80,7 @@ The Void desktop package lists in `ansible/inventory/group_vars/void.yml` are ke
- `desktop_common_packages` — GUI infrastructure shared by the minimal desktop mode.
- `desktop_minimal_packages` — applications, integration components, and the `emptty` display manager.
- `desktop_sway_packages` — binaries specific to the Sway session.
`profile_packages` remains the shared package bucket for Void, Fedora, and Ubuntu profiles. Rocky uses
`profile_packages` remains the shared package bucket for Void and Fedora profiles. Rocky uses
`rocky_profile_packages` so RPM-specific names do not leak back into the other platforms; do not move
desktop-specific Void entries through either bucket.
The dotfile vars follow the same split: `desktop_common_dotfiles` carries mode-independent content and `desktop_minimal_dotfiles` carries Thunar, Udiskie, and MIME defaults. `desktop_void_dotfiles` remains reserved for files that need the Void runtime.
@@ -93,15 +92,12 @@ The dotfile vars follow the same split: `desktop_common_dotfiles` carries mode-i
- Windows applications are installed manually and are not managed from the WSL profile.
## Rocky Server Notes
- `rocky_server` is an empty child of both `platform_rocky` and `server`; it must stay empty until a
real migration target is ready.
- The active `prometheus` host remains in `ubuntu_server`. Never place the same inventory host in both
`ubuntu_server` and `rocky_server`; use a distinct name while testing a parallel replacement.
- `rocky_server` is a child of both `platform_rocky` and `server`; `prometheus` is its active target.
- The target must already provide `server_username` with local sudo access before the profile runs.
- The Rocky profile installs Docker CE, uses firewalld, preserves SELinux enforcement, and renders the
same server Compose stack. It does not transfer data, start containers, update DNS, or cut over traffic.
- Atlas-only OpenZFS, NFS, Samba, Cockpit, and native Syncthing packages stay selected through Atlas
host variables and must not leak into `rocky_server`.
- Atlas-only OpenZFS, NFS, Samba, Cockpit, and Syncthing stay selected through Atlas host variables
and must not leak into `rocky_server`.
## Atlas NAS Notes
- `atlas` is a remote Rocky Linux 9 NAS. Keep its connection, LAN, pool and mountpoint values in

View File

@@ -33,7 +33,6 @@ infra/
│ ├── common/
│ ├── desktop/
│ ├── fedora/
│ ├── ubuntu/
│ ├── server/
│ ├── workstation/
│ ├── workstation_dev_wsl/
@@ -56,8 +55,8 @@ Il repository è diviso in due componenti principali:
# Macchine gestite
Il repository modella attualmente host Fedora/GNOME, una workstation Fedora WSL, un server Ubuntu e
un NAS Rocky Linux 9. La composizione resta separata in assi indipendenti:
Il repository modella attualmente host Fedora/GNOME, una workstation Fedora WSL, un server Rocky
Linux 9 e un NAS Rocky Linux 9. La composizione resta separata in assi indipendenti:
```text
common user environment
@@ -74,7 +73,7 @@ Matrice target:
| ikaros | Fedora | Personal workstation | GNOME |
| nymph | Fedora | Desktop laptop | GNOME |
| deadalus | Fedora WSL | Workstation dev | — |
| prometheus | Ubuntu | Server | — |
| prometheus | Rocky 9 | Server | — |
| atlas | Rocky 9 | NAS | — |
Regola operativa:
@@ -93,7 +92,7 @@ Nota sullo stato attuale del playbook principale:
- `ansible/site.yml` applica oggi in automatico Fedora/GNOME su `ikaros` e `nymph`
- `ansible/site.yml` applica il profilo Fedora WSL alla workstation `deadalus`
- `ansible/site.yml` applica anche il profilo `ubuntu_server` con baseline apt, systemd, dotfiles server e firewall UFW
- `ansible/site.yml` applica il profilo server Rocky a `prometheus` con DNF, systemd, dotfiles server e firewalld
- `ansible/site.yml` applica il profilo NAS Rocky su `atlas` tramite SSH remoto
## Desktop
@@ -164,7 +163,7 @@ Le applicazioni Windows sono installate e gestite manualmente; il profilo WSL no
Sistema operativo:
- Ubuntu LTS
- Rocky Linux 9
Configurazione:
@@ -178,12 +177,12 @@ Profilo orientato a servizi server e gestione di dotfiles dedicati.
Lo stato attuale del profilo server include:
- installazione pacchetti base Ubuntu via apt
- installazione pacchetti Rocky via DNF, EPEL e CRB
- installazione e configurazione di Docker dal repository ufficiale
- abilitazione dei servizi systemd dichiarati in inventory/group vars
- copia dei dotfiles server e rendering dei template server, incluso il `docker-compose.yml` dello stack servizi
- attivazione del firewall UFW con regola SSH esplicita
- apertura delle porte Syncthing `22000/tcp`, `22000/udp` e `21027/udp`, lasciando la GUI non esposta direttamente su UFW
- attivazione di firewalld con servizio SSH esplicitamente abilitato
- Syncthing escluso dal profilo server Rocky
Utente del profilo server:
@@ -275,7 +274,6 @@ I principali ruoli attualmente presenti sono:
| base | configurazione base comune |
| packages_void | installazione pacchetti su Void |
| packages_freebsd | installazione pacchetti su FreeBSD via pkg |
| packages_ubuntu | installazione pacchetti su Ubuntu |
| packages_fedora | installazione pacchetti su Fedora |
| packages_rocky | installazione pacchetti su Rocky Linux 9 |
| services_runit | gestione servizi runit |
@@ -312,7 +310,7 @@ platform_fedora & role_personal_workstation -> profile_personal_workstation
platform_fedora & desktop_gnome -> profile_desktop_gnome
workstation_dev_fedora -> profile_workstation_dev_common
workstation_dev_wsl -> profile_workstation_dev_wsl (dopo platform_fedora + workstation_dev_fedora)
ubuntu_server -> packages_ubuntu + services_systemd + profile_server
rocky_server -> dotfiles_common + profile_server (dopo platform_rocky)
```
Questo significa che, allo stato attuale:
@@ -321,9 +319,9 @@ Questo significa che, allo stato attuale:
- `nymph` riceve Fedora Workstation/GNOME come target laptop
- il profilo Void resta selezionabile tramite `platform_void + graphical_desktop` per host futuri
- `deadalus` riceve il profilo Fedora WSL tramite play dev dedicati
- il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall
- il server Rocky (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewalld
- il NAS Rocky (`atlas`) usa un pool ZFS gia esistente, condivisioni NFSv4/SMB limitate alla LAN e Cockpit/45Drives
- lo stack container server include `navidrome`, `postgres`, `gitea`, `nginx-proxy-manager` e `syncthing`, con GUI Syncthing raggiungibile tramite la rete Docker `web`
- lo stack container server include `navidrome`, `postgres`, `gitea` e `nginx-proxy-manager`
# Dotfiles
@@ -335,7 +333,6 @@ dotfiles/
├── desktop
├── server
├── fedora
├── ubuntu
├── workstation
├── workstation_dev_wsl
└── nymph
@@ -398,8 +395,7 @@ Allo stato attuale questo comando:
- per `platform_fedora & role_personal_workstation` applica il layer personale a `ikaros`
- per `platform_fedora & desktop_gnome` applica il profilo GNOME a `ikaros` e `nymph`
- per `workstation_dev_wsl` applica i tweak WSL dopo il layer Fedora a `deadalus`, escludendo Flatpak e Snap
- per gli host `ubuntu_server` applica pacchetti Ubuntu, servizi systemd, profilo server, UFW, dotfiles e template dedicati
- per `platform_rocky` applica pacchetti Rocky e servizi systemd ad `atlas`, quindi il profilo NAS dedicato
- per `platform_rocky` applica pacchetti Rocky e servizi systemd ad `atlas` e `prometheus`; quindi applica il profilo NAS ad `atlas` e il profilo server a `prometheus`
- non riavvia automaticamente il display manager
- carica `secrets/vault.yml` solo se presente
- carica `secrets/vault.local.yml` solo se presente, dopo `vault.yml`, cosi gli override locali hanno precedenza

View File

@@ -20,7 +20,6 @@ infra/
│ ├── common/
│ ├── desktop/
│ ├── fedora/
│ ├── ubuntu/
│ ├── server/
│ ├── workstation/
│ ├── workstation_dev_wsl/
@@ -36,8 +35,8 @@ infra/
## Managed machines
The repo currently covers Fedora/GNOME desktops, one Fedora WSL workstation, an Ubuntu server, a
dormant Rocky Linux 9 server profile, and a Rocky Linux 9 NAS. Configuration is layered instead of
The repo currently covers Fedora/GNOME desktops, one Fedora WSL workstation, a Rocky Linux 9 server,
and a Rocky Linux 9 NAS. Configuration is layered instead of
being tied to host names:
```text
@@ -53,8 +52,7 @@ common user environment
| `ikaros` | Fedora | Personal workstation | GNOME |
| `nymph` | Fedora | Desktop laptop | GNOME |
| `deadalus` | Fedora WSL | Development workstation | — |
| `prometheus` | Ubuntu | Server | — |
| — (`rocky_server`, dormant) | Rocky 9 | Server | — |
| `prometheus` | Rocky 9 | Server | — |
| `atlas` | Rocky 9 | NAS | — |
```text
@@ -101,15 +99,14 @@ That gives it Fedora packages through DNF, Docker from the official repository,
## Server
`prometheus` is the Ubuntu LTS server. It has no graphical environment and gets server-specific
dotfiles and templates. `rocky_server` is the empty alternative profile for a future Rocky Linux 9
migration; it does not select any host until one is explicitly added to that inventory group.
`prometheus` is the Rocky Linux 9 server. It has no graphical environment and gets server-specific
dotfiles and templates. The profile provisions configuration only: it does not transfer data, start
the Compose stack, update DNS, or perform a cutover.
The server profile installs platform-specific packages, Docker CE from the official repository,
declared systemd services, the server Compose stack, and either UFW on Ubuntu or firewalld on Rocky.
Syncthing ports `22000/tcp`, `22000/udp`, and `21027/udp` are opened; the Syncthing GUI is not
directly exposed by the managed firewall rules. Rocky bind mounts use private SELinux relabeling for
application data while host system files remain unchanged.
declared systemd services, the server Compose stack, and firewalld. The Rocky server excludes
Syncthing. Rocky bind mounts use private SELinux relabeling for application data while host system
files remain unchanged.
Server identity comes from `server_username`, `server_user_group`, and `server_user_home` in `ansible/inventory/group_vars/server.yml`. `server_username` defaults to `username`, but it can be overridden, for example:
@@ -120,11 +117,7 @@ ansible-playbook ansible/site.yml --limit prometheus \
-e server_user_home=/srv/myuser
```
The dormant profile provisions configuration only: it does not transfer data, start the Compose
stack, update DNS, or perform a cutover. During migration, add the replacement machine to
`rocky_server` under a distinct inventory name after creating `server_username` with local sudo
access. When reusing `prometheus` at cutover, remove it from `ubuntu_server` before adding it to
`rocky_server`; a host must never belong to both platform groups.
The target must already provide `server_username` with local sudo access.
## NAS
@@ -222,7 +215,6 @@ ansible-playbook ansible/site.yml --limit deadalus --tags ai_agents --check --di
| --- | --- |
| `packages_void` | Installs packages on Void. |
| `packages_freebsd` | Installs packages on FreeBSD with pkg. |
| `packages_ubuntu` | Installs packages on Ubuntu. |
| `packages_fedora` | Installs packages on Fedora. |
| `packages_rocky` | Installs packages on Rocky Linux 9. |
| `services_runit` | Manages runit services. |
@@ -255,17 +247,15 @@ platform_fedora & role_personal_workstation -> profile_personal_workstation
platform_fedora & desktop_gnome -> profile_desktop_gnome
workstation_dev_fedora -> profile_workstation_dev_common
workstation_dev_wsl -> profile_workstation_dev_wsl (after platform_fedora + workstation_dev_fedora)
ubuntu_server -> packages_ubuntu + services_systemd + profile_server
```
So, in practice:
- `platform_fedora` configures `ikaros`, `nymph`, and `deadalus`.
- `deadalus` gets the Fedora development layer followed by the WSL layer.
- `ubuntu_server` configures `prometheus`.
- Empty `rocky_server` defines the Rocky 9 server alternative without targeting a machine.
- `rocky_server` configures the Rocky 9 server, `prometheus`.
- `atlas` receives the Rocky platform layer and the NAS profile through SSH.
- Empty `platform_void`, `platform_freebsd`, and `rocky_server` groups do nothing until they get a host.
- Empty `platform_void` and `platform_freebsd` groups do nothing until they get a host.
- The playbook never restarts the display manager during a run.
- `secrets/vault.yml` and then `secrets/vault.local.yml` are loaded only when present.

View File

@@ -32,6 +32,7 @@ enabled_services:
rocky_common_packages:
- bash-completion
- bat
- entr
- fzf
- git
- jq

View File

@@ -49,9 +49,11 @@ server_firewall_backend: firewalld
server_firewalld_zone: public
server_firewalld_services:
- ssh
server_firewalld_ports:
server_firewalld_ports: []
server_firewalld_absent_ports:
- 22000/tcp
- 22000/udp
- 21027/udp
server_sshd_service_name: sshd
server_compose_selinux_mount_option: Z
server_syncthing_enabled: false

View File

@@ -25,6 +25,9 @@ profile_packages:
- rsync
server_dotfiles:
- src: .bashrc.d/20-editor-server.sh
dest: .bashrc.d/20-editor-server.sh
mode: "0644"
- src: .gnupg/gpg-agent.conf
dest: .gnupg/gpg-agent.conf
mode: "0600"
@@ -50,6 +53,10 @@ server_templates:
no_log: true
server_directories:
- path: "{{ server_user_home }}/.bashrc.d"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
mode: "0755"
- path: "{{ server_user_home }}/.gnupg"
owner: "{{ server_username }}"
group: "{{ server_user_group }}"
@@ -82,6 +89,17 @@ server_directories:
owner: root
group: root
mode: "0755"
- path: /srv/nextcloud
owner: root
group: root
mode: "0755"
- path: /srv/nextcloud/data
owner: root
group: root
mode: "0755"
server_syncthing_enabled: true
server_syncthing_directories:
- path: /opt/syncthing/config
owner: root
group: root
@@ -94,30 +112,6 @@ server_directories:
owner: "1000"
group: "1000"
mode: "0755"
- path: /srv/nextcloud
owner: root
group: root
mode: "0755"
- path: /srv/nextcloud/data
owner: root
group: root
mode: "0755"
server_ufw_rules:
- rule: allow
name: OpenSSH
- rule: allow
port: "22000"
proto: tcp
comment: Syncthing sync traffic
- rule: allow
port: "22000"
proto: udp
comment: Syncthing QUIC sync traffic
- rule: allow
port: "21027"
proto: udp
comment: Syncthing local discovery
server_sshd_settings:
PermitRootLogin: "no"

View File

@@ -1,41 +0,0 @@
---
ubuntu_packages_base:
- curl
- ufw
- htop
- build-essential
- nodejs
- git-delta
- jq
- ripgrep
ubuntu_manage_docker_repo: true
ubuntu_emacs_packages:
- emacs
- pandoc
- latexmk
- texlive-luatex
- texlive-latex-base
- texlive-latex-recommended
- texlive-fonts-recommended
ubuntu_docker_packages:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
enabled_services:
- ufw
- docker
server_firewall_backend: ufw
server_sshd_service_name: ssh
server_compose_selinux_mount_option: ""
ubuntu_dotfiles:
- src: .bashrc.d/
dest: .bashrc.d/
mode: preserve

View File

@@ -1,5 +1,8 @@
---
hostname: prometheus
ansible_host: 179.237.102.172
ansible_user: rocky
ansible_port: 22
ansible_ssh_private_key_file: /home/fscotto/.ssh/id_ed25519
host_packages: []
host_enabled_services: []
server_username: rocky

View File

@@ -63,10 +63,6 @@ all:
nymph:
ansible_connection: local
ubuntu:
children:
ubuntu_server:
workstation:
children:
workstation_dev:
@@ -79,7 +75,6 @@ all:
server:
children:
rocky_server:
ubuntu_server:
workstation_dev_fedora:
hosts:
@@ -91,10 +86,6 @@ all:
deadalus:
ansible_connection: local
ubuntu_server:
rocky_server:
hosts:
prometheus:
ansible_connection: local
rocky_server:
hosts: {}

View File

@@ -1,82 +0,0 @@
---
- name: Copy Ubuntu dotfiles
tags: [dotfiles, dotfiles:common]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/ubuntu/{{ item.src }}"
dest: "{{ effective_user_home }}/{{ item.dest }}"
owner: "{{ effective_username }}"
group: "{{ effective_user_group }}"
mode: "{{ item.mode }}"
loop: "{{ ubuntu_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
- name: Ensure Docker apt keyrings directory exists
tags: [packages]
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
owner: root
group: root
mode: "0755"
when: ubuntu_manage_docker_repo | default(false)
- name: Download Docker apt repository signing key
tags: [packages]
ansible.builtin.get_url:
url: https://download.docker.com/linux/ubuntu/gpg
dest: /etc/apt/keyrings/docker.asc
owner: root
group: root
mode: "0644"
when: ubuntu_manage_docker_repo | default(false)
- name: Configure Docker apt repository
tags: [packages]
ansible.builtin.apt_repository:
repo: >-
deb [arch={{ 'amd64' if ansible_facts['architecture'] == 'x86_64'
else 'arm64' if ansible_facts['architecture'] in ['aarch64', 'arm64']
else ansible_facts['architecture'] }}
signed-by=/etc/apt/keyrings/docker.asc]
https://download.docker.com/linux/ubuntu
{{ ansible_facts['distribution_release'] }} stable
filename: docker
state: present
update_cache: true
when: ubuntu_manage_docker_repo | default(false)
- name: Refresh apt package cache
tags: [packages]
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Install packages on Ubuntu
tags: [packages]
ansible.builtin.apt:
name: >-
{{
(
(common_packages | default([]))
+ (ubuntu_packages_base | default([]))
+ (ubuntu_docker_packages | default([]))
+ (profile_packages | default([]))
+ (
(ubuntu_emacs_packages | default([]))
if (emacs_enabled | default(false) | bool)
else []
)
+ (host_packages | default([]))
)
| unique
}}
state: present
- name: Add user to docker group
tags: [packages]
ansible.builtin.user:
name: "{{ effective_username }}"
groups: docker
append: true
when: (ubuntu_docker_packages | default([])) | length > 0

View File

@@ -4,9 +4,9 @@
tags: [services, packages]
ansible.builtin.assert:
that:
- server_firewall_backend in ['ufw', 'firewalld']
- server_firewall_backend == 'firewalld'
fail_msg: >-
server_firewall_backend must be either ufw or firewalld for the server profile.
server_firewall_backend must be firewalld for the Rocky server profile.
- name: Copy server dotfiles
tags: [dotfiles, dotfiles:server]
@@ -38,7 +38,15 @@
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
loop: "{{ server_directories | default([]) }}"
loop: >-
{{
(server_directories | default([]))
+ (
server_syncthing_directories | default([])
if server_syncthing_enabled | default(true) | bool
else []
)
}}
loop_control:
label: "{{ item.path }}"
@@ -76,41 +84,6 @@
notify: Reload SSH service
when: (server_sshd_allow_users | default([])) | length > 0
- name: Define effective server UFW rules
tags: [services, packages]
ansible.builtin.set_fact:
server_ufw_rules_effective: "{{ server_ufw_rules | default([]) }}"
when: server_firewall_backend == 'ufw'
- name: Apply server UFW rules
tags: [services, packages]
community.general.ufw:
rule: "{{ item.rule }}"
name: "{{ item.name | default(omit) }}"
port: "{{ item.port | default(omit) }}"
proto: "{{ item.proto | default(omit) }}"
from_ip: "{{ item.src | default(omit) }}"
to_ip: "{{ item.dest | default(omit) }}"
from_port: "{{ item.from_port | default(omit) }}"
direction: "{{ item.direction | default(omit) }}"
interface: "{{ item.interface | default(omit) }}"
interface_in: "{{ item.interface_in | default(omit) }}"
interface_out: "{{ item.interface_out | default(omit) }}"
route: "{{ item.route | default(omit) }}"
comment: "{{ item.comment | default(omit) }}"
loop: "{{ server_ufw_rules_effective | default([]) }}"
loop_control:
label: "{{ item.name | default(item.port) }}"
when: server_firewall_backend == 'ufw'
- name: Enable UFW firewall on server
tags: [services, packages]
community.general.ufw:
state: enabled
when:
- server_firewall_backend == 'ufw'
- (server_ufw_rules_effective | default([])) | length > 0
- name: Allow server services through firewalld
tags: [services, packages]
ansible.posix.firewalld:
@@ -136,3 +109,16 @@
loop_control:
label: "{{ item }}"
when: server_firewall_backend == 'firewalld'
- name: Remove disabled server ports from firewalld
tags: [services, packages]
ansible.posix.firewalld:
port: "{{ item }}"
zone: "{{ server_firewalld_zone }}"
state: disabled
permanent: true
immediate: true
loop: "{{ server_firewalld_absent_ports | default([]) }}"
loop_control:
label: "{{ item }}"
when: server_firewall_backend == 'firewalld'

View File

@@ -119,12 +119,3 @@
roles:
- profile_workstation_dev_wsl
- name: Configure Ubuntu server
hosts: ubuntu_server
become: true
roles:
- packages_ubuntu
- services_systemd
- profile_server

View File

@@ -88,6 +88,7 @@ services:
- "3000:3000"
- "127.0.0.1:222:22"
{% if server_syncthing_enabled | default(true) | bool %}
syncthing:
image: syncthing/syncthing:2
container_name: syncthing
@@ -104,6 +105,7 @@ services:
- "21027:21027/udp"
networks:
- web
{% endif %}
networks:
web:

View File

@@ -1,5 +1,5 @@
# Server
- Ubuntu minimal server
- Rocky Linux 9 server
- Self-hosting services
- Low attack surface

View File

@@ -1,17 +0,0 @@
case "$(uname -r 2>/dev/null)" in
*[Mm]icrosoft*) ;;
*) return ;;
esac
command -v gpgconf >/dev/null 2>&1 || return
if tty -s; then
export GPG_TTY="$(tty)"
fi
gpgconf --launch gpg-agent >/dev/null 2>&1
export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
if [ -n "${GPG_TTY-}" ]; then
gpg-connect-agent updatestartuptty /bye >/dev/null 2>&1
fi