Compare commits
No commits in common. "bba5e0e47844bcbc8368ee389502fc2c79cf48f3" and "bd16ea01bcceca87ffb904f0572d1194055ee818" have entirely different histories.
bba5e0e478
...
bd16ea01bc
74
playbook.yml
74
playbook.yml
|
|
@ -8,9 +8,6 @@
|
|||
tags: firewall_base
|
||||
- role: cli_productivity
|
||||
tags: cli_productivity
|
||||
- role: tailscale
|
||||
tags: tailscale
|
||||
when: tailscale_enabled | bool
|
||||
|
||||
- name: Shared storage clients
|
||||
hosts: nfs_clients
|
||||
|
|
@ -29,7 +26,7 @@
|
|||
tags: nfs_server
|
||||
|
||||
- name: Containers stack
|
||||
hosts: nas:services
|
||||
hosts: services
|
||||
become: true
|
||||
roles:
|
||||
- role: container_runtime
|
||||
|
|
@ -37,55 +34,13 @@
|
|||
- role: selinux_containers
|
||||
tags: selinux_containers
|
||||
|
||||
- name: VPN
|
||||
hosts: vpn_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: vpn
|
||||
tags: vpn
|
||||
|
||||
- name: Postgres stack
|
||||
hosts: postgres_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: postgres
|
||||
tags: postgres
|
||||
|
||||
- name: Matrix stack
|
||||
hosts: matrix_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: matrix_synapse
|
||||
tags: matrix
|
||||
when: matrix_enabled | bool
|
||||
|
||||
- name: Coturn stack
|
||||
hosts: coturn_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: coturn
|
||||
tags: coturn
|
||||
|
||||
- name: Media services
|
||||
hosts: media
|
||||
become: true
|
||||
roles:
|
||||
- role: jellyfin
|
||||
tags: jellyfin
|
||||
|
||||
- name: Notes stack
|
||||
hosts: notes_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: trilium
|
||||
tags: trilium
|
||||
|
||||
- name: Servarr stack
|
||||
hosts: servarr_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: servarr
|
||||
tags: servarr
|
||||
# Jellyfin role will go here later.
|
||||
# - role: jellyfin
|
||||
# tags: jellyfin
|
||||
|
||||
- name: DNS and reverse proxy
|
||||
hosts: services
|
||||
|
|
@ -96,6 +51,27 @@
|
|||
- role: caddy
|
||||
tags: caddy
|
||||
|
||||
- name: Servarr stack
|
||||
hosts: servarr_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: servarr
|
||||
tags: servarr
|
||||
|
||||
- name: Matrix stack
|
||||
hosts: matrix_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: matrix_synapse
|
||||
tags: matrix
|
||||
|
||||
- name: Notes stack
|
||||
hosts: notes_hosts
|
||||
become: true
|
||||
roles:
|
||||
- role: trilium
|
||||
tags: trilium
|
||||
|
||||
- name: ML workloads
|
||||
hosts: ml_hosts
|
||||
become: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
# adguard/meta/main.yml
|
||||
dependencies:
|
||||
- role: selinux_containers
|
||||
|
|
@ -2,25 +2,58 @@
|
|||
#adguard/tasks/main.yml
|
||||
- import_tasks: firewall.yml
|
||||
|
||||
- name: Create adguard container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ adguard_base_directories }}"
|
||||
- name: Create stack and config directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
recurse: yes
|
||||
loop: "{{ adguard_base_directories }}"
|
||||
|
||||
- name: Setup directory for adguard config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- name: Directory SELinux requirement
|
||||
ansible.builtin.set_fact:
|
||||
selinux_container_paths: "{{ adguard_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: "{{ adguard_dir }}/conf"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
recurse: true
|
||||
|
||||
- name: Deploy AdGuard configuration template
|
||||
template:
|
||||
src: AdGuardHome.yaml.j2
|
||||
dest: "{{ stack_root }}/adguard/conf/AdGuardHome.yaml"
|
||||
mode: '0600'
|
||||
force: "{{ adguard_overwrite_config | default(false) | bool }}"
|
||||
|
||||
- name: Deploy AdGuard Quadlet
|
||||
template:
|
||||
src: adguard.container.j2
|
||||
dest: "{{ container_config_dir }}/adguard.container"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "adguard"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- name: Wait for quadlet generation
|
||||
pause:
|
||||
seconds: 1
|
||||
|
||||
- name: Start and enable AdGuard service
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
systemd:
|
||||
name: adguard.service
|
||||
scope: user
|
||||
state: started
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
http:
|
||||
pprof:
|
||||
port: 6060
|
||||
enabled: false
|
||||
doh:
|
||||
routes:
|
||||
- GET /dns-query
|
||||
- POST /dns-query
|
||||
- GET /dns-query/{ClientID}
|
||||
- POST /dns-query/{ClientID}
|
||||
insecure_enabled: false
|
||||
address: 0.0.0.0:80
|
||||
session_ttl: 720h
|
||||
users:
|
||||
- name: "{{ adguard_admin_user }}"
|
||||
password: "{{ adguard_admin_password_hash }}"
|
||||
auth_attempts: 5
|
||||
block_auth_min: 15
|
||||
http_proxy: ""
|
||||
language: ""
|
||||
theme: auto
|
||||
dns:
|
||||
bind_hosts:
|
||||
- 0.0.0.0
|
||||
port: 53
|
||||
anonymize_client_ip: false
|
||||
ratelimit: 20
|
||||
ratelimit_subnet_len_ipv4: 24
|
||||
ratelimit_subnet_len_ipv6: 56
|
||||
ratelimit_whitelist: []
|
||||
refuse_any: true
|
||||
upstream_dns:
|
||||
- https://dns10.quad9.net/dns-query
|
||||
upstream_dns_file: ""
|
||||
bootstrap_dns:
|
||||
- 9.9.9.10
|
||||
- 149.112.112.10
|
||||
- 2620:fe::10
|
||||
- 2620:fe::fe:10
|
||||
fallback_dns: []
|
||||
upstream_mode: load_balance
|
||||
fastest_timeout: 1s
|
||||
allowed_clients: []
|
||||
disallowed_clients: []
|
||||
blocked_hosts:
|
||||
- version.bind
|
||||
- id.server
|
||||
- hostname.bind
|
||||
trusted_proxies:
|
||||
- 127.0.0.0/8
|
||||
- ::1/128
|
||||
cache_enabled: true
|
||||
cache_size: 4194304
|
||||
cache_ttl_min: 0
|
||||
cache_ttl_max: 0
|
||||
cache_optimistic: false
|
||||
cache_optimistic_answer_ttl: 30s
|
||||
cache_optimistic_max_age: 12h
|
||||
bogus_nxdomain: []
|
||||
aaaa_disabled: false
|
||||
enable_dnssec: false
|
||||
edns_client_subnet:
|
||||
custom_ip: ""
|
||||
enabled: false
|
||||
use_custom: false
|
||||
max_goroutines: 300
|
||||
handle_ddr: true
|
||||
ipset: []
|
||||
ipset_file: ""
|
||||
bootstrap_prefer_ipv6: false
|
||||
upstream_timeout: 10s
|
||||
private_networks: []
|
||||
use_private_ptr_resolvers: true
|
||||
local_ptr_upstreams: []
|
||||
use_dns64: false
|
||||
dns64_prefixes: []
|
||||
serve_http3: false
|
||||
use_http3_upstreams: false
|
||||
serve_plain_dns: true
|
||||
hostsfile_enabled: true
|
||||
pending_requests:
|
||||
enabled: true
|
||||
tls:
|
||||
enabled: false
|
||||
server_name: ""
|
||||
force_https: false
|
||||
port_https: 443
|
||||
port_dns_over_tls: 853
|
||||
port_dns_over_quic: 853
|
||||
port_dnscrypt: 0
|
||||
dnscrypt_config_file: ""
|
||||
certificate_chain: ""
|
||||
private_key: ""
|
||||
certificate_path: ""
|
||||
private_key_path: ""
|
||||
strict_sni_check: false
|
||||
querylog:
|
||||
dir_path: ""
|
||||
ignored: []
|
||||
interval: 2160h
|
||||
size_memory: 1000
|
||||
enabled: true
|
||||
ignored_enabled: false
|
||||
file_enabled: true
|
||||
statistics:
|
||||
dir_path: ""
|
||||
ignored: []
|
||||
interval: 24h
|
||||
enabled: true
|
||||
ignored_enabled: false
|
||||
filters:
|
||||
- enabled: true
|
||||
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
|
||||
name: AdGuard DNS filter
|
||||
id: 1
|
||||
- enabled: false
|
||||
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt
|
||||
name: AdAway Default Blocklist
|
||||
id: 2
|
||||
whitelist_filters: []
|
||||
user_rules: []
|
||||
dhcp:
|
||||
enabled: false
|
||||
interface_name: ""
|
||||
local_domain_name: lan
|
||||
dhcpv4:
|
||||
gateway_ip: ""
|
||||
subnet_mask: ""
|
||||
range_start: ""
|
||||
range_end: ""
|
||||
lease_duration: 86400
|
||||
icmp_timeout_msec: 1000
|
||||
options: []
|
||||
dhcpv6:
|
||||
range_start: ""
|
||||
lease_duration: 86400
|
||||
ra_slaac_only: false
|
||||
ra_allow_slaac: false
|
||||
filtering:
|
||||
blocking_ipv4: ""
|
||||
blocking_ipv6: ""
|
||||
blocked_services:
|
||||
schedule:
|
||||
time_zone: UTC
|
||||
ids: []
|
||||
protection_disabled_until: null
|
||||
safe_search:
|
||||
enabled: false
|
||||
bing: true
|
||||
duckduckgo: true
|
||||
ecosia: true
|
||||
google: true
|
||||
pixabay: true
|
||||
yandex: true
|
||||
youtube: true
|
||||
blocking_mode: default
|
||||
parental_block_host: family-block.dns.adguard.com
|
||||
safebrowsing_block_host: standard-block.dns.adguard.com
|
||||
rewrites: []
|
||||
safe_fs_patterns:
|
||||
- /opt/adguardhome/work/userfilters/*
|
||||
safebrowsing_cache_size: 1048576
|
||||
safesearch_cache_size: 1048576
|
||||
parental_cache_size: 1048576
|
||||
cache_time: 30
|
||||
filters_update_interval: 24
|
||||
blocked_response_ttl: 10
|
||||
filtering_enabled: true
|
||||
rewrites_enabled: true
|
||||
parental_enabled: false
|
||||
safebrowsing_enabled: false
|
||||
protection_enabled: true
|
||||
clients:
|
||||
runtime_sources:
|
||||
whois: true
|
||||
arp: true
|
||||
rdns: true
|
||||
dhcp: true
|
||||
hosts: true
|
||||
persistent: []
|
||||
log:
|
||||
enabled: true
|
||||
file: ""
|
||||
max_backups: 0
|
||||
max_size: 100
|
||||
max_age: 3
|
||||
compress: false
|
||||
local_time: false
|
||||
verbose: false
|
||||
os:
|
||||
group: ""
|
||||
user: ""
|
||||
rlimit_nofile: 0
|
||||
schema_version: 34
|
||||
|
|
@ -7,15 +7,15 @@ Requires=homelab-network.service
|
|||
[Container]
|
||||
Image=docker.io/adguard/adguardhome:latest
|
||||
ContainerName=adguard
|
||||
Network=homelab
|
||||
Network=homelab.network
|
||||
NetworkAlias=adguard
|
||||
|
||||
Volume={{ adguard_dir }}/work:/opt/adguardhome/work
|
||||
Volume={{ adguard_dir }}/conf:/opt/adguardhome/conf
|
||||
|
||||
PublishPort={{ adguard_bind_ip }}:{{ adguard_dns_port | default(53) }}:53/tcp
|
||||
PublishPort={{ adguard_bind_ip }}:{{ adguard_dns_port | default(53) }}:53/udp
|
||||
PublishPort={{ adguard_bind_ip }}:{{ adguard_web_port | default(3000) }}:3000/tcp
|
||||
PublishPort=53:53/tcp
|
||||
PublishPort=53:53/udp
|
||||
PublishPort=3000:3000/tcp
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
# caddy/meta/main.yml
|
||||
dependencies:
|
||||
- role: selinux_containers
|
||||
|
|
@ -1,13 +1,22 @@
|
|||
---
|
||||
#caddy/tasks/main.yml
|
||||
- name: Create caddy container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ caddy_base_directories }}"
|
||||
- name: Create stack and config directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
recurse: yes
|
||||
loop: "{{ caddy_base_directories }}"
|
||||
|
||||
- name: Setup directory for caddy config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- name: Base SELinux requirement
|
||||
ansible.builtin.set_fact:
|
||||
selinux_container_paths: "{{ caddy_base_directories }}"
|
||||
|
||||
- import_role:
|
||||
name: selinux_containers
|
||||
tasks_from: labels
|
||||
|
||||
- name: Ensure Caddyfile is deployed
|
||||
template:
|
||||
|
|
@ -22,11 +31,19 @@
|
|||
src: caddy.container.j2
|
||||
dest: "{{ container_config_dir }}/caddy.container"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "caddy"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- name: Wait for quadlet generation
|
||||
pause:
|
||||
seconds: 1
|
||||
|
||||
- name: Start service
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
systemd:
|
||||
name: caddy.service
|
||||
scope: user
|
||||
state: started
|
||||
|
|
@ -4,12 +4,6 @@
|
|||
reverse_proxy {{ adguard_upstream }}
|
||||
}
|
||||
|
||||
# Jellyfin
|
||||
{{ jellyfin_domain }} {
|
||||
tls internal
|
||||
reverse_proxy {{ jellyfin_upstream }}
|
||||
}
|
||||
|
||||
# QBittorrent
|
||||
{{ qbittorrent_domain }} {
|
||||
tls internal
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ After=homelab-network.service
|
|||
[Container]
|
||||
Image=docker.io/caddy:latest
|
||||
ContainerName=caddy
|
||||
Network=homelab
|
||||
Network=homelab.network
|
||||
|
||||
Volume={{ caddy_dir }}/Caddyfile:/etc/caddy/Caddyfile
|
||||
Volume={{ caddy_dir }}/data:/data
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ cli_user: "{{ container_user }}"
|
|||
cli_group: "{{ cli_user }}"
|
||||
|
||||
cli_install_epel: true
|
||||
cli_use_epel: "{{ cli_install_epel | bool and ansible_facts['os_family'] == 'RedHat' and ansible_facts['distribution'] != 'Fedora' }}"
|
||||
cli_use_epel: "{{ cli_install_epel | bool and ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora' }}"
|
||||
|
||||
cli_set_fish_as_default_shell: true
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
---
|
||||
# container_runtime/tasks/config-setup.yml
|
||||
- import_tasks: directory.yml
|
||||
|
||||
- name: Directory SELinux requirement
|
||||
ansible.builtin.set_fact:
|
||||
selinux_container_paths: "{{ missing_dirs }}"
|
||||
when: missing_dirs | length > 0
|
||||
|
||||
- name: Apply SELinux container labels
|
||||
ansible.builtin.import_role:
|
||||
name: selinux_containers
|
||||
tasks_from: labels
|
||||
when: missing_dirs | length > 0
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
- name: Check directories exist
|
||||
ansible.builtin.stat:
|
||||
path: "{{ item.path if item is mapping else item }}"
|
||||
loop: "{{ dir_list }}"
|
||||
register: dir_stats
|
||||
|
||||
- name: Build list of missing directories
|
||||
ansible.builtin.set_fact:
|
||||
missing_dirs: >-
|
||||
{{
|
||||
dir_stats.results
|
||||
| rejectattr('stat.exists', 'equalto', true)
|
||||
| map(attribute='item')
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: Ensure missing directories exist
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item.path if item is mapping else item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "{{ item.mode | default('0755') if item is mapping else '0755' }}"
|
||||
loop: "{{ missing_dirs }}"
|
||||
when: missing_dirs | length > 0
|
||||
|
|
@ -20,24 +20,6 @@
|
|||
value: '53'
|
||||
state: present
|
||||
|
||||
- name: Check configuration directories exist
|
||||
ansible.builtin.stat:
|
||||
path: "{{ item }}"
|
||||
loop:
|
||||
- "{{ stack_root }}"
|
||||
- "{{ container_config_dir }}"
|
||||
register: config_dirs_stats
|
||||
|
||||
- name: Build list of missing configuration directories
|
||||
ansible.builtin.set_fact:
|
||||
missing_config_dirs: >-
|
||||
{{
|
||||
config_dirs_stats.results
|
||||
| rejectattr('stat.exists')
|
||||
| map(attribute='item')
|
||||
| list
|
||||
}}
|
||||
|
||||
- name: Create stack directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
|
|
@ -46,9 +28,9 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
recurse: yes
|
||||
loop: "{{ missing_config_dirs }}"
|
||||
when: missing_config_dirs | length > 0
|
||||
|
||||
loop:
|
||||
- "{{ stack_root }}"
|
||||
- "{{ container_config_dir }}"
|
||||
|
||||
- name: Configure SELinux container policies
|
||||
ansible.builtin.import_tasks: ../selinux_containers/tasks/main.yml
|
||||
|
|
@ -62,11 +44,17 @@
|
|||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "homelab-network"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- name: Start homelab network
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
systemd:
|
||||
name: homelab-network.service
|
||||
scope: user
|
||||
state: started
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
---
|
||||
# container_runtime/tasks/systemd.yml
|
||||
- name: Build container service list
|
||||
ansible.builtin.set_fact:
|
||||
container_service_names: "{{ service_names | default([service_name]) }}"
|
||||
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Wait for quadlet generation
|
||||
pause:
|
||||
seconds: 1
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Start and enable container services
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
systemd:
|
||||
name: "{{ item }}.service"
|
||||
scope: user
|
||||
state: started
|
||||
enabled: true
|
||||
loop: "{{ container_service_names }}"
|
||||
when: not ansible_check_mode
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
# coturn/meta/main.yml
|
||||
dependencies:
|
||||
- role: selinux_containers
|
||||
|
|
@ -2,14 +2,32 @@
|
|||
# coturn/tasks/main.yml
|
||||
- import_tasks: firewall.yml
|
||||
|
||||
- name: Create coturn container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ coturn_base_directories }}"
|
||||
- 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: Setup directory for coturn config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- 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:
|
||||
|
|
@ -18,8 +36,6 @@
|
|||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: '0600'
|
||||
force: "{{ coturn_overwrite_config | default(false) | bool }}"
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Deploy Coturn Quadlet
|
||||
template:
|
||||
|
|
@ -29,11 +45,24 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: '0644'
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "coturn"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- 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
|
||||
|
|
@ -7,7 +7,7 @@ Requires=homelab-network.service
|
|||
ContainerName=coturn
|
||||
Image=docker.io/coturn/coturn:latest
|
||||
Volume={{ coturn_config_dir }}/turnserver.conf:/etc/coturn/turnserver.conf:Z
|
||||
Network=homelab
|
||||
Network=homelab.network
|
||||
PublishPort=3478:3478/tcp
|
||||
PublishPort=3478:3478/udp
|
||||
PublishPort=49152-49172:49152-49172/udp
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
---
|
||||
# jellyfin/tasks/firewall.yml
|
||||
|
||||
- name: Open required Jellyfin firewall rules
|
||||
become: true
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ item.port | default(omit) }}"
|
||||
service: "{{ item.service | default(omit) }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
immediate: true
|
||||
loop: "{{ jellyfin_firewall_rules }}"
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
---
|
||||
# jellyfin/tasks/main.yml
|
||||
|
||||
- import_tasks: firewall.yml
|
||||
|
||||
- name: Create jellyfin container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ jellyfin_base_directories }}"
|
||||
|
||||
- name: Setup directory for jellyfin config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
|
||||
- name: Deploy Jellyfin Quadlet
|
||||
template:
|
||||
src: jellyfin.container.j2
|
||||
dest: "{{ container_config_dir }}/jellyfin.container"
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "jellyfin"
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
[Unit]
|
||||
Description=Jellyfin Media Server
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Container]
|
||||
ContainerName=jellyfin
|
||||
Image=docker.io/jellyfin/jellyfin:10.11.7
|
||||
Network=host
|
||||
|
||||
Volume={{ jellyfin_config_dir }}:/config:Z
|
||||
Volume={{ jellyfin_cache_dir }}:/cache:Z
|
||||
Volume={{ jellyfin_media_dir }}:/data:ro
|
||||
|
||||
Environment=TZ={{ timezone }}
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
# matrix_synapse/meta/main.yml
|
||||
dependencies:
|
||||
- role: tailscale
|
||||
- role: postgres
|
||||
- role: coturn
|
||||
|
|
@ -1,13 +1,21 @@
|
|||
---
|
||||
# matrix_synapse/tasks/main.yml
|
||||
- name: Create synapse container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ synapse_base_directories }}"
|
||||
- name: Create stack and config directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
loop: "{{ synapse_base_directories }}"
|
||||
|
||||
- name: Create directory for synapse config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- name: Directory SELinux requirement
|
||||
ansible.builtin.set_fact:
|
||||
selinux_container_paths: "{{ synapse_base_directories }}"
|
||||
|
||||
- import_role:
|
||||
name: selinux_containers
|
||||
tasks_from: labels
|
||||
|
||||
- name: Deploy homesever configuration template
|
||||
template:
|
||||
|
|
@ -17,7 +25,6 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: '0600'
|
||||
force: "{{ matrix_overwrite_config | default(false) | bool }}"
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Ensure Synapse signing key is deployed
|
||||
copy:
|
||||
|
|
@ -27,7 +34,6 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: '0600'
|
||||
force: "{{ matrix_overwrite_signing_key | default(false) | bool }}"
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Deploy Synapse Quadlet
|
||||
template:
|
||||
|
|
@ -37,11 +43,24 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: '0644'
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "synapse"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- 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
|
||||
|
|
@ -7,7 +7,7 @@ Requires=postgres.service
|
|||
ContainerName=synapse
|
||||
Image=docker.io/matrixdotorg/synapse:latest
|
||||
Volume={{ synapse_config_dir }}:/data:Z
|
||||
Network=homelab
|
||||
Network=homelab.network
|
||||
# Expose the client-server API port
|
||||
PublishPort={{ tailscale_ip }}:8008:8008
|
||||
UserNS=keep-id
|
||||
|
|
|
|||
|
|
@ -1,5 +1,42 @@
|
|||
---
|
||||
# nfs_client/tasks/main.yml
|
||||
- name: Configure dummy NAS storage for test environment
|
||||
when: env == "test"
|
||||
block:
|
||||
- name: Create dummy NAS root for test environment
|
||||
become: true
|
||||
file:
|
||||
path: "{{ nfs_mount_point }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Create dummy NAS storage tree for test environment
|
||||
become: true
|
||||
file:
|
||||
path: "{{ nfs_mount_point }}/{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0775"
|
||||
loop: "{{ storage_tree }}"
|
||||
|
||||
- name: Set SELinux context for dummy NAS storage in test environment
|
||||
become: true
|
||||
community.general.sefcontext:
|
||||
target: "{{ nfs_mount_point }}(/.*)?"
|
||||
setype: container_file_t
|
||||
state: present
|
||||
|
||||
- name: Apply SELinux context for dummy NAS storage in test environment
|
||||
become: true
|
||||
command: restorecon -Rv "{{ nfs_mount_point }}"
|
||||
changed_when: false
|
||||
|
||||
- name: Configure NFS client for non-test environments
|
||||
when: env != "test"
|
||||
block:
|
||||
- name: Install required NFS client packages
|
||||
become: true
|
||||
dnf:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
# postgres/meta/main.yml
|
||||
dependencies:
|
||||
- role: selinux_containers
|
||||
|
|
@ -1,13 +1,30 @@
|
|||
---
|
||||
# postgres/tasks/main.yml
|
||||
- name: Create postgres container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ postgres_base_directories }}"
|
||||
- name: Create stack and config directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
loop: "{{ postgres_base_directories }}"
|
||||
|
||||
- name: Setup directory for postgres config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- 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:
|
||||
|
|
@ -17,14 +34,27 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: "0600"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "postgres"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- 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
|
||||
|
|
@ -38,4 +68,3 @@
|
|||
retries: 20
|
||||
delay: 5
|
||||
changed_when: false
|
||||
when: not ansible_check_mode
|
||||
|
|
@ -11,7 +11,7 @@ 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=homelab.network
|
||||
IP=10.89.0.54
|
||||
|
||||
[Install]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
- name: Ensure SELinux context for container config paths
|
||||
become: true
|
||||
community.general.sefcontext:
|
||||
target: "{{ (item.path if item is mapping else item) }}(/.*)?"
|
||||
target: "{{ item }}(/.*)?"
|
||||
setype: container_file_t
|
||||
state: present
|
||||
loop: "{{ selinux_container_paths | default([]) }}"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
# selinux_containers/tasks/storage.yml
|
||||
- name: Set SELinux context for storage mounts
|
||||
become: true
|
||||
community.general.sefcontext:
|
||||
target: "{{ item }}(/.*)?"
|
||||
setype: container_file_t
|
||||
state: present
|
||||
loop: "{{ storage_backends }}"
|
||||
when: "'nas' in group_names"
|
||||
|
||||
- name: Apply SELinux context (storage)
|
||||
become: true
|
||||
command: restorecon -R -F -v "{{ item }}"
|
||||
loop: "{{ storage_backends }}"
|
||||
changed_when: false
|
||||
when: "'nas' in group_names"
|
||||
|
|
@ -7,5 +7,3 @@ servarr_firewall_rules:
|
|||
- port: 8191/tcp
|
||||
- port: 8989/tcp
|
||||
- port: 9696/tcp
|
||||
|
||||
vpn_guard_enabled: false
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
# servarr/meta/main.yml
|
||||
dependencies:
|
||||
- role: selinux_containers
|
||||
- role: vpn
|
||||
|
|
@ -1,14 +1,31 @@
|
|||
#servarr/tasks/main.yml
|
||||
- import_tasks: firewall.yml
|
||||
|
||||
- name: Create servarr container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ servarr_base_directories }}"
|
||||
- name: Create stack and config directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
recurse: yes
|
||||
loop: "{{ servarr_base_directories }}"
|
||||
|
||||
- name: Setup directory for servarr config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- name: Directory SELinux requirement
|
||||
ansible.builtin.set_fact:
|
||||
selinux_container_paths: "{{ servarr_base_directories }}"
|
||||
|
||||
- import_role:
|
||||
name: selinux_containers
|
||||
tasks_from: labels
|
||||
|
||||
- name: Ensure systemd directory exists for rootless user
|
||||
file:
|
||||
path: "{{ container_config_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
|
||||
- name: Deploy Quadlet files
|
||||
template:
|
||||
|
|
@ -17,25 +34,33 @@
|
|||
loop: "{{ servarr_stack }}"
|
||||
register: quadlets_deployed
|
||||
|
||||
- name: Validate VPN
|
||||
- name: Ensure app config directories are writable
|
||||
become: true
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
recurse: true
|
||||
loop:
|
||||
- "{{ radarr_dir }}/config"
|
||||
- "{{ sonarr_dir }}/config"
|
||||
- "{{ qbittorrent_dir }}/config"
|
||||
- "{{ prowlarr_dir }}/config"
|
||||
- "{{ bazarr_dir }}/config"
|
||||
|
||||
#- name: Force systemd reload (blocking)
|
||||
# become: true
|
||||
# become_user: "{{ container_user }}"
|
||||
# command: systemctl --user daemon-reload
|
||||
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Validate VPN and start arr stack
|
||||
ansible.builtin.import_role:
|
||||
name: vpn_guard
|
||||
when:
|
||||
- vpn_guard_enabled | bool
|
||||
- not ansible_check_mode
|
||||
|
||||
- name: Skip VPN guard validation in check mode
|
||||
debug:
|
||||
msg: "Skipping VPN guard validation during Ansible check mode."
|
||||
when:
|
||||
- vpn_guard_enabled | bool
|
||||
- ansible_check_mode
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_names: "{{ arr_suite }}"
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
|
|
@ -1,53 +1,43 @@
|
|||
---
|
||||
#storage_client/tasks/main.yml
|
||||
- name: Install required packages
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
dnf:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop: "{{ base_storage_install_packages }}"
|
||||
when: env == "prod"
|
||||
|
||||
- name: Install mergerfs repo package
|
||||
become: true
|
||||
ansible.builtin.dnf:
|
||||
dnf:
|
||||
name: https://github.com/trapexit/mergerfs/releases/download/2.41.1/mergerfs-2.41.1-1.el10.x86_64.rpm
|
||||
disable_gpg_check: true
|
||||
state: present
|
||||
when: env == "prod"
|
||||
|
||||
- name: Set storage mount directory list
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ storage_drives + mergerfs }}"
|
||||
when: env == "prod"
|
||||
|
||||
- name: Ensure storage mount directories exist
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: directory
|
||||
when: env == "prod"
|
||||
|
||||
- name: Mount filesystem by UUID
|
||||
- name: Ensure source data directories exist
|
||||
become: true
|
||||
ansible.posix.mount:
|
||||
path: "{{ item.path }}"
|
||||
src: "UUID={{ item.uuid }}"
|
||||
fstype: "{{ item.fstype }}"
|
||||
opts: "{{ item.opts }}"
|
||||
dump: "{{ item.dump }}"
|
||||
passno: "{{ item.passno }}"
|
||||
state: mounted
|
||||
loop: "{{ storage_drives }}"
|
||||
when: env == "prod"
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
loop: "{{ storage_backends }}"
|
||||
|
||||
- name: Create mergerfs mountpoint
|
||||
become: true
|
||||
file:
|
||||
path: /mnt/nas01
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
|
||||
- name: Mount mergerfs pool
|
||||
become: true
|
||||
ansible.posix.mount:
|
||||
path: "{{ item.path }}"
|
||||
src: "{{ item.src_path }}"
|
||||
path: "{{ mergerfs_path }}"
|
||||
src: "{{ drive_a_path }}/data:{{ drive_b_path }}/data"
|
||||
fstype: fuse.mergerfs
|
||||
opts: "{{ item.opts }}"
|
||||
dump: "{{ item.dump | default('0') }}"
|
||||
passno: "{{ item.passno | default('0') }}"
|
||||
opts: defaults,allow_other,use_ino,category.create=mfs
|
||||
state: mounted
|
||||
loop: "{{ mergerfs }}"
|
||||
when: env == "prod"
|
||||
|
|
@ -20,7 +20,6 @@
|
|||
name: tailscaled
|
||||
state: started
|
||||
enabled: true
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Bring Tailscale up (without hijacking DNS)
|
||||
become: true
|
||||
|
|
@ -35,5 +34,3 @@
|
|||
failed_when:
|
||||
- ts_up.rc != 0
|
||||
- "'already authenticated' not in ts_up.stderr"
|
||||
when: not ansible_check_mode
|
||||
no_log: true
|
||||
|
|
@ -2,14 +2,23 @@
|
|||
# trilium/tasks/main.yml
|
||||
- import_tasks: firewall.yml
|
||||
|
||||
- name: Create trilium container directory
|
||||
ansible.builtin.set_fact:
|
||||
dir_list: "{{ trilium_base_directories }}"
|
||||
- name: Create stack and config directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0755"
|
||||
recurse: yes
|
||||
loop: "{{ trilium_base_directories }}"
|
||||
|
||||
- name: Setup directory for trilium config
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: config-setup
|
||||
- name: Directory SELinux requirement
|
||||
ansible.builtin.set_fact:
|
||||
selinux_container_paths: "{{ trilium_base_directories }}"
|
||||
|
||||
- import_role:
|
||||
name: selinux_containers
|
||||
tasks_from: labels
|
||||
|
||||
- name: Deploy Trilium Quadlet
|
||||
template:
|
||||
|
|
@ -19,11 +28,24 @@
|
|||
group: "{{ container_group }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "trilium"
|
||||
- name: Force systemd reload
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- name: Wait for quadlet generation
|
||||
pause:
|
||||
seconds: 1
|
||||
|
||||
- name: Start and enable Trilium service
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
systemd:
|
||||
name: trilium.service
|
||||
scope: user
|
||||
state: started
|
||||
enabled: true
|
||||
|
|
@ -7,8 +7,9 @@ Requires=homelab-network.service
|
|||
ContainerName=trilium
|
||||
Image=docker.io/triliumnext/notes:latest
|
||||
Volume={{ trilium_data_dir }}:/home/node/trilium-data:Z
|
||||
Network=homelab
|
||||
Network=homelab.network
|
||||
NetworkAlias=trilium
|
||||
IP={{ trilium_ip }}
|
||||
Environment=TZ={{ timezone }}
|
||||
|
||||
[Service]
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@
|
|||
|
||||
- name: Check whether xt_conntrack is available for running kernel
|
||||
become: true
|
||||
ansible.builtin.command: modinfo xt_conntrack
|
||||
command: modinfo xt_conntrack
|
||||
register: xt_conntrack_modinfo
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
check_mode: false
|
||||
|
||||
- name: Reboot if kernel modules were installed but running kernel cannot find xt_conntrack
|
||||
become: true
|
||||
|
|
@ -21,8 +20,6 @@
|
|||
msg: "Rebooting to load kernel matching installed kernel-modules-extra for Gluetun firewall"
|
||||
reboot_timeout: 600
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- kernel_modules_extra_install.changed
|
||||
- xt_conntrack_modinfo.rc != 0
|
||||
|
||||
- name: Load xt_conntrack for Gluetun firewall
|
||||
|
|
@ -45,21 +42,30 @@
|
|||
tasks_from: vpn
|
||||
|
||||
- name: Deploy Quadlet files
|
||||
ansible.builtin.template:
|
||||
template:
|
||||
src: "gluetun.container.j2"
|
||||
dest: "{{ container_config_dir }}/gluetun.container"
|
||||
owner: "{{ container_user }}"
|
||||
group: "{{ container_group }}"
|
||||
mode: "0644"
|
||||
|
||||
- name: Set fact for systemd
|
||||
ansible.builtin.set_fact:
|
||||
service_name: "gluetun"
|
||||
- name: Force systemd reload (blocking)
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
command: systemctl --user daemon-reload
|
||||
|
||||
- name: Execute systemd tasks
|
||||
ansible.builtin.import_role:
|
||||
name: container_runtime
|
||||
tasks_from: systemd
|
||||
- name: Wait for quadlet generation
|
||||
pause:
|
||||
seconds: 1
|
||||
|
||||
- name: Start vpn
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
systemd:
|
||||
name: gluetun.service
|
||||
scope: user
|
||||
state: started
|
||||
|
||||
- name: Wait for Gluetun container to exist
|
||||
become: true
|
||||
|
|
@ -70,9 +76,7 @@
|
|||
delay: 2
|
||||
until: gluetun_exists.rc == 0
|
||||
changed_when: false
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Skip Gluetun runtime validation in check mode
|
||||
debug:
|
||||
msg: "Skipping Gluetun container existence check during Ansible check mode."
|
||||
when: ansible_check_mode
|
||||
- name: Wait for Gluetun to stabilize
|
||||
pause:
|
||||
seconds: 5
|
||||
|
|
@ -7,6 +7,7 @@ Wants=network-online.target
|
|||
[Container]
|
||||
Image=docker.io/qmcgaw/gluetun:latest
|
||||
ContainerName=gluetun
|
||||
UserNS=keep-id
|
||||
|
||||
AddCapability=NET_ADMIN
|
||||
AddCapability=NET_RAW
|
||||
|
|
@ -37,8 +38,7 @@ Environment=FIREWALL_ENABLED=on
|
|||
Environment=DNS_ENABLED=false
|
||||
Environment=FIREWALL_INPUT_PORTS=6767,7878,8080,8191,8989,9696
|
||||
|
||||
Network=homelab
|
||||
NetworkAlias=gluetun
|
||||
Network=homelab:alias=gluetun
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
command: curl -s https://ipinfo.io/ip
|
||||
register: host_ip
|
||||
changed_when: false
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Get VPN public IP (via Gluetun)
|
||||
become: true
|
||||
|
|
@ -12,11 +11,30 @@
|
|||
command: podman exec gluetun wget -qO- https://ipinfo.io/ip
|
||||
register: vpn_ip
|
||||
changed_when: false
|
||||
when: not ansible_check_mode
|
||||
|
||||
- name: Fail if VPN is not active (kill switch check)
|
||||
fail:
|
||||
msg: "VPN is NOT active (host={{ host_ip.stdout }} vpn={{ vpn_ip.stdout }}). Aborting arr stack start."
|
||||
when:
|
||||
- not ansible_check_mode
|
||||
- host_ip.stdout == vpn_ip.stdout
|
||||
when: host_ip.stdout == vpn_ip.stdout
|
||||
|
||||
#- name: Start arr stack only after VPN validation
|
||||
# become: true
|
||||
# become_user: "{{ container_user }}"
|
||||
# systemd:
|
||||
# name: "{{ item }}.service"
|
||||
# enabled: yes
|
||||
# state: started
|
||||
# scope: user
|
||||
# loop: "{{ arr_suite }}"
|
||||
|
||||
- name: Start arr stack only after VPN validation
|
||||
become: true
|
||||
become_user: "{{ container_user }}"
|
||||
environment:
|
||||
XDG_RUNTIME_DIR: "{{ container_runtime_dir }}"
|
||||
systemd:
|
||||
name: "{{ item }}.service"
|
||||
enabled: yes
|
||||
state: started
|
||||
scope: user
|
||||
loop: "{{ arr_suite }}"
|
||||
Loading…
Reference in New Issue