Add matrix to stack

This commit is contained in:
drew 2026-05-06 00:56:22 -04:00
parent c482d75d5f
commit 04795554b7
16 changed files with 400 additions and 2 deletions

View File

@ -43,4 +43,13 @@
- base_os - base_os
- firewall_base - firewall_base
- container_runtime - container_runtime
- selinux_containers - selinux_containers
- name: Matrix
hosts: matrix
become: true
roles:
- base_os
- firewall_base
- container_runtime
- matrix_synapse

View File

@ -0,0 +1,4 @@
---
# coturn/meta/main.yml
dependencies:
- role: selinux_containers

View File

@ -0,0 +1,11 @@
---
# coturn/tasks/firewall.yml
- name: Open required firewall rules
become: true
ansible.posix.firewalld:
port: "{{ item.port | default(omit) }}"
service: "{{ item.service | default(omit) }}"
permanent: true
state: enabled
immediate: true
loop: "{{ coturn_firewall_rules }}"

View File

@ -0,0 +1,68 @@
---
# coturn/tasks/main.yml
- import_tasks: firewall.yml
- name: Create stack and config directories
file:
path: "{{ item }}"
state: directory
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: "0755"
recurse: yes
loop: "{{ coturn_base_directories }}"
- name: Directory SELinux requirement
ansible.builtin.set_fact:
selinux_container_paths: "{{ coturn_base_directories }}"
- import_role:
name: selinux_containers
tasks_from: labels
- name: Ensure container app config directories are owned by container UID
become: true
file:
path: "{{ coturn_dir }}/conf"
state: directory
owner: "{{ container_user }}"
group: "{{ container_group }}"
recurse: true
- name: Deploy Turnserver configuration template
template:
src: turnserver.conf.j2
dest: "{{ coturn_config_dir }}/turnserver.conf"
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: '0600'
- name: Deploy Coturn Quadlet
template:
src: coturn.container.j2
dest: "{{ container_config_dir }}/coturn.container"
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: '0644'
- name: Force systemd reload (blocking)
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
command: systemctl --user daemon-reload
- name: Wait for quadlet generation
pause:
seconds: 1
- name: Start and enable Coturn service
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
systemd:
name: coturn.service
scope: user
state: started
enabled: true

View File

@ -0,0 +1,17 @@
[Unit]
Description=Coturn TURN server for Matrix
After=network-online.target homelab-network.service
Requires=homelab-network.service
[Container]
ContainerName=coturn
Image=docker.io/coturn/coturn:latest
Volume={{ coturn_config_dir }}/turnserver.conf:/etc/coturn/turnserver.conf:Z
Network=homelab.network
PublishPort=3478:3478/tcp
PublishPort=3478:3478/udp
PublishPort=49152-49172:49152-49172/udp
Exec=-c /etc/coturn/turnserver.conf
[Install]
WantedBy=multi-user.target default.target

View File

@ -0,0 +1,15 @@
# /etc/coturn/turnserver.conf
listening-port=3478
fingerprint
lt-cred-mech
use-auth-secret
static-auth-secret={{ vault_matrix_turn_shared_secret }}
realm=matrix.{{ domain_name }}
total-quota=0
bps-capacity=0
stale-nonce=600
no-stdout-log
min-port=49152
max-port=49172
external-ip={{ nanode_public_ip }}

View File

@ -0,0 +1,6 @@
---
# matrix_synapse/meta/main.yml
dependencies:
- role: tailscale
- role: postgres
- role: coturn

View File

@ -0,0 +1,73 @@
---
# matrix_synapse/tasks/main.yml
- name: Create stack and config directories
file:
path: "{{ item }}"
state: directory
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: "0755"
loop: "{{ synapse_base_directories }}"
- name: Directory SELinux requirement
ansible.builtin.set_fact:
selinux_container_paths: "{{ synapse_base_directories }}"
- import_role:
name: selinux_containers
tasks_from: labels
#- name: Ensure container app config directories are owned by container UID
# become: true
# file:
# path: "{{ synapse_config_dir }}"
# state: directory
# owner: "{{ container_user }}"
# group: "{{ container_group }}"
# recurse: true
- name: Deploy homesever configuration template
template:
src: homeserver.yaml.j2
dest: "{{ synapse_config_dir }}/homeserver.yaml"
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: '0600'
- name: Ensure Synapse signing key is deployed
copy:
content: "{{ vault_matrix_signing_key }}"
dest: "{{ deploy_signing_key_path }}"
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: '0600'
- name: Deploy Synapse Quadlet
template:
src: synapse.container.j2
dest: "{{ container_config_dir }}/synapse.container"
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: '0644'
- name: Force systemd reload (blocking)
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
command: systemctl --user daemon-reload
- name: Wait for quadlet generation
pause:
seconds: 1
- name: Start and enable Synapse service
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
systemd:
name: synapse.service
scope: user
state: started
enabled: true

View File

@ -0,0 +1,48 @@
server_name: "{{ domain_name }}"
public_baseurl: "https://matrix.{{ domain_name }}/"
pid_file: /data/homeserver.pid
signing_key_path: "/data/{{ domain_name }}.signing.key"
registration_shared_secret: "{{ vault_matrix_registration_shared_secret }}"
macaroon_secret_key: "{{ vault_matrix_macaroon_secret }}"
form_secret: "{{ vault_matrix_form_secret }}"
presence:
enabled: true
report_stats: false
trusted_key_servers:
- server_name: "matrix.org"
suppress_key_server_warning: true
media_store_path: "/data/media_store"
uploads_path: "/data/uploads"
# Database configuration
database:
name: psycopg2
args:
user: synapse
password: "{{ vault_matrix_postgres_password }}"
database: synapse
host: 10.89.0.54
cp_min: 5
cp_max: 10
# Voice/Video (Coturn) integration
turn_uris:
- "turn:matrix.{{ domain_name }}:3478?transport=udp"
- "turn:matrix.{{ domain_name }}:3478?transport=tcp"
turn_shared_secret: "{{ vault_matrix_turn_shared_secret }}"
turn_user_lifetime: 86400000
# Listeners
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client, federation]
compress: false

View File

@ -0,0 +1,16 @@
[Unit]
Description=Matrix Synapse Homeserver
After=network-online.target postgres.service coturn.service
Requires=postgres.service
[Container]
ContainerName=synapse
Image=docker.io/matrixdotorg/synapse:latest
Volume={{ synapse_config_dir }}:/data:Z
Network=homelab.network
# Expose the client-server API port
PublishPort={{ tailscale_ip }}:8008:8008
UserNS=keep-id
[Install]
WantedBy=multi-user.target default.target

View File

@ -0,0 +1,4 @@
---
# postgres/meta/main.yml
dependencies:
- role: selinux_containers

View File

@ -0,0 +1,70 @@
---
# postgres/tasks/main.yml
- name: Create stack and config directories
file:
path: "{{ item }}"
state: directory
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: "0755"
loop: "{{ postgres_base_directories }}"
- name: Directory SELinux requirement
ansible.builtin.set_fact:
selinux_container_paths: "{{ postgres_base_directories }}"
- import_role:
name: selinux_containers
tasks_from: labels
- name: Ensure container app config directories are owned by container UID
become: true
file:
path: "{{ postgres_config_dir }}"
state: directory
owner: "{{ container_user }}"
group: "{{ container_group }}"
recurse: true
- name: Deploy Postgres Quadlet
template:
src: postgres.container.j2
dest: "{{ container_config_dir }}/postgres.container"
owner: "{{ container_user }}"
group: "{{ container_group }}"
mode: "0600"
- name: Force systemd reload (blocking)
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
command: systemctl --user daemon-reload
- name: Wait for quadlet generation
pause:
seconds: 1
- name: Start and enable Postgres service
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
systemd:
name: postgres.service
scope: user
state: started
enabled: true
- name: Wait for Postgres to be ready (Handling the double-start)
become: true
become_user: "{{ container_user }}"
environment:
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
ansible.builtin.command:
cmd: "podman exec postgres pg_isready -U synapse -d synapse"
register: pg_check
until: pg_check.rc == 0
retries: 20
delay: 5
changed_when: false

View File

@ -0,0 +1,18 @@
[Unit]
Description=PostgreSQL for Matrix
After=network-online.target homelab-network.service
Requires=homelab-network.service
[Container]
ContainerName=postgres
Image=docker.io/library/postgres:16-alpine
Environment=POSTGRES_USER=synapse
Environment=POSTGRES_PASSWORD={{ vault_matrix_postgres_password }}
Environment=POSTGRES_DB=synapse
Environment=POSTGRES_INITDB_ARGS="--lc-collate=C --lc-ctype=C --encoding=UTF8"
Volume={{ postgres_data_dir }}:/var/lib/postgresql/data
Network=homelab.network
IP=10.89.0.54
[Install]
WantedBy=multi-user.target default.target

View File

@ -0,0 +1,3 @@
#base_os/defaults/main.yml
tailscale_install_packages:
- tailscale

View File

@ -0,0 +1,36 @@
---
# tailscale/tasks/main.yml
- name: Add Tailscale repository
become: true
ansible.builtin.get_url:
url: https://pkgs.tailscale.com/stable/rhel/9/tailscale.repo
dest: /etc/yum.repos.d/tailscale.repo
mode: '0644'
- name: Install required base packages
become: true
dnf:
name: "{{ item }}"
state: present
loop: "{{ tailscale_install_packages }}"
- name: Start tailscaled
become: true
ansible.builtin.systemd:
name: tailscaled
state: started
enabled: true
- name: Bring Tailscale up (without hijacking DNS)
become: true
ansible.builtin.command:
cmd: >
tailscale up
--authkey={{ vault_tailscale_auth_key }}
--accept-dns=false
--reset
register: ts_up
changed_when: "'already authenticated' not in ts_up.stderr"
failed_when:
- ts_up.rc != 0
- "'already authenticated' not in ts_up.stderr"

View File

@ -30,7 +30,7 @@ PublishPort=9696:9696
Environment=VPN_SERVICE_PROVIDER=mullvad Environment=VPN_SERVICE_PROVIDER=mullvad
Environment=VPN_TYPE=wireguard Environment=VPN_TYPE=wireguard
Environment=WIREGUARD_PRIVATE_KEY={{ vpn_private_key }} Environment=WIREGUARD_PRIVATE_KEY={{ vault_vpn_private_key }}
Environment=WIREGUARD_ADDRESSES={{ vpn_addresses }} Environment=WIREGUARD_ADDRESSES={{ vpn_addresses }}
Environment=FIREWALL_ENABLED=on Environment=FIREWALL_ENABLED=on