Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4527e39d0f | |||
| 02fa912cb1 | |||
| aceef4bdaa | |||
| 64aad4fcf0 | |||
| 81244d55a7 | |||
| 1cfd024285 | |||
| 26115c5660 | |||
| acef35ca8b | |||
| b531170bd7 | |||
| ad586c3cd3 | |||
| 6dfef08f7b | |||
| 934dd314a8 | |||
| 2529a918df | |||
| 7dfa20d3dd | |||
| 329620c7d7 | |||
| f820e89cf6 | |||
| a05951f883 | |||
| b404a9e459 | |||
| 3b4b56f53f | |||
| f697715065 | |||
| be7f215380 | |||
| 26e0fe4f8b | |||
| 2bb1f015e0 | |||
| 0f546e13b3 | |||
| ba8b312bf2 | |||
| 6fcedd9162 | |||
| 6ca4f61d50 | |||
| 15c09cb899 | |||
| 880857a70a | |||
| 70bf539546 | |||
| 5dd38b7e49 | |||
| 33d94211d1 | |||
| 278dd3cebe | |||
| d1dcb1984a | |||
| 37c986177b | |||
| 17326b1b15 | |||
| 88e1383202 | |||
| c9b4707cb2 | |||
| da9c610426 | |||
| c1a6da2aa8 | |||
| f1cd8c9a60 | |||
| 6010230a14 | |||
| c3d8b62504 | |||
| 4a409e37e9 | |||
| cb4d17f99e | |||
| 9569492e42 | |||
| 2a7b234f4e | |||
| 621d5310a3 | |||
| 6377a56d95 | |||
| dbd72f43a4 | |||
| 9f236b6fa5 | |||
| b4a0874deb | |||
| c51216ff9b | |||
| 7debdfcb93 | |||
| da016343c0 | |||
| bf749ebbde | |||
| 41d509a49d | |||
| f062f6862f | |||
| 2dfc0f734e | |||
| f9211dfa24 | |||
| 8713631e0b | |||
| 01ad4350b0 | |||
| 8a4ce488f1 | |||
| 664cf2956d | |||
| 8c3fe409ae | |||
| 075b796608 | |||
| 0b7d1c4d78 | |||
| 017de863d9 | |||
| b52a6f6f0d | |||
| 84d961c7e3 | |||
| d1e0eb30c0 | |||
| 0f38df0100 | |||
| 7911657c8c | |||
| fd5d0ce4f8 | |||
| 98bc863d08 | |||
| 9137791aac | |||
| f9179282b8 | |||
| 25e33caec9 | |||
| d5090503d8 | |||
| b7a038dcab | |||
| 5f063d82d5 | |||
| 95eff329b6 | |||
| e8f523c2af | |||
| 726c0c3523 | |||
| 8bff16d172 | |||
| fc3b5a1e05 | |||
| 13839c9dfd | |||
| 242b719671 | |||
| 224b27abc3 | |||
| a2022fd14c | |||
| be07698dae | |||
| ab7e09d90b | |||
| 8c81827e24 | |||
| 57996f1efd | |||
| 8311fcf53e | |||
| 90277b2d4e | |||
| 6fc12d0119 | |||
| 4b7ec4d638 | |||
| 6cd26eb7d8 |
@@ -1,3 +1,4 @@
|
|||||||
|
.ansible
|
||||||
data/bin/*
|
data/bin/*
|
||||||
data/volumes/*
|
data/volumes/*
|
||||||
data/images/*
|
data/images/*
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# ilnmors homelab README
|
# ilnmors homelab README
|
||||||
|
|
||||||
This homelab project implements single-node On-premise IaaS system. The homelab contains virtual machines which are divided by their roles, such as private firewall, DNS, PKI, LDAP and database, SSO\(OIDC\). The standard domain is used to implement this system without specific vendors. All components are defined as code and initiated by IaC \(Ansible\) except hypervisor initial configuration.
|
This homelab project implements single-node On-premise IaaS system. The homelab contains virtual machines which are divided by their roles, such as private firewall, DNS, PKI, LDAP and database, SSO(OIDC). The standard domain is used to implement this system without specific vendors. All components are defined as code and initiated by IaC (Ansible) except hypervisor initial configuration.
|
||||||
|
|
||||||
## RTO times
|
## RTO times
|
||||||
- Feb/25/2026 - Reprovisioning Hypervisor and vms
|
- Feb/25/2026 - Reprovisioning Hypervisor and vms
|
||||||
@@ -15,12 +15,12 @@ This homelab project implements single-node On-premise IaaS system. The homelab
|
|||||||
- Mar/5/2026 - Reprovisioning Hardware and Hypervisor and vms
|
- Mar/5/2026 - Reprovisioning Hardware and Hypervisor and vms
|
||||||
- RTO: 2 hour 20 min
|
- RTO: 2 hour 20 min
|
||||||
- console: 15min - verified
|
- console: 15min - verified
|
||||||
- certificate: 0 min \(When it needs to be created, RTO will be 20 min) - not verified
|
- certificate: 0 min (When it needs to be created, RTO will be 20 min) - not verified
|
||||||
- wireguard: 0 min \(When it needs to be created, RTO will be 1 min) - not verified
|
- wireguard: 0 min (When it needs to be created, RTO will be 1 min) - not verified
|
||||||
- hypervisor\(+fw\): 45 min - verified
|
- hypervisor(+fw): 45 min - verified
|
||||||
- switch: 1 min - verified
|
- switch: 1 min - verified
|
||||||
- dsm: 30 min - verified
|
- dsm: 30 min - verified
|
||||||
- kopia: 0 min \(When it needs to be created, RTO will be 10 min) - verified
|
- kopia: 0 min (When it needs to be created, RTO will be 10 min) - verified
|
||||||
- Extra vms: 30 min - verified
|
- Extra vms: 30 min - verified
|
||||||
- Etc: 30 min
|
- Etc: 30 min
|
||||||
|
|
||||||
|
|||||||
@@ -2,73 +2,187 @@
|
|||||||
# Global vars
|
# Global vars
|
||||||
ansible_ssh_private_key_file: "/etc/secrets/{{ hostvars['console']['node']['uid'] }}/id_console"
|
ansible_ssh_private_key_file: "/etc/secrets/{{ hostvars['console']['node']['uid'] }}/id_console"
|
||||||
|
|
||||||
# URL infromation, you can use {{ infra_uri['services'] | split(':') | first|last }} to seperate domain and ports
|
# CA
|
||||||
infra_uri:
|
root_cert_filename: "ilnmors_root_ca.crt"
|
||||||
|
intermediate_cert_filename: "ilnmors_intermediate_ca.crt"
|
||||||
|
intermediate_key_filename: "ilnmors_intermediate_ca.key"
|
||||||
|
|
||||||
|
|
||||||
|
# local SAN and SSH SAN should be updated manually on host_vars
|
||||||
|
domain:
|
||||||
|
public: "ilnmors.com"
|
||||||
|
internal: "ilnmors.internal"
|
||||||
|
dc: "dc=ilnmors,dc=internal"
|
||||||
|
org: "ilnmors"
|
||||||
|
|
||||||
|
# DNS configuration including bind and blocky should be set manually.
|
||||||
|
# named.conf.j2 is also set manually.
|
||||||
|
# Check the hosts.j2 when cname records are fixed
|
||||||
|
|
||||||
|
services:
|
||||||
crowdsec:
|
crowdsec:
|
||||||
domain: "crowdsec.ilnmors.internal"
|
domain: "crowdsec"
|
||||||
ports:
|
ports:
|
||||||
https: "8080"
|
https: "8080"
|
||||||
bind:
|
bind:
|
||||||
domain: "bind.ilnmors.internal"
|
domain: "bind"
|
||||||
ports:
|
ports:
|
||||||
dns: "53"
|
dns: "53"
|
||||||
blocky:
|
blocky:
|
||||||
domain: "blocky.ilnmors.internal"
|
domain: "blocky"
|
||||||
ports:
|
ports:
|
||||||
https: "443"
|
https: "443"
|
||||||
dns: "53"
|
dns: "53"
|
||||||
postgresql:
|
postgresql:
|
||||||
domain: "postgresql.ilnmors.internal"
|
domain: "postgresql"
|
||||||
ports:
|
ports:
|
||||||
tcp: "5432" # postgresql db connection port
|
tcp: "5432" # postgresql db connection port
|
||||||
|
subuid: "100998"
|
||||||
ldap:
|
ldap:
|
||||||
domain: "ldap.ilnmors.internal"
|
domain: "ldap"
|
||||||
ports:
|
ports:
|
||||||
http: "17170"
|
http: "17170"
|
||||||
ldaps: "636"
|
ldaps: "6360"
|
||||||
|
subuid: "100999"
|
||||||
ca:
|
ca:
|
||||||
domain: "ca.ilnmors.internal"
|
domain: "ca"
|
||||||
ports:
|
ports:
|
||||||
https: "9000"
|
https: "9000"
|
||||||
|
subuid: "100999"
|
||||||
|
x509-exporter:
|
||||||
|
ports:
|
||||||
|
http: "9793"
|
||||||
|
subuid: "165533"
|
||||||
prometheus:
|
prometheus:
|
||||||
domain: "prometheus.ilnmors.internal"
|
domain: "prometheus"
|
||||||
ports:
|
ports:
|
||||||
https: "9090"
|
https: "9090"
|
||||||
|
subuid: "165533"
|
||||||
loki:
|
loki:
|
||||||
domain: "loki.ilnmors.internal"
|
domain: "loki"
|
||||||
ports:
|
ports:
|
||||||
https: "3100"
|
https: "3100"
|
||||||
|
subuid: "110000"
|
||||||
|
grafana:
|
||||||
|
domain: "grafana"
|
||||||
|
ports:
|
||||||
|
http: "3000" # Infra server: Internal ports
|
||||||
|
subuid: "100471"
|
||||||
|
caddy:
|
||||||
|
ports:
|
||||||
|
http: "2080"
|
||||||
|
https: "2443"
|
||||||
nas:
|
nas:
|
||||||
domain: "nas.ilnmors.internal"
|
domain: "nas"
|
||||||
ports:
|
ports:
|
||||||
https: "5001"
|
https: "5001"
|
||||||
kopia:
|
kopia:
|
||||||
domain: "nas.ilnmors.internal"
|
domain: "nas"
|
||||||
ports:
|
ports:
|
||||||
https: "51515"
|
https: "51515"
|
||||||
|
authelia:
|
||||||
|
domain: "authelia"
|
||||||
|
ports:
|
||||||
|
http: "9091"
|
||||||
|
redis:
|
||||||
|
subuid: "100998"
|
||||||
|
vaultwarden:
|
||||||
|
domain:
|
||||||
|
public: "vault"
|
||||||
|
internal: "vault.app"
|
||||||
|
ports:
|
||||||
|
http: "8000"
|
||||||
|
gitea:
|
||||||
|
domain:
|
||||||
|
public: "gitea"
|
||||||
|
internal: "gitea.app"
|
||||||
|
ports:
|
||||||
|
http: "3000" # App server: Public ports
|
||||||
|
subuid: "100999"
|
||||||
|
immich:
|
||||||
|
domain:
|
||||||
|
public: "immich"
|
||||||
|
internal: "immich.app"
|
||||||
|
ports:
|
||||||
|
http: "2283"
|
||||||
|
redis: "6379"
|
||||||
|
immich-ml:
|
||||||
|
ports:
|
||||||
|
http: "3003"
|
||||||
|
paperless:
|
||||||
|
domain:
|
||||||
|
public: "paperless"
|
||||||
|
internal: "paperless.app"
|
||||||
|
ports:
|
||||||
|
http: "8001"
|
||||||
|
redis: "6380"
|
||||||
|
subuid: "100999"
|
||||||
|
manticore:
|
||||||
|
subuid: "100998"
|
||||||
|
affine:
|
||||||
|
domain:
|
||||||
|
public: "affine"
|
||||||
|
internal: "affine.app"
|
||||||
|
ports:
|
||||||
|
http: "3010"
|
||||||
|
redis: "6381"
|
||||||
|
manticore: "9308"
|
||||||
|
nextcloud:
|
||||||
|
domain:
|
||||||
|
public: "nextcloud"
|
||||||
|
internal: "nextcloud.app"
|
||||||
|
ports:
|
||||||
|
http: "8002"
|
||||||
|
redis: "6382"
|
||||||
|
subuid: "100032"
|
||||||
|
collabora:
|
||||||
|
domain:
|
||||||
|
public: "collabora"
|
||||||
|
internal: "collabora.app"
|
||||||
|
ports:
|
||||||
|
http: "9980"
|
||||||
|
subuid: "101000"
|
||||||
|
sure:
|
||||||
|
domain:
|
||||||
|
public: "sure"
|
||||||
|
internal: "sure.app"
|
||||||
|
ports:
|
||||||
|
http: "3001"
|
||||||
|
redis: "6383"
|
||||||
|
subuid: "100999"
|
||||||
|
|
||||||
version:
|
version:
|
||||||
packages:
|
packages:
|
||||||
sops: "3.12.1"
|
sops: "3.12.1"
|
||||||
step: "0.29.0"
|
step: "0.30.2"
|
||||||
kopia: "0.22.3"
|
kopia: "0.22.3"
|
||||||
blocky: "0.28.2"
|
blocky: "0.29.0"
|
||||||
alloy: "1.13.0"
|
alloy: "1.16.1"
|
||||||
# telegraf: "1.37.1"
|
|
||||||
containers:
|
containers:
|
||||||
# common
|
# common
|
||||||
caddy: "2.10.2"
|
caddy: "2.11.2"
|
||||||
# infra
|
# infra
|
||||||
step: "0.29.0"
|
step: "0.30.2"
|
||||||
ldap: "v0.6.2"
|
ldap: "v0.6.3"
|
||||||
x509-exporter: "3.19.1"
|
x509-exporter: "4.1.0"
|
||||||
prometheus: "v3.9.1"
|
prometheus: "v3.11.3"
|
||||||
loki: "3.6.5"
|
loki: "3.7.1"
|
||||||
grafana: "12.3.3"
|
grafana: "13.0.1"
|
||||||
## Postgresql
|
## Postgresql
|
||||||
postgresql: "18.2"
|
postgresql: "18.3"
|
||||||
# For immich - https://github.com/immich-app/base-images/blob/main/postgres/versions.yaml
|
# For immich - https://github.com/immich-app/base-images/blob/main/postgres/versions.yaml
|
||||||
# pgvector: "v0.8.1"
|
# pgvector: "v0.8.1"
|
||||||
vectorchord: "0.5.3"
|
vectorchord: "1.1.1"
|
||||||
# Auth
|
# Auth
|
||||||
authelia: "4.39.15"
|
authelia: "4.39.19"
|
||||||
|
# App
|
||||||
|
vaultwarden: "1.36.0"
|
||||||
|
gitea: "1.26.1"
|
||||||
|
redis: "8.6.3"
|
||||||
|
immich: "v2.7.5"
|
||||||
|
paperless: "2.20.15"
|
||||||
|
manticore: "25.0.0"
|
||||||
|
affine: "0.26.3"
|
||||||
|
nextcloud: "33.0.3"
|
||||||
|
collabora: "25.04.9.4.1"
|
||||||
|
sure: "0.7.0-hotfix.2"
|
||||||
|
|||||||
@@ -21,5 +21,6 @@ node:
|
|||||||
config_path: "{{ node.homelab_path }}/config"
|
config_path: "{{ node.homelab_path }}/config"
|
||||||
ssh_san: "console,console.ilnmors.internal"
|
ssh_san: "console,console.ilnmors.internal"
|
||||||
ssh_users: "vmm,fw,infra,auth,app"
|
ssh_users: "vmm,fw,infra,auth,app"
|
||||||
local_san: "localhost console.ilnmors.internal"
|
# add the hostname of wsl, it is needed to improve the sudo problem
|
||||||
|
local_san: "localhost console.ilnmors.internal surface"
|
||||||
# ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
# ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||||
|
|||||||
@@ -153,6 +153,78 @@
|
|||||||
tags: ["site", "kopia"]
|
tags: ["site", "kopia"]
|
||||||
tags: ["site", "kopia"]
|
tags: ["site", "kopia"]
|
||||||
|
|
||||||
|
- name: Set caddy
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "common"
|
||||||
|
tasks_from: "services/set_caddy"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "caddy"]
|
||||||
|
tags: ["site", "caddy"]
|
||||||
|
|
||||||
|
- name: Set vaultwarden
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_vaultwarden"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "vaultwarden"]
|
||||||
|
tags: ["site", "vaultwarden"]
|
||||||
|
|
||||||
|
- name: Set gitea
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_gitea"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "gitea"]
|
||||||
|
tags: ["site", "gitea"]
|
||||||
|
|
||||||
|
- name: Set immich
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_immich"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "immich"]
|
||||||
|
tags: ["site", "immich"]
|
||||||
|
|
||||||
|
- name: Set paperless
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_paperless"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "paperless"]
|
||||||
|
tags: ["site", "paperless"]
|
||||||
|
|
||||||
|
- name: Set affine
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_affine"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "affine"]
|
||||||
|
tags: ["site", "affine"]
|
||||||
|
|
||||||
|
- name: Set nextcloud
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_nextcloud"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "nextcloud"]
|
||||||
|
tags: ["site", "nextcloud"]
|
||||||
|
|
||||||
|
- name: Set collabora
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_collabora"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "collabora"]
|
||||||
|
tags: ["site", "collabora"]
|
||||||
|
|
||||||
|
- name: Set sure
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: "app"
|
||||||
|
tasks_from: "services/set_sure"
|
||||||
|
apply:
|
||||||
|
tags: ["site", "sure"]
|
||||||
|
tags: ["site", "sure"]
|
||||||
|
|
||||||
- name: Flush handlers right now
|
- name: Flush handlers right now
|
||||||
ansible.builtin.meta: "flush_handlers"
|
ansible.builtin.meta: "flush_handlers"
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@
|
|||||||
become: true
|
become: true
|
||||||
tags: ["init", "site", "install-packages"]
|
tags: ["init", "site", "install-packages"]
|
||||||
|
|
||||||
- name: Install CLI tools
|
- name: Set CLI tools
|
||||||
ansible.builtin.include_role:
|
ansible.builtin.include_role:
|
||||||
name: "console"
|
name: "console"
|
||||||
tasks_from: "services/set_cli_tools"
|
tasks_from: "services/set_cli_tools"
|
||||||
@@ -123,10 +123,10 @@
|
|||||||
tags: ["init", "site", "tools"]
|
tags: ["init", "site", "tools"]
|
||||||
tags: ["init", "site", "tools"]
|
tags: ["init", "site", "tools"]
|
||||||
|
|
||||||
- name: Install chromium with font
|
- name: Set kopia
|
||||||
ansible.builtin.include_role:
|
ansible.builtin.include_role:
|
||||||
name: "console"
|
name: "common"
|
||||||
tasks_from: "services/set_chromium"
|
tasks_from: "services/set_kopia"
|
||||||
apply:
|
apply:
|
||||||
tags: ["init", "site", "chromium"]
|
tags: ["init", "site", "kopia"]
|
||||||
tags: ["init", "site", "chromium"]
|
tags: ["init", "site", "kopia"]
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
- name: Restart vaultwarden
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "vaultwarden.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_vaultwarden"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart gitea
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "gitea.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_gitea"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart immich
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "immich.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_immich"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart immich-ml
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "immich-ml.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_immich-ml"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart paperless
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "paperless.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_paperless"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart affine
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "affine.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_affine_init.stat.exists
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_affine"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart nextcloud
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "nextcloud.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_nextcloud_init.stat.exists
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_nextcloud"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart collabora
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "collabora.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_collabora"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
|
- name: Restart sure
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
scope: "user"
|
||||||
|
daemon_reload: true
|
||||||
|
loop:
|
||||||
|
- "sure-web.service"
|
||||||
|
- "sure-worker.service"
|
||||||
|
changed_when: false
|
||||||
|
listen: "notification_restart_sure"
|
||||||
|
ignore_errors: true # noqa: ignore-errors
|
||||||
@@ -68,3 +68,23 @@
|
|||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy btrfs scrub service and timer
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/app/btrfs/{{ item }}.j2"
|
||||||
|
dest: "/etc/systemd/system/{{ item }}"
|
||||||
|
owner: "root"
|
||||||
|
group: "root"
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- "btrfs-scrub.service"
|
||||||
|
- "btrfs-scrub.timer"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Enable auto btrfs scrub
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "btrfs-scrub.timer"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
become: true
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
---
|
||||||
|
- name: Set manticore service name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
manticore_service: "affine"
|
||||||
|
|
||||||
|
- name: Create manticore directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['manticore']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/manticore"
|
||||||
|
- "data/containers/manticore/{{ manticore_service }}"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy manticore.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/manticore/manticore.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/manticore_{{ manticore_service }}.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_manticore_containerfile"
|
||||||
|
|
||||||
|
- name: Enable (Restart) manticore.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "manticore_{{ manticore_service }}.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_manticore_containerfile.changed # noqa: no-handler
|
||||||
|
|
||||||
|
- name: Set redis service name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
redis_service: "affine"
|
||||||
|
|
||||||
|
- name: Create redis_affine directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['redis']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "containers/redis"
|
||||||
|
- "containers/redis/{{ redis_service }}"
|
||||||
|
- "containers/redis/{{ redis_service }}/data"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy redis config file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_conf"
|
||||||
|
|
||||||
|
- name: Deploy redis container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_containerfile"
|
||||||
|
|
||||||
|
- name: Enable (Restart) redis service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "redis_{{ redis_service }}.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
|
||||||
|
|
||||||
|
- name: Create affine directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/affine"
|
||||||
|
- "containers/affine"
|
||||||
|
- "containers/affine/ssl"
|
||||||
|
- "containers/affine/config"
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/affine/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
notify: "notification_restart_affine"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Register secret value to podman secret
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
data: "{{ item.value }}"
|
||||||
|
state: "present"
|
||||||
|
force: true
|
||||||
|
loop:
|
||||||
|
- name: "AFFINE_PRIVATE_KEY"
|
||||||
|
value: "{{ hostvars['console']['affine']['secret_key'] }}"
|
||||||
|
- name: "AFFINE_DATABASE_URL"
|
||||||
|
value: "postgresql://affine:{{ hostvars['console']['postgresql']['password']['affine'] | urlencode | replace('/', '%2F') }}\
|
||||||
|
@{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}/affine_db?sslmode=verify-full&\
|
||||||
|
sslrootcert=/etc/ssl/affine/{{ root_cert_filename }}"
|
||||||
|
notify: "notification_restart_affine"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Check data directory empty
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ node['home_path'] }}/data/containers/affine/.init"
|
||||||
|
register: "is_affine_init"
|
||||||
|
|
||||||
|
- name: Initialize affine
|
||||||
|
when: not is_affine_init.stat.exists
|
||||||
|
block:
|
||||||
|
- name: Execute init command (Including pulling image)
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "affine_init"
|
||||||
|
image: "ghcr.io/toeverything/affine:{{ version['containers']['affine'] }}"
|
||||||
|
command: ['sh', '-c', 'node ./scripts/self-host-predeploy.js']
|
||||||
|
state: "started"
|
||||||
|
rm: true
|
||||||
|
detach: false
|
||||||
|
secrets:
|
||||||
|
- "AFFINE_DATABASE_URL,type=env,target=DATABASE_URL"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Create .init file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/data/containers/affine/.init"
|
||||||
|
state: "touch"
|
||||||
|
mode: "0644"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
|
||||||
|
- name: Deploy affine.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/affine/affine.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/affine.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_affine"
|
||||||
|
|
||||||
|
- name: Enable affine.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "affine.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
- name: Deploy container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/collabora/collabora.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/collabora.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_collabora"
|
||||||
|
|
||||||
|
- name: Enable collabora.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "collabora.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
- name: Create gitea directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['gitea']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/gitea"
|
||||||
|
- "containers/gitea"
|
||||||
|
- "containers/gitea/ssl"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/gitea/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ services['gitea']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_gitea"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Register secret value to podman secret
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "GITEA__database__PASSWD"
|
||||||
|
data: "{{ hostvars['console']['postgresql']['password']['gitea'] }}"
|
||||||
|
state: "present"
|
||||||
|
force: true
|
||||||
|
notify: "notification_restart_gitea"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Deploy container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/gitea/gitea.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/gitea.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_gitea"
|
||||||
|
|
||||||
|
- name: Enable gitea.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "gitea.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
- name: Set redis service name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
redis_service: "immich"
|
||||||
|
|
||||||
|
- name: Create redis_immich directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['redis']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "containers/redis"
|
||||||
|
- "containers/redis/{{ redis_service }}"
|
||||||
|
- "containers/redis/{{ redis_service }}/data"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy redis config file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_conf"
|
||||||
|
|
||||||
|
- name: Deploy redis container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_containerfile"
|
||||||
|
|
||||||
|
- name: Enable (Restart) redis service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "redis_{{ redis_service }}.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
|
||||||
|
|
||||||
|
- name: Add user in video, render group
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ ansible_user }}"
|
||||||
|
state: "present"
|
||||||
|
groups: "video, render"
|
||||||
|
append: true
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create immich directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/immich"
|
||||||
|
- "containers/immich"
|
||||||
|
- "containers/immich/ssl"
|
||||||
|
- "containers/immich/ml"
|
||||||
|
- "containers/immich/ml/cache"
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/immich/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
notify: "notification_restart_immich"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Register secret value to podman secret
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "IMMICH_DB_PASSWORD"
|
||||||
|
data: "{{ hostvars['console']['postgresql']['password']['immich'] }}"
|
||||||
|
state: "present"
|
||||||
|
force: true
|
||||||
|
notify: "notification_restart_immich"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Deploy immich.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/immich/immich.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/immich.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_immich"
|
||||||
|
|
||||||
|
- name: Deploy immich-ml.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/immich/immich-ml.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/immich-ml.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_immich-ml"
|
||||||
|
|
||||||
|
- name: Enable immich.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "immich.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
|
||||||
|
- name: Enable immich-ml.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "immich-ml.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -0,0 +1,176 @@
|
|||||||
|
---
|
||||||
|
- name: Set redis service name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
redis_service: "nextcloud"
|
||||||
|
|
||||||
|
- name: Create redis_nextcloud directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['redis']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "containers/redis"
|
||||||
|
- "containers/redis/{{ redis_service }}"
|
||||||
|
- "containers/redis/{{ redis_service }}/data"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy redis config file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_conf"
|
||||||
|
|
||||||
|
- name: Deploy redis container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_containerfile"
|
||||||
|
|
||||||
|
- name: Enable (Restart) redis service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "redis_{{ redis_service }}.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
|
||||||
|
|
||||||
|
- name: Create nextcloud directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['nextcloud']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/nextcloud"
|
||||||
|
- "data/containers/nextcloud/html"
|
||||||
|
- "containers/nextcloud"
|
||||||
|
- "containers/nextcloud/ssl"
|
||||||
|
- "containers/nextcloud/ini"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Check data directory empty
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ node['home_path'] }}/data/containers/nextcloud/.init"
|
||||||
|
register: "is_nextcloud_init"
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/nextcloud/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ services['nextcloud']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_nextcloud"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Initialize nextcloud
|
||||||
|
when: not is_nextcloud_init.stat.exists
|
||||||
|
block:
|
||||||
|
- name: Execute init command (Including pulling image)
|
||||||
|
containers.podman.podman_container:
|
||||||
|
name: "nextcloud_init"
|
||||||
|
image: "docker.io/library/nextcloud:{{ version['containers']['nextcloud'] }}"
|
||||||
|
command: "/bin/true"
|
||||||
|
state: "started"
|
||||||
|
rm: true
|
||||||
|
detach: false
|
||||||
|
env:
|
||||||
|
NEXTCLOUD_UPDATE: "1"
|
||||||
|
NEXTCLOUD_ADMIN_USER: "admin-local"
|
||||||
|
NEXTCLOUD_ADMIN_PASSWORD: "{{ hostvars['console']['nextcloud']['admin-local']['password'] }}"
|
||||||
|
POSTGRES_HOST: "{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}"
|
||||||
|
POSTGRES_DB: "nextcloud_db"
|
||||||
|
POSTGRES_USER: "nextcloud"
|
||||||
|
POSTGRES_PASSWORD: "{{ hostvars['console']['postgresql']['password']['nextcloud'] }}"
|
||||||
|
PGSSLMODE: "verify-full"
|
||||||
|
PGSSLROOTCERT: "/etc/ssl/nextcloud/{{ root_cert_filename }}"
|
||||||
|
PGSSLCERTMODE: "disable"
|
||||||
|
REDIS_HOST: "host.containers.internal"
|
||||||
|
REDIS_HOST_PORT: "{{ services['nextcloud']['ports']['redis'] }}"
|
||||||
|
volume:
|
||||||
|
- "{{ node['home_path'] }}/containers/nextcloud/ssl:/etc/ssl/nextcloud:ro"
|
||||||
|
- "{{ node['home_path'] }}/data/containers/nextcloud/html:/var/www/html:rw"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Create .init file
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/data/containers/nextcloud/.init"
|
||||||
|
state: "touch"
|
||||||
|
mode: "0644"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
|
||||||
|
- name: Deploy config files
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/config/{{ item }}.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/data/containers/nextcloud/html/config/{{ item }}"
|
||||||
|
owner: "{{ services['nextcloud']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0640"
|
||||||
|
loop:
|
||||||
|
- "background.config.php"
|
||||||
|
- "cache.config.php"
|
||||||
|
- "domain.config.php"
|
||||||
|
- "local_remote.config.php"
|
||||||
|
- "user_oidc.config.php"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_nextcloud"
|
||||||
|
|
||||||
|
- name: Deploy opcache.ini file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/ini/{{ item }}"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/nextcloud/ini/{{ item }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- "opcache.ini"
|
||||||
|
- "upload.ini"
|
||||||
|
notify: "notification_restart_nextcloud"
|
||||||
|
|
||||||
|
- name: Deploy nextcloud.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/nextcloud.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/nextcloud.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_nextcloud"
|
||||||
|
|
||||||
|
- name: Deploy nextcloud-cron service
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/nextcloud/systemd/{{ item }}"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- "nextcloud-cron.service"
|
||||||
|
- "nextcloud-cron.timer"
|
||||||
|
|
||||||
|
- name: Enable nextcloud.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "nextcloud.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
|
||||||
|
- name: Enable nextcloud-cron.timer
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "nextcloud-cron.timer"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
---
|
||||||
|
- name: Set redis service name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
redis_service: "paperless"
|
||||||
|
|
||||||
|
- name: Create redis_paperless directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['redis']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "containers/redis"
|
||||||
|
- "containers/redis/{{ redis_service }}"
|
||||||
|
- "containers/redis/{{ redis_service }}/data"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy redis config file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_conf"
|
||||||
|
|
||||||
|
- name: Deploy redis container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_containerfile"
|
||||||
|
|
||||||
|
- name: Enable (Restart) redis service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "redis_{{ redis_service }}.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
|
||||||
|
|
||||||
|
- name: Create paperless directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['paperless']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/paperless"
|
||||||
|
- "data/containers/paperless/data"
|
||||||
|
- "data/containers/paperless/media"
|
||||||
|
- "data/containers/paperless/consume"
|
||||||
|
- "containers/paperless"
|
||||||
|
- "containers/paperless/ssl"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/paperless/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ services['paperless']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_paperless"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Register secret value to podman secret
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
data: "{{ item.value }}"
|
||||||
|
state: "present"
|
||||||
|
force: true
|
||||||
|
loop:
|
||||||
|
- name: "PAPERLESS_SECRET_KEY"
|
||||||
|
value: "{{ hostvars['console']['paperless']['session_secret'] }}"
|
||||||
|
- name: "PAPERLESS_DBPASS"
|
||||||
|
value: "{{ hostvars['console']['postgresql']['password']['paperless'] }}"
|
||||||
|
- name: "PAPERLESS_SOCIALACCOUNT_PROVIDERS"
|
||||||
|
value: |-
|
||||||
|
{
|
||||||
|
"openid_connect": {
|
||||||
|
"SCOPE": ["openid", "profile", "email"],
|
||||||
|
"OAUTH_PKCE_ENABLED": true,
|
||||||
|
"APPS": [
|
||||||
|
{
|
||||||
|
"provider_id": "authelia",
|
||||||
|
"name": "Authelia",
|
||||||
|
"client_id": "paperless",
|
||||||
|
"secret": "{{ hostvars['console']['paperless']['oidc']['secret'] }}",
|
||||||
|
"settings": {
|
||||||
|
"server_url": "https://{{ services['authelia']['domain'] }}.{{ domain['public'] }}/.well-known/openid-configuration",
|
||||||
|
"token_auth_method": "client_secret_post"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notify: "notification_restart_paperless"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Deploy paperless.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/paperless/paperless.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/paperless.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_paperless"
|
||||||
|
|
||||||
|
- name: Enable paperless.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "paperless.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
---
|
||||||
|
- name: Set redis service name
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
redis_service: "sure"
|
||||||
|
|
||||||
|
- name: Create redis_sure directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['redis']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "containers/redis"
|
||||||
|
- "containers/redis/{{ redis_service }}"
|
||||||
|
- "containers/redis/{{ redis_service }}/data"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy redis config file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.conf.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/redis/{{ redis_service }}/redis.conf"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_conf"
|
||||||
|
|
||||||
|
- name: Deploy redis container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/redis/redis.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/redis_{{ redis_service }}.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
register: "is_redis_containerfile"
|
||||||
|
|
||||||
|
- name: Enable (Restart) redis service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "redis_{{ redis_service }}.service"
|
||||||
|
state: "restarted"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
when: is_redis_conf.changed or is_redis_containerfile.changed # noqa: no-handler
|
||||||
|
|
||||||
|
- name: Create sure directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ services['sure']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/sure"
|
||||||
|
- "data/containers/sure/storage"
|
||||||
|
- "containers/sure"
|
||||||
|
- "containers/sure/ssl"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/sure/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ services['paperless']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_sure"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Register secret value to podman secret
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
data: "{{ item.value }}"
|
||||||
|
state: "present"
|
||||||
|
force: true
|
||||||
|
loop:
|
||||||
|
- name: "SURE_SECRET_KEY_BASE"
|
||||||
|
value: "{{ hostvars['console']['sure']['session_secret'] }}"
|
||||||
|
- name: "SURE_POSTGRES_PASSWORD"
|
||||||
|
value: "{{ hostvars['console']['postgresql']['password']['sure'] }}"
|
||||||
|
- name: "SURE_OIDC_CLIENT_SECRET"
|
||||||
|
value: "{{ hostvars['console']['sure']['oidc']['secret'] }}"
|
||||||
|
notify: "notification_restart_sure"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Deploy sure.container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/sure/{{ item }}.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/{{ item }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- "sure-web.container"
|
||||||
|
- "sure-worker.container"
|
||||||
|
notify: "notification_restart_sure"
|
||||||
|
|
||||||
|
- name: Enable paperless.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
|
loop:
|
||||||
|
- "sure-web.service"
|
||||||
|
- "sure-worker.service"
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
- name: Create vaultwarden directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/{{ item }}"
|
||||||
|
state: "directory"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0770"
|
||||||
|
loop:
|
||||||
|
- "data/containers/vaultwarden"
|
||||||
|
- "containers/vaultwarden"
|
||||||
|
- "containers/vaultwarden/ssl"
|
||||||
|
|
||||||
|
- name: Deploy root certificate
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
|
dest: "{{ node['home_path'] }}/containers/vaultwarden/ssl/{{ root_cert_filename }}"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_vaultwarden"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Register secret value to podman secret
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
data: "{{ item.value }}"
|
||||||
|
state: "present"
|
||||||
|
force: true
|
||||||
|
loop:
|
||||||
|
- name: "VW_ADMIN_TOKEN"
|
||||||
|
value: "{{ hostvars['console']['vaultwarden']['admin']['hash'] }}"
|
||||||
|
- name: "VW_DATABASE_URL"
|
||||||
|
value: "postgresql://vaultwarden:{{ hostvars['console']['postgresql']['password']['vaultwarden'] | urlencode | replace('/', '%2F') }}\
|
||||||
|
@{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}/vaultwarden_db?sslmode=verify-full&\
|
||||||
|
sslrootcert=/etc/ssl/vaultwarden/{{ root_cert_filename }}"
|
||||||
|
notify: "notification_restart_vaultwarden"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Deploy container file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/app/vaultwarden/vaultwarden.container.j2"
|
||||||
|
dest: "{{ node['home_path'] }}/.config/containers/systemd/vaultwarden.container"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0644"
|
||||||
|
notify: "notification_restart_vaultwarden"
|
||||||
|
|
||||||
|
- name: Enable vaultwarden.service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "vaultwarden.service"
|
||||||
|
state: "started"
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
scope: "user"
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
content: |
|
content: |
|
||||||
{{ hostvars['console']['ca']['root']['crt'] }}
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
dest: "{{ node['home_path'] }}/containers/authelia/certs/ilnmors_root_ca.crt"
|
dest: "{{ node['home_path'] }}/containers/authelia/certs/{{ root_cert_filename }}"
|
||||||
owner: "{{ ansible_user }}"
|
owner: "{{ ansible_user }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
|
|||||||
@@ -27,14 +27,14 @@
|
|||||||
listen: "notification_reload_networkctl"
|
listen: "notification_reload_networkctl"
|
||||||
ignore_errors: true # noqa: ignore-errors
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
- name: Reload systemd-resolved.service
|
- name: Restart systemd-resolved.service
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
name: "systemd-resolved.service"
|
name: "systemd-resolved.service"
|
||||||
state: "reloaded"
|
state: "restarted"
|
||||||
enabled: true
|
enabled: true
|
||||||
become: true
|
become: true
|
||||||
changed_when: false
|
changed_when: false
|
||||||
listen: "notification_reload_resolved"
|
listen: "notification_restart_resolved"
|
||||||
ignore_errors: true # noqa: ignore-errors
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
- name: Restart systemd-timesyncd
|
- name: Restart systemd-timesyncd
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
- name: Deploy root_ca.crt
|
- name: Deploy root_ca.crt
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
content: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
content: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
dest: "/usr/local/share/ca-certificates/ilnmors_root_ca.crt"
|
dest: "/usr/local/share/ca-certificates/{{ root_cert_filename }}"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
group: "systemd-resolve"
|
group: "systemd-resolve"
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
become: true
|
become: true
|
||||||
notify: "notification_reload_resolved"
|
notify: "notification_restart_resolved"
|
||||||
|
|
||||||
- name: Restart systemd-resolved.service when it is initiated
|
- name: Restart systemd-resolved.service when it is initiated
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
- hardware
|
- hardware
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Deploy alloy deb file (x86_64)
|
- name: Download alloy deb file (x86_64)
|
||||||
ansible.builtin.copy:
|
ansible.builtin.get_url:
|
||||||
src: "{{ hostvars['console']['node']['data_path'] }}/bin/alloy-{{ version['packages']['alloy'] }}-amd64.deb"
|
url: "https://github.com/grafana/alloy/releases/download/v{{ version['packages']['alloy'] }}/\
|
||||||
|
alloy-{{ version['packages']['alloy'] }}-1.amd64.deb"
|
||||||
dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
|
dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
@@ -15,9 +16,10 @@
|
|||||||
become: true
|
become: true
|
||||||
when: ansible_facts['architecture'] == "x86_64"
|
when: ansible_facts['architecture'] == "x86_64"
|
||||||
|
|
||||||
- name: Deploy alloy deb file (aarch64)
|
- name: Download alloy deb file (aarch64)
|
||||||
ansible.builtin.copy:
|
ansible.builtin.get_url:
|
||||||
src: "{{ hostvars['console']['node']['data_path'] }}/bin/alloy-{{ version['packages']['alloy'] }}-arm64.deb"
|
url: "https://github.com/grafana/alloy/releases/download/v{{ version['packages']['alloy'] }}/\
|
||||||
|
alloy-{{ version['packages']['alloy'] }}-1.arm64.deb"
|
||||||
dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
|
dest: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
@@ -30,6 +32,7 @@
|
|||||||
deb: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
|
deb: "/var/cache/apt/archives/alloy-{{ version['packages']['alloy'] }}.deb"
|
||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
|
notify: "notification_restart_alloy"
|
||||||
|
|
||||||
- name: Deploy alloy config
|
- name: Deploy alloy config
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
- name: Deploy root crt for build
|
- name: Deploy root crt for build
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
content: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
content: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
dest: "{{ node['home_path'] }}/containers/caddy/build/ilnmors_root_ca.crt"
|
dest: "{{ node['home_path'] }}/containers/caddy/build/{{ root_cert_filename }}"
|
||||||
owner: "{{ ansible_user }}"
|
owner: "{{ ansible_user }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
- name: Build caddy container image
|
- name: Build caddy container image
|
||||||
containers.podman.podman_image:
|
containers.podman.podman_image:
|
||||||
name: "ilnmors.internal/{{ node['name'] }}/caddy"
|
name: "{{ domain['internal'] }}/{{ node['name'] }}/caddy"
|
||||||
# check tags from container file
|
# check tags from container file
|
||||||
tag: "{{ version['containers']['caddy'] }}"
|
tag: "{{ version['containers']['caddy'] }}"
|
||||||
state: "build"
|
state: "build"
|
||||||
|
|||||||
@@ -36,10 +36,15 @@
|
|||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
acquisd_list:
|
acquisd_list:
|
||||||
fw:
|
fw:
|
||||||
collection: "crowdsecurity/suricata"
|
collection:
|
||||||
|
- "crowdsecurity/suricata"
|
||||||
|
parser: []
|
||||||
config: "suricata.yaml"
|
config: "suricata.yaml"
|
||||||
auth:
|
auth:
|
||||||
collection: "crowdsecurity/caddy"
|
collection:
|
||||||
|
- "crowdsecurity/caddy"
|
||||||
|
parser:
|
||||||
|
- "crowdsecurity/nextcloud-whitelist"
|
||||||
config: "caddy.yaml"
|
config: "caddy.yaml"
|
||||||
|
|
||||||
- name: Deploy crowdsec-update service files
|
- name: Deploy crowdsec-update service files
|
||||||
@@ -181,7 +186,8 @@
|
|||||||
block:
|
block:
|
||||||
- name: Install crowdsec collection
|
- name: Install crowdsec collection
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
cmd: "cscli collections install {{ acquisd_list[node['name']]['collection'] }}"
|
cmd: "cscli collections install {{ item }}"
|
||||||
|
loop: "{{ acquisd_list[node['name']]['collection'] }}"
|
||||||
become: true
|
become: true
|
||||||
changed_when: "'overwrite' not in is_collection_installed.stderr"
|
changed_when: "'overwrite' not in is_collection_installed.stderr"
|
||||||
failed_when:
|
failed_when:
|
||||||
@@ -189,6 +195,17 @@
|
|||||||
- "'already installed' not in is_collection_installed.stderr"
|
- "'already installed' not in is_collection_installed.stderr"
|
||||||
register: "is_collection_installed"
|
register: "is_collection_installed"
|
||||||
|
|
||||||
|
- name: Install crowdsec parser
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "cscli parsers install {{ item }}"
|
||||||
|
loop: "{{ acquisd_list[node['name']]['parser'] }}"
|
||||||
|
become: true
|
||||||
|
changed_when: "'overwrite' not in is_parser_installed.stderr"
|
||||||
|
failed_when:
|
||||||
|
- is_parser_installed.rc != 0
|
||||||
|
- "'already installed' not in is_parser_installed.stderr"
|
||||||
|
register: "is_parser_installed"
|
||||||
|
|
||||||
- name: Create crowdsec acquis.d directory
|
- name: Create crowdsec acquis.d directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "/etc/crowdsec/acquis.d"
|
path: "/etc/crowdsec/acquis.d"
|
||||||
|
|||||||
@@ -5,41 +5,43 @@
|
|||||||
- hardware
|
- hardware
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Check kopia installation
|
|
||||||
ansible.builtin.shell: |
|
|
||||||
command -v kopia
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
register: "is_kopia_installed"
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Set console kopia
|
- name: Set console kopia
|
||||||
when: node['name'] == 'console'
|
when: node['name'] == 'console'
|
||||||
block:
|
block:
|
||||||
- name: Apply cli tools (x86_64)
|
- name: Download kopia
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
|
||||||
|
kopia_{{ version['packages']['kopia'] }}_linux_{{ item }}.deb"
|
||||||
|
dest: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-{{ item }}.deb"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0600"
|
||||||
|
loop:
|
||||||
|
- "amd64"
|
||||||
|
- "arm64"
|
||||||
|
|
||||||
|
- name: Install kopia (x86_64)
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb"
|
deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb"
|
||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
when:
|
when: ansible_facts['architecture'] == "x86_64"
|
||||||
- ansible_facts['architecture'] == "x86_64"
|
|
||||||
- is_kopia_installed.rc != 0
|
- name: Install kopia (aarch64)
|
||||||
- name: Apply cli tools (aarch64)
|
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb"
|
deb: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb"
|
||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
when:
|
when: ansible_facts['architecture'] == "aarch64"
|
||||||
- ansible_facts['architecture'] == "aarch64"
|
|
||||||
- is_kopia_installed.rc != 0
|
- name: Connect console kopia server
|
||||||
- name: Connect kopia server
|
|
||||||
environment:
|
environment:
|
||||||
KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['user']['console'] }}"
|
KOPIA_PASSWORD: "{{ hostvars['console']['kopia']['user']['console'] }}"
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
/usr/bin/kopia repository connect server \
|
/usr/bin/kopia repository connect server \
|
||||||
--url=https://{{ infra_uri['kopia']['domain'] }}:{{ infra_uri['kopia']['ports']['https'] }} \
|
--url=https://{{ services['kopia']['domain'] }}.{{ domain['internal'] }}:{{ services['kopia']['ports']['https'] }} \
|
||||||
--override-username=console \
|
--override-username=console \
|
||||||
--override-hostname=console.ilnmors.internal
|
--override-hostname=console.{{ domain['internal'] }}
|
||||||
changed_when: false
|
changed_when: false
|
||||||
failed_when: is_kopia_connected.rc != 0
|
failed_when: is_kopia_connected.rc != 0
|
||||||
register: "is_kopia_connected"
|
register: "is_kopia_connected"
|
||||||
@@ -51,30 +53,36 @@
|
|||||||
- name: Set kopia uid
|
- name: Set kopia uid
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
kopia_uid: 951
|
kopia_uid: 951
|
||||||
- name: Deploy kopia deb file (x86_64)
|
|
||||||
ansible.builtin.copy:
|
- name: Download kopia deb file (x86_64)
|
||||||
src: "{{ hostvars['console']['node']['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-amd64.deb"
|
ansible.builtin.get_url:
|
||||||
|
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
|
||||||
|
kopia_{{ version['packages']['kopia'] }}_linux_amd64.deb"
|
||||||
dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
|
dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
become: true
|
become: true
|
||||||
when: ansible_facts['architecture'] == "x86_64"
|
when: ansible_facts['architecture'] == "x86_64"
|
||||||
- name: Deploy kopia deb file (aarch64)
|
|
||||||
ansible.builtin.copy:
|
- name: Download kopia deb file (aarch64)
|
||||||
src: "{{ hostvars['console']['node']['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-arm64.deb"
|
ansible.builtin.get_url:
|
||||||
|
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
|
||||||
|
kopia_{{ version['packages']['kopia'] }}_linux_arm64.deb"
|
||||||
dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
|
dest: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
mode: "0644"
|
mode: "0644"
|
||||||
become: true
|
become: true
|
||||||
when: ansible_facts['architecture'] == "aarch64"
|
when: ansible_facts['architecture'] == "aarch64"
|
||||||
|
|
||||||
- name: Create kopia group
|
- name: Create kopia group
|
||||||
ansible.builtin.group:
|
ansible.builtin.group:
|
||||||
name: "kopia"
|
name: "kopia"
|
||||||
gid: "{{ kopia_uid }}"
|
gid: "{{ kopia_uid }}"
|
||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Create kopia user
|
- name: Create kopia user
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
name: "kopia"
|
name: "kopia"
|
||||||
@@ -85,6 +93,7 @@
|
|||||||
comment: "Kopia backup User"
|
comment: "Kopia backup User"
|
||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Create kopia directory
|
- name: Create kopia directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ item.name }}"
|
path: "{{ item.name }}"
|
||||||
@@ -101,12 +110,13 @@
|
|||||||
mode: "0700"
|
mode: "0700"
|
||||||
become: true
|
become: true
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Install kopia
|
- name: Install kopia
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
deb: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
|
deb: "/var/cache/apt/archives/kopia-{{ version['packages']['kopia'] }}.deb"
|
||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
when: is_kopia_installed.rc != 0
|
|
||||||
- name: Deploy kopia env
|
- name: Deploy kopia env
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia.env.j2"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/kopia.env.j2"
|
||||||
@@ -116,6 +126,7 @@
|
|||||||
mode: "0400"
|
mode: "0400"
|
||||||
become: true
|
become: true
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Deploy kopia service files
|
- name: Deploy kopia service files
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/{{ item }}.j2"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/common/kopia/{{ item }}.j2"
|
||||||
@@ -128,6 +139,7 @@
|
|||||||
- "kopia-backup.service"
|
- "kopia-backup.service"
|
||||||
- "kopia-backup.timer"
|
- "kopia-backup.timer"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Enable auto kopia rules update
|
- name: Enable auto kopia rules update
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
name: "kopia-backup.timer"
|
name: "kopia-backup.timer"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
state: "directory"
|
state: "directory"
|
||||||
mode: "0700"
|
mode: "0700"
|
||||||
|
|
||||||
- name: Create contaienr data directory for app
|
- name: Create container data directory for app
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/data/containers"
|
path: "{{ node['home_path'] }}/data/containers"
|
||||||
owner: "{{ ansible_user }}"
|
owner: "{{ ansible_user }}"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
become: true
|
become: true
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
content: |
|
content: |
|
||||||
@cert-authority *.ilnmors.internal {{ hostvars['console']['ssh']['ca']['pub'] }}
|
@cert-authority *.{{ domain['internal'] }} {{ hostvars['console']['ssh']['ca']['pub'] }}
|
||||||
dest: "/etc/ssh/ssh_known_hosts"
|
dest: "/etc/ssh/ssh_known_hosts"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
|
|||||||
@@ -49,42 +49,6 @@
|
|||||||
- "amd64"
|
- "amd64"
|
||||||
- "arm64"
|
- "arm64"
|
||||||
|
|
||||||
- name: Download kopia
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: "https://github.com/kopia/kopia/releases/download/v{{ version['packages']['kopia'] }}/\
|
|
||||||
kopia_{{ version['packages']['kopia'] }}_linux_{{ item }}.deb"
|
|
||||||
dest: "{{ node['data_path'] }}/bin/kopia-{{ version['packages']['kopia'] }}-{{ item }}.deb"
|
|
||||||
owner: "{{ ansible_user }}"
|
|
||||||
group: "svadmins"
|
|
||||||
mode: "0600"
|
|
||||||
loop:
|
|
||||||
- "amd64"
|
|
||||||
- "arm64"
|
|
||||||
|
|
||||||
- name: Download blocky
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: "https://github.com/0xERR0R/blocky/releases/download/v{{ version['packages']['blocky'] }}/\
|
|
||||||
blocky_v{{ version['packages']['blocky'] }}_Linux_{{ item }}.tar.gz"
|
|
||||||
dest: "{{ node['data_path'] }}/bin/blocky-{{ version['packages']['blocky'] }}-{{ item }}.tar.gz"
|
|
||||||
owner: "{{ ansible_user }}"
|
|
||||||
group: "svadmins"
|
|
||||||
mode: "0600" # noqa: line-length
|
|
||||||
loop:
|
|
||||||
- "x86_64"
|
|
||||||
- "arm64"
|
|
||||||
|
|
||||||
- name: Download alloy
|
|
||||||
ansible.builtin.get_url:
|
|
||||||
url: "https://github.com/grafana/alloy/releases/download/v{{ version['packages']['alloy'] }}/\
|
|
||||||
alloy-{{ version['packages']['alloy'] }}-1.{{ item }}.deb"
|
|
||||||
dest: "{{ node['data_path'] }}/bin/alloy-{{ version['packages']['alloy'] }}-{{ item }}.deb"
|
|
||||||
owner: "{{ ansible_user }}"
|
|
||||||
group: "svadmins"
|
|
||||||
mode: "0600"
|
|
||||||
loop:
|
|
||||||
- "amd64"
|
|
||||||
- "arm64"
|
|
||||||
|
|
||||||
- name: Apply cli tools (x86_64)
|
- name: Apply cli tools (x86_64)
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
deb: "{{ node['data_path'] }}/bin/{{ item }}"
|
deb: "{{ node['data_path'] }}/bin/{{ item }}"
|
||||||
@@ -92,7 +56,6 @@
|
|||||||
loop:
|
loop:
|
||||||
- "sops-{{ version['packages']['sops'] }}-amd64.deb"
|
- "sops-{{ version['packages']['sops'] }}-amd64.deb"
|
||||||
- "step-{{ version['packages']['step'] }}-amd64.deb"
|
- "step-{{ version['packages']['step'] }}-amd64.deb"
|
||||||
- "kopia-{{ version['packages']['kopia'] }}-amd64.deb"
|
|
||||||
become: true
|
become: true
|
||||||
when: ansible_facts['architecture'] == "x86_64"
|
when: ansible_facts['architecture'] == "x86_64"
|
||||||
|
|
||||||
@@ -103,6 +66,5 @@
|
|||||||
loop:
|
loop:
|
||||||
- "sops-{{ version['packages']['sops'] }}-arm64.deb"
|
- "sops-{{ version['packages']['sops'] }}-arm64.deb"
|
||||||
- "step-{{ version['packages']['step'] }}-arm64.deb"
|
- "step-{{ version['packages']['step'] }}-arm64.deb"
|
||||||
- "kopia-{{ version['packages']['kopia'] }}-arm64.deb"
|
|
||||||
become: true
|
become: true
|
||||||
when: ansible_facts['architecture'] == "aarch64"
|
when: ansible_facts['architecture'] == "aarch64"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
state: "present"
|
state: "present"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Create blocky etc directory
|
- name: Create blocky directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
owner: "blocky"
|
owner: "blocky"
|
||||||
@@ -31,13 +31,38 @@
|
|||||||
mode: "0750"
|
mode: "0750"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
loop:
|
loop:
|
||||||
|
- "/home/blocky"
|
||||||
|
- "/home/blocky/bin"
|
||||||
- "/etc/blocky"
|
- "/etc/blocky"
|
||||||
- "/etc/blocky/ssl"
|
- "/etc/blocky/ssl"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
|
- name: Download blocky (x86_64)
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "https://github.com/0xERR0R/blocky/releases/download/v{{ version['packages']['blocky'] }}/\
|
||||||
|
blocky_v{{ version['packages']['blocky'] }}_Linux_x86_64.tar.gz"
|
||||||
|
dest: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}-x86_64.tar.gz"
|
||||||
|
owner: "blocky"
|
||||||
|
group: "blocky"
|
||||||
|
mode: "0600"
|
||||||
|
become: true
|
||||||
|
when: ansible_facts['architecture'] == "x86_64"
|
||||||
|
|
||||||
|
- name: Download blocky (aarch64)
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "https://github.com/0xERR0R/blocky/releases/download/v{{ version['packages']['blocky'] }}/\
|
||||||
|
blocky_v{{ version['packages']['blocky'] }}_Linux_arm64.tar.gz"
|
||||||
|
dest: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}-arm64.tar.gz"
|
||||||
|
owner: "blocky"
|
||||||
|
group: "blocky"
|
||||||
|
mode: "0600"
|
||||||
|
become: true
|
||||||
|
when: ansible_facts['architecture'] == "aarch64"
|
||||||
|
|
||||||
- name: Deploy blocky binary file (x86_64)
|
- name: Deploy blocky binary file (x86_64)
|
||||||
ansible.builtin.unarchive:
|
ansible.builtin.unarchive:
|
||||||
src: "{{ hostvars['console']['node']['data_path'] }}/bin/blocky-{{ version['packages']['blocky'] }}-x86_64.tar.gz"
|
src: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}-x86_64.tar.gz"
|
||||||
|
remote_src: true
|
||||||
dest: "/usr/local/bin/"
|
dest: "/usr/local/bin/"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
@@ -52,7 +77,8 @@
|
|||||||
|
|
||||||
- name: Deploy blocky binary file (aarch64)
|
- name: Deploy blocky binary file (aarch64)
|
||||||
ansible.builtin.unarchive:
|
ansible.builtin.unarchive:
|
||||||
src: "{{ hostvars['console']['node']['data_path'] }}/bin/blocky-{{ version['packages']['blocky'] }}-arm64.tar.gz"
|
src: "/home/blocky/bin/blocky-{{ version['packages']['blocky'] }}-arm64.tar.gz"
|
||||||
|
remote_src: true
|
||||||
dest: "/usr/local/bin/"
|
dest: "/usr/local/bin/"
|
||||||
owner: "root"
|
owner: "root"
|
||||||
group: "root"
|
group: "root"
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Deploy ddns service files
|
- name: Deploy ddns service files
|
||||||
ansible.builtin.copy:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/fw/ddns/{{ item }}"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/systemd/fw/ddns/{{ item }}.j2"
|
||||||
dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}"
|
dest: "{{ node['home_path'] }}/.config/systemd/user/{{ item }}"
|
||||||
owner: "{{ ansible_user }}"
|
owner: "{{ ansible_user }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
- name: Reload postgresql
|
- name: Reload postgresql
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
/usr/bin/podman exec -u postgres postgresql sh -c "pg_ctl reload"
|
/usr/bin/podman exec -u postgres postgresql sh -c "pg_ctl reload"
|
||||||
when: not (is_postgresql_init_run | default(false))
|
when: is_postgresql_init.stat.exists
|
||||||
changed_when: false
|
changed_when: false
|
||||||
listen: "notification_reload_postgresql"
|
listen: "notification_reload_postgresql"
|
||||||
ignore_errors: true # noqa: ignore-errors
|
ignore_errors: true # noqa: ignore-errors
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
enabled: true
|
enabled: true
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
scope: "user"
|
scope: "user"
|
||||||
when: not (is_postgresql_init_run | default(false))
|
when: is_postgresql_init.stat.exists
|
||||||
changed_when: false
|
changed_when: false
|
||||||
listen: "notification_restart_postgresql"
|
listen: "notification_restart_postgresql"
|
||||||
ignore_errors: true # noqa: ignore-errors
|
ignore_errors: true # noqa: ignore-errors
|
||||||
@@ -73,10 +73,10 @@
|
|||||||
listen: "notification_restart_grafana"
|
listen: "notification_restart_grafana"
|
||||||
ignore_errors: true # noqa: ignore-errors
|
ignore_errors: true # noqa: ignore-errors
|
||||||
|
|
||||||
- name: Enable x509-exporter.service
|
- name: Restart x509-exporter.service
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
name: "x509-exporter.service"
|
name: "x509-exporter.service"
|
||||||
state: "started"
|
state: "restarted"
|
||||||
enabled: true
|
enabled: true
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
scope: "user"
|
scope: "user"
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Set ca container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
ca_subuid: "100999"
|
|
||||||
|
|
||||||
- name: Create ca directory
|
- name: Create ca directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
owner: "{{ ca_subuid }}"
|
owner: "{{ services['ca']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
@@ -32,7 +28,7 @@
|
|||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ca/config/{{ item }}.j2"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/ca/config/{{ item }}.j2"
|
||||||
dest: "{{ node['home_path'] }}/containers/ca/config/{{ item }}"
|
dest: "{{ node['home_path'] }}/containers/ca/config/{{ item }}"
|
||||||
owner: "{{ ca_subuid }}"
|
owner: "{{ services['ca']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0400"
|
mode: "0400"
|
||||||
loop:
|
loop:
|
||||||
@@ -46,19 +42,19 @@
|
|||||||
content: |
|
content: |
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
dest: "{{ item.path }}/{{ item.name }}"
|
dest: "{{ item.path }}/{{ item.name }}"
|
||||||
owner: "{{ ca_subuid }}"
|
owner: "{{ services['ca']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "{{ item.mode }}"
|
mode: "{{ item.mode }}"
|
||||||
loop:
|
loop:
|
||||||
- name: "ilnmors_root_ca.crt"
|
- name: "{{ root_cert_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
path: "{{ node['home_path'] }}/containers/ca/certs"
|
path: "{{ node['home_path'] }}/containers/ca/certs"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
- name: "ilnmors_intermediate_ca.crt"
|
- name: "{{ intermediate_cert_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['intermediate']['crt'] }}"
|
value: "{{ hostvars['console']['ca']['intermediate']['crt'] }}"
|
||||||
path: "{{ node['home_path'] }}/containers/ca/certs"
|
path: "{{ node['home_path'] }}/containers/ca/certs"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
- name: "ilnmors_intermediate_ca.key"
|
- name: "{{ intermediate_key_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['intermediate']['key'] }}"
|
value: "{{ hostvars['console']['ca']['intermediate']['key'] }}"
|
||||||
path: "{{ node['home_path'] }}/containers/ca/secrets"
|
path: "{{ node['home_path'] }}/containers/ca/secrets"
|
||||||
mode: "0400"
|
mode: "0400"
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Set grafana container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
grafana_subuid: "100471"
|
|
||||||
|
|
||||||
- name: Create grafana directory
|
- name: Create grafana directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
owner: "{{ grafana_subuid }}"
|
owner: "{{ services['grafana']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
@@ -23,8 +19,8 @@
|
|||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
content: |
|
content: |
|
||||||
{{ hostvars['console']['ca']['root']['crt'] }}
|
{{ hostvars['console']['ca']['root']['crt'] }}
|
||||||
dest: "{{ node['home_path'] }}/containers/grafana/ssl/ilnmors_root_ca.crt"
|
dest: "{{ node['home_path'] }}/containers/grafana/ssl/{{ root_cert_filename }}"
|
||||||
owner: "{{ grafana_subuid }}"
|
owner: "{{ services['grafana']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0400"
|
mode: "0400"
|
||||||
become: true
|
become: true
|
||||||
@@ -51,7 +47,7 @@
|
|||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/{{ item }}.j2"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/{{ item }}.j2"
|
||||||
dest: "{{ node['home_path'] }}/containers/grafana/etc/{{ item }}"
|
dest: "{{ node['home_path'] }}/containers/grafana/etc/{{ item }}"
|
||||||
owner: "{{ grafana_subuid }}"
|
owner: "{{ services['grafana']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0400"
|
mode: "0400"
|
||||||
loop:
|
loop:
|
||||||
@@ -61,11 +57,11 @@
|
|||||||
notify: "notification_restart_grafana"
|
notify: "notification_restart_grafana"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Deploy provisioing and dashboard files
|
- name: Deploy provisioing file
|
||||||
ansible.builtin.copy:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/provisioning/"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/grafana/etc/provisioning/datasources/datasources.yaml.j2"
|
||||||
dest: "{{ node['home_path'] }}/containers/grafana/etc/provisioning/"
|
dest: "{{ node['home_path'] }}/containers/grafana/etc/provisioning/datasources/datasources.yaml"
|
||||||
owner: "{{ grafana_subuid }}"
|
owner: "{{ services['grafana']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0400"
|
mode: "0400"
|
||||||
become: true
|
become: true
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Set ldap container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
ldap_subuid: "100999"
|
|
||||||
|
|
||||||
- name: Create ldap directory
|
- name: Create ldap directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
owner: "{{ ldap_subuid }}"
|
owner: "{{ services['ldap']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
@@ -21,11 +17,11 @@
|
|||||||
content: |
|
content: |
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
dest: "{{ node['home_path'] }}/containers/ldap/ssl/{{ item.name }}"
|
dest: "{{ node['home_path'] }}/containers/ldap/ssl/{{ item.name }}"
|
||||||
owner: "{{ ldap_subuid }}"
|
owner: "{{ services['ldap']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "{{ item.mode }}"
|
mode: "{{ item.mode }}"
|
||||||
loop:
|
loop:
|
||||||
- name: "ilnmors_root_ca.crt"
|
- name: "{{ root_cert_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
- name: "ldap.crt"
|
- name: "ldap.crt"
|
||||||
@@ -50,7 +46,7 @@
|
|||||||
# urlencode doesn't fix `/` as `%2F`. It needs replace
|
# urlencode doesn't fix `/` as `%2F`. It needs replace
|
||||||
- name: "LLDAP_DATABASE_URL"
|
- name: "LLDAP_DATABASE_URL"
|
||||||
value: "postgres://ldap:{{ hostvars['console']['postgresql']['password']['ldap'] | urlencode | replace('/', '%2F') }}\
|
value: "postgres://ldap:{{ hostvars['console']['postgresql']['password']['ldap'] | urlencode | replace('/', '%2F') }}\
|
||||||
@{{ infra_uri['postgresql']['domain'] }}/ldap_db?sslmode=verify-full&sslrootcert=/etc/ssl/ldap/ilnmors_root_ca.crt"
|
@{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}/ldap_db?sslmode=verify-full&sslrootcert=/etc/ssl/ldap/{{ root_cert_filename }}"
|
||||||
- name: "LLDAP_KEY_SEED"
|
- name: "LLDAP_KEY_SEED"
|
||||||
value: "{{ hostvars['console']['ldap']['seed_key'] }}"
|
value: "{{ hostvars['console']['ldap']['seed_key'] }}"
|
||||||
- name: "LLDAP_JWT_SECRET"
|
- name: "LLDAP_JWT_SECRET"
|
||||||
@@ -59,6 +55,8 @@
|
|||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Initiate ldap (When = false, If DB data does not exist in postgresql, activate this block)
|
- name: Initiate ldap (When = false, If DB data does not exist in postgresql, activate this block)
|
||||||
|
# The reason why this task doesn't use the way to check ".init" file is this tasks can override original database.
|
||||||
|
# Absent of ".init" file cannot guarantee DB is empty.
|
||||||
when: false
|
when: false
|
||||||
become: true
|
become: true
|
||||||
block:
|
block:
|
||||||
@@ -78,7 +76,7 @@
|
|||||||
detach: false
|
detach: false
|
||||||
env:
|
env:
|
||||||
TZ: "Asia/Seoul"
|
TZ: "Asia/Seoul"
|
||||||
LLDAP_LDAP_BASE_DN: "dc=ilnmors,dc=internal"
|
LLDAP_LDAP_BASE_DN: "{{ domain['dc'] }}"
|
||||||
secrets:
|
secrets:
|
||||||
- "LLDAP_DATABASE_URL,type=env"
|
- "LLDAP_DATABASE_URL,type=env"
|
||||||
- "LLDAP_KEY_SEED,type=env"
|
- "LLDAP_KEY_SEED,type=env"
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
- name: Set loki container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
loki_subuid: "110000" # 10001
|
|
||||||
|
|
||||||
- name: Create loki directory
|
- name: Create loki directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
owner: "{{ loki_subuid }}"
|
owner: "{{ services['loki']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
loop:
|
loop:
|
||||||
@@ -18,10 +14,10 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Deploy loki configuration file
|
- name: Deploy loki configuration file
|
||||||
ansible.builtin.copy:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/loki/etc/loki.yaml"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/loki/etc/loki.yaml.j2"
|
||||||
dest: "{{ node['home_path'] }}/containers/loki/etc/loki.yaml"
|
dest: "{{ node['home_path'] }}/containers/loki/etc/loki.yaml"
|
||||||
owner: "{{ loki_subuid }}"
|
owner: "{{ services['loki']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
become: true
|
become: true
|
||||||
@@ -33,11 +29,11 @@
|
|||||||
content: |
|
content: |
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
dest: "{{ node['home_path'] }}/containers/loki/ssl/{{ item.name }}"
|
dest: "{{ node['home_path'] }}/containers/loki/ssl/{{ item.name }}"
|
||||||
owner: "{{ loki_subuid }}"
|
owner: "{{ services['loki']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "{{ item.mode }}"
|
mode: "{{ item.mode }}"
|
||||||
loop:
|
loop:
|
||||||
- name: "ilnmors_root_ca.crt"
|
- name: "{{ root_cert_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
- name: "loki.crt"
|
- name: "loki.crt"
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
---
|
---
|
||||||
- name: Set postgresql container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
postgresql_subuid: "100998"
|
|
||||||
|
|
||||||
- name: Set connected services list
|
- name: Set connected services list
|
||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
# telegraf has no database
|
|
||||||
connected_services:
|
connected_services:
|
||||||
- "ldap"
|
- "ldap"
|
||||||
- "authelia"
|
- "authelia"
|
||||||
- "grafana"
|
- "grafana"
|
||||||
|
- "vaultwarden"
|
||||||
|
- "gitea"
|
||||||
|
- "immich"
|
||||||
|
- "paperless"
|
||||||
|
- "affine"
|
||||||
|
- "nextcloud"
|
||||||
|
- "sure"
|
||||||
|
|
||||||
- name: Create postgresql directory
|
- name: Create postgresql directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
owner: "{{ postgresql_subuid }}"
|
owner: "{{ services['postgresql']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
loop:
|
loop:
|
||||||
@@ -38,7 +40,7 @@
|
|||||||
|
|
||||||
- name: Build postgresql container image
|
- name: Build postgresql container image
|
||||||
containers.podman.podman_image:
|
containers.podman.podman_image:
|
||||||
name: "ilnmors.internal/{{ node['name'] }}/postgres"
|
name: "{{ domain['internal'] }}/{{ node['name'] }}/postgres"
|
||||||
# check tags from container file
|
# check tags from container file
|
||||||
tag: "pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}"
|
tag: "pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}"
|
||||||
state: "build"
|
state: "build"
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/config/{{ item }}.j2"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/config/{{ item }}.j2"
|
||||||
dest: "{{ node['home_path'] }}/containers/postgresql/config/{{ item }}"
|
dest: "{{ node['home_path'] }}/containers/postgresql/config/{{ item }}"
|
||||||
owner: "{{ postgresql_subuid }}"
|
owner: "{{ services['postgresql']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
loop:
|
loop:
|
||||||
@@ -67,11 +69,11 @@
|
|||||||
content: |
|
content: |
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
dest: "{{ node['home_path'] }}/containers/postgresql/ssl/{{ item.name }}"
|
dest: "{{ node['home_path'] }}/containers/postgresql/ssl/{{ item.name }}"
|
||||||
owner: "{{ postgresql_subuid }}"
|
owner: "{{ services['postgresql']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "{{ item.mode }}"
|
mode: "{{ item.mode }}"
|
||||||
loop:
|
loop:
|
||||||
- name: "ilnmors_root_ca.crt"
|
- name: "{{ root_cert_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
- name: "postgresql.crt"
|
- name: "postgresql.crt"
|
||||||
@@ -87,15 +89,13 @@
|
|||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
- name: Check data directory empty
|
- name: Check data directory empty
|
||||||
ansible.builtin.find:
|
ansible.builtin.stat:
|
||||||
paths: "{{ node['home_path'] }}/containers/postgresql/data/"
|
path: "{{ node['home_path'] }}/containers/postgresql/data/.init"
|
||||||
hidden: true
|
|
||||||
file_type: "any"
|
|
||||||
become: true
|
become: true
|
||||||
register: "is_data_dir_empty"
|
register: "is_postgresql_init"
|
||||||
|
|
||||||
- name: Prepare initiating DB
|
- name: Prepare initiating DB
|
||||||
when: is_data_dir_empty.matched == 0
|
when: not is_postgresql_init.stat.exists
|
||||||
become: true
|
become: true
|
||||||
block:
|
block:
|
||||||
# `init/pg_cluster.sql` should be fetched from postgresql's backup directory before running initiating
|
# `init/pg_cluster.sql` should be fetched from postgresql's backup directory before running initiating
|
||||||
@@ -103,23 +103,28 @@
|
|||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_cluster.sql"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_cluster.sql"
|
||||||
dest: "{{ node['home_path'] }}/containers/postgresql/init/0_pg_cluster.sql"
|
dest: "{{ node['home_path'] }}/containers/postgresql/init/0_pg_cluster.sql"
|
||||||
owner: "{{ postgresql_subuid }}"
|
owner: "{{ services['postgresql']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
|
|
||||||
- name: Deploy resoring data sql files
|
- name: Deploy restoring data sql files
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_{{ item }}.sql"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/postgresql/init/pg_{{ item }}.sql"
|
||||||
dest: "{{ node['home_path'] }}/containers/postgresql/init/{{ index_num + 1 }}_pg_{{ item }}.sql"
|
dest: "{{ node['home_path'] }}/containers/postgresql/init/{{ index_num + 1 }}_pg_{{ item }}.sql"
|
||||||
owner: "{{ postgresql_subuid }}"
|
owner: "{{ services['postgresql']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
loop: "{{ connected_services }}"
|
loop: "{{ connected_services }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
index_var: index_num
|
index_var: index_num
|
||||||
- name: Set is_postgresql_init_run
|
|
||||||
ansible.builtin.set_fact:
|
- name: Create .init file
|
||||||
is_postgresql_init_run: true
|
ansible.builtin.file:
|
||||||
|
path: "{{ node['home_path'] }}/containers/postgresql/data/.init"
|
||||||
|
state: "touch"
|
||||||
|
mode: "0644"
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "svadmins"
|
||||||
|
|
||||||
- name: Deploy container file
|
- name: Deploy container file
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
---
|
---
|
||||||
- name: Set prometheus container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
prometheus_subuid: "165533" # nobody - 65534
|
|
||||||
|
|
||||||
- name: Create prometheus directory
|
- name: Create prometheus directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
owner: "{{ prometheus_subuid }}"
|
owner: "{{ services['prometheus']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
loop:
|
loop:
|
||||||
@@ -21,7 +17,7 @@
|
|||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/prometheus/etc/{{ item }}.j2"
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/prometheus/etc/{{ item }}.j2"
|
||||||
dest: "{{ node['home_path'] }}/containers/prometheus/etc/{{ item }}"
|
dest: "{{ node['home_path'] }}/containers/prometheus/etc/{{ item }}"
|
||||||
owner: "{{ prometheus_subuid }}"
|
owner: "{{ services['prometheus']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0600"
|
mode: "0600"
|
||||||
loop:
|
loop:
|
||||||
@@ -37,11 +33,11 @@
|
|||||||
content: |
|
content: |
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
dest: "{{ node['home_path'] }}/containers/prometheus/ssl/{{ item.name }}"
|
dest: "{{ node['home_path'] }}/containers/prometheus/ssl/{{ item.name }}"
|
||||||
owner: "{{ prometheus_subuid }}"
|
owner: "{{ services['prometheus']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "{{ item.mode }}"
|
mode: "{{ item.mode }}"
|
||||||
loop:
|
loop:
|
||||||
- name: "ilnmors_root_ca.crt"
|
- name: "{{ root_cert_filename }}"
|
||||||
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
value: "{{ hostvars['console']['ca']['root']['crt'] }}"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
- name: "prometheus.crt"
|
- name: "prometheus.crt"
|
||||||
|
|||||||
@@ -1,26 +1,33 @@
|
|||||||
---
|
---
|
||||||
- name: Set x509-exporter container subuid
|
|
||||||
ansible.builtin.set_fact:
|
|
||||||
x509_exporter_subuid: "165533" # nobody - 65534
|
|
||||||
|
|
||||||
- name: Create x509-exporter directory
|
- name: Create x509-exporter directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
path: "{{ node['home_path'] }}/containers/{{ item }}"
|
||||||
state: "directory"
|
state: "directory"
|
||||||
owner: "{{ x509_exporter_subuid }}"
|
owner: "{{ services['x509-exporter']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0770"
|
mode: "0770"
|
||||||
loop:
|
loop:
|
||||||
- "x509-exporter"
|
- "x509-exporter"
|
||||||
|
- "x509-exporter/config"
|
||||||
- "x509-exporter/certs"
|
- "x509-exporter/certs"
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy config.yaml
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ hostvars['console']['node']['config_path'] }}/services/containers/infra/x509-exporter/config/config.yaml"
|
||||||
|
dest: "{{ node['home_path'] }}/containers/x509-exporter/config/config.yaml"
|
||||||
|
owner: "{{ services['x509-exporter']['subuid'] }}"
|
||||||
|
group: "svadmins"
|
||||||
|
mode: "0440"
|
||||||
|
become: true
|
||||||
|
notify: "notification_restart_x509-exporter"
|
||||||
|
|
||||||
- name: Deploy certificates
|
- name: Deploy certificates
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
content: |
|
content: |
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
dest: "{{ node['home_path'] }}/containers/x509-exporter/certs/{{ item.name }}"
|
dest: "{{ node['home_path'] }}/containers/x509-exporter/certs/{{ item.name }}"
|
||||||
owner: "{{ x509_exporter_subuid }}"
|
owner: "{{ services['x509-exporter']['subuid'] }}"
|
||||||
group: "svadmins"
|
group: "svadmins"
|
||||||
mode: "0440"
|
mode: "0440"
|
||||||
loop:
|
loop:
|
||||||
|
|||||||
@@ -5,17 +5,27 @@ define NET4_SERVER = {{ hostvars['fw']['network4']['subnet']['server'] }}
|
|||||||
define NET6_SERVER = {{ hostvars['fw']['network6']['subnet']['server'] }}
|
define NET6_SERVER = {{ hostvars['fw']['network6']['subnet']['server'] }}
|
||||||
define HOSTS4_CONSOLE = { {{ hostvars['fw']['network4']['console'].values() | join(', ') }} }
|
define HOSTS4_CONSOLE = { {{ hostvars['fw']['network4']['console'].values() | join(', ') }} }
|
||||||
define HOSTS6_CONSOLE = { {{ hostvars['fw']['network6']['console'].values() | join(', ') }} }
|
define HOSTS6_CONSOLE = { {{ hostvars['fw']['network6']['console'].values() | join(', ') }} }
|
||||||
|
define HOSTS4_AUTH = {{ hostvars['fw']['network4']['auth']['server'] }}
|
||||||
|
define HOSTS6_AUTH = {{ hostvars['fw']['network6']['auth']['server'] }}
|
||||||
define PORTS_SSH = 22
|
define PORTS_SSH = 22
|
||||||
|
define PORTS_HTTP = 80
|
||||||
|
define PORTS_HTTP_FORWARD = 2080
|
||||||
|
define PORTS_HTTPS = 443
|
||||||
|
define PORTS_HTTPS_FORWARD = 2443
|
||||||
|
|
||||||
table inet nat {
|
table inet nat {
|
||||||
chain prerouting {
|
chain prerouting {
|
||||||
type nat hook prerouting priority dstnat; policy accept;
|
type nat hook prerouting priority dstnat; policy accept;
|
||||||
|
tcp dport $PORTS_HTTP dnat to :$PORTS_HTTP_FORWARD comment "dnat http ports to $PORTS_HTTP_FORWARD"
|
||||||
|
tcp dport $PORTS_HTTPS dnat to :$PORTS_HTTPS_FORWARD comment "dnat https ports to $PORTS_HTTPS_FORWARD"
|
||||||
}
|
}
|
||||||
chain postrouting {
|
chain postrouting {
|
||||||
|
|
||||||
}
|
}
|
||||||
chain output {
|
chain output {
|
||||||
type nat hook output priority dstnat; policy accept;
|
type nat hook output priority dstnat; policy accept;
|
||||||
|
oifname "lo" tcp dport $PORTS_HTTP dnat to :$PORTS_HTTP_FORWARD comment "dnat http ports to $PORTS_HTTP_FORWARD out of LOCALHOST"
|
||||||
|
oifname "lo" tcp dport $PORTS_HTTPS dnat to :$PORTS_HTTPS_FORWARD comment "dnat https ports to $PORTS_HTTPS_FORWARD out of LOCALHOST"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,6 +38,10 @@ table inet filter {
|
|||||||
meta l4proto { icmp, icmpv6 } accept comment "allow icmp connection"
|
meta l4proto { icmp, icmpv6 } accept comment "allow icmp connection"
|
||||||
ip saddr $HOSTS4_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv4 ssh connection: CONSOLE > APP"
|
ip saddr $HOSTS4_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv4 ssh connection: CONSOLE > APP"
|
||||||
ip6 saddr $HOSTS6_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv6 ssh connection: CONSOLE > APP"
|
ip6 saddr $HOSTS6_CONSOLE tcp dport $PORTS_SSH accept comment "allow ipv6 ssh connection: CONSOLE > APP"
|
||||||
|
ip saddr { $HOSTS4_CONSOLE, $HOSTS4_AUTH } tcp dport $PORTS_HTTP_FORWARD ct original proto-dst $PORTS_HTTP accept comment "allow ipv4 http connection: CONSOLE, AUTH > APP"
|
||||||
|
ip6 saddr { $HOSTS6_CONSOLE, $HOSTS6_AUTH } tcp dport $PORTS_HTTP_FORWARD ct original proto-dst $PORTS_HTTP accept comment "allow ipv6 http connection: CONSOLE, AUTH > APP"
|
||||||
|
ip saddr { $HOSTS4_CONSOLE, $HOSTS4_AUTH } tcp dport $PORTS_HTTPS_FORWARD ct original proto-dst $PORTS_HTTPS accept comment "allow ipv4 https connection: CONSOLE, AUTH > APP"
|
||||||
|
ip6 saddr { $HOSTS6_CONSOLE, $HOSTS6_AUTH } tcp dport $PORTS_HTTPS_FORWARD ct original proto-dst $PORTS_HTTPS accept comment "allow ipv6 https connection: CONSOLE, AUTH > APP"
|
||||||
}
|
}
|
||||||
chain forward {
|
chain forward {
|
||||||
type filter hook forward priority 0; policy drop;
|
type filter hook forward priority 0; policy drop;
|
||||||
|
|||||||
+20
-20
@@ -3,32 +3,32 @@
|
|||||||
::1 {{ node['local_san'] }}
|
::1 {{ node['local_san'] }}
|
||||||
{% if node['name'] == 'console' %}
|
{% if node['name'] == 'console' %}
|
||||||
# Hosts IPv4
|
# Hosts IPv4
|
||||||
{{ hostvars['fw']['network4']['firewall']['server'] }} fw.ilnmors.internal
|
{{ hostvars['fw']['network4']['firewall']['server'] }} fw.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['vmm']['client'] }} init.vmm.ilnmors.internal
|
{{ hostvars['fw']['network4']['vmm']['client'] }} init.vmm.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['vmm']['server'] }} vmm.ilnmors.internal
|
{{ hostvars['fw']['network4']['vmm']['server'] }} vmm.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['infra']['server'] }} infra.ilnmors.internal
|
{{ hostvars['fw']['network4']['infra']['server'] }} infra.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['auth']['server'] }} auth.ilnmors.internal
|
{{ hostvars['fw']['network4']['auth']['server'] }} auth.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['app']['server'] }} app.ilnmors.internal
|
{{ hostvars['fw']['network4']['app']['server'] }} app.{{ domain['internal'] }}
|
||||||
# Hosts IPv6
|
# Hosts IPv6
|
||||||
{{ hostvars['fw']['network6']['firewall']['server'] }} fw.ilnmors.internal
|
{{ hostvars['fw']['network6']['firewall']['server'] }} fw.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['vmm']['client'] }} init.vmm.ilnmors.internal
|
{{ hostvars['fw']['network6']['vmm']['client'] }} init.vmm.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['vmm']['server'] }} vmm.ilnmors.internal
|
{{ hostvars['fw']['network6']['vmm']['server'] }} vmm.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['infra']['server'] }} infra.ilnmors.internal
|
{{ hostvars['fw']['network6']['infra']['server'] }} infra.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['auth']['server'] }} auth.ilnmors.internal
|
{{ hostvars['fw']['network6']['auth']['server'] }} auth.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['app']['server'] }} app.ilnmors.internal
|
{{ hostvars['fw']['network6']['app']['server'] }} app.{{ domain['internal'] }}
|
||||||
{% else %}
|
{% else %}
|
||||||
# IPv4
|
# IPv4
|
||||||
# Crowdsec, blocky, bind(fw)
|
# Crowdsec, blocky, bind(fw)
|
||||||
{{ hostvars['fw']['network4']['firewall']['server'] }} ntp.ilnmors.internal crowdsec.ilnmors.internal
|
{{ hostvars['fw']['network4']['firewall']['server'] }} ntp.{{ domain['internal'] }} crowdsec.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['blocky']['server'] }} blocky.ilnmors.internal
|
{{ hostvars['fw']['network4']['blocky']['server'] }} blocky.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network4']['bind']['server'] }} bind.ilnmors.internal
|
{{ hostvars['fw']['network4']['bind']['server'] }} bind.{{ domain['internal'] }}
|
||||||
# DB, LDAP, CA, Prometheus, Loki, mail (infra)
|
# DB, LDAP, CA, Prometheus, Loki, mail (infra)
|
||||||
{{ hostvars['fw']['network4']['infra']['server'] }} postgresql.ilnmors.internal ldap.ilnmors.internal prometheus.ilnmors.internal loki.ilnmors.internal mail.ilnmors.internal ca.ilnmors.internal
|
{{ hostvars['fw']['network4']['infra']['server'] }} postgresql.{{ domain['internal'] }} ldap.{{ domain['internal'] }} prometheus.{{ domain['internal'] }} loki.{{ domain['internal'] }} mail.{{ domain['internal'] }} ca.{{ domain['internal'] }}
|
||||||
# IPv6
|
# IPv6
|
||||||
# Crowdsec, blocky, bind(fw)
|
# Crowdsec, blocky, bind(fw)
|
||||||
{{ hostvars['fw']['network6']['firewall']['server'] }} ntp.ilnmors.internal crowdsec.ilnmors.internal
|
{{ hostvars['fw']['network6']['firewall']['server'] }} ntp.{{ domain['internal'] }} crowdsec.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['blocky']['server'] }} blocky.ilnmors.internal
|
{{ hostvars['fw']['network6']['blocky']['server'] }} blocky.{{ domain['internal'] }}
|
||||||
{{ hostvars['fw']['network6']['bind']['server'] }} bind.ilnmors.internal
|
{{ hostvars['fw']['network6']['bind']['server'] }} bind.{{ domain['internal'] }}
|
||||||
# DB, LDAP, CA, Prometheus, Loki, mail (infra)
|
# DB, LDAP, CA, Prometheus, Loki, mail (infra)
|
||||||
{{ hostvars['fw']['network6']['infra']['server'] }} postgresql.ilnmors.internal ldap.ilnmors.internal prometheus.ilnmors.internal loki.ilnmors.internal mail.ilnmors.internal ca.ilnmors.internal
|
{{ hostvars['fw']['network6']['infra']['server'] }} postgresql.{{ domain['internal'] }} ldap.{{ domain['internal'] }} prometheus.{{ domain['internal'] }} loki.{{ domain['internal'] }} mail.{{ domain['internal'] }} ca.{{ domain['internal'] }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
DNS=1.1.1.2 1.0.0.2
|
DNS=1.1.1.2 1.0.0.2
|
||||||
DNS=2606:4700:4700::1112 2606:4700:4700::1002
|
DNS=2606:4700:4700::1112 2606:4700:4700::1002
|
||||||
{% endif %}
|
{% endif %}
|
||||||
cache=false
|
cache=false
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
[Time]
|
[Time]
|
||||||
NTP=ntp.ilnmors.internal
|
NTP=ntp.{{ domain['internal'] }}
|
||||||
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
|
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ define HOSTS4_INFRA = {{ hostvars['fw']['network4']['infra']['server'] }}
|
|||||||
define HOSTS4_AUTH = {{ hostvars['fw']['network4']['auth']['server'] }}
|
define HOSTS4_AUTH = {{ hostvars['fw']['network4']['auth']['server'] }}
|
||||||
define HOSTS4_APP = {{ hostvars['fw']['network4']['app']['server'] }}
|
define HOSTS4_APP = {{ hostvars['fw']['network4']['app']['server'] }}
|
||||||
define HOSTS4_NAS = {{ hostvars['fw']['network4']['nas']['client'] }}
|
define HOSTS4_NAS = {{ hostvars['fw']['network4']['nas']['client'] }}
|
||||||
|
define HOSTS4_PRINTER = {{ hostvars['fw']['network4']['printer']['client'] }}
|
||||||
|
|
||||||
define HOSTS6_FW = { {{ hostvars['fw']['network6']['firewall'].values() | join(', ') }} }
|
define HOSTS6_FW = { {{ hostvars['fw']['network6']['firewall'].values() | join(', ') }} }
|
||||||
define HOSTS6_BLOCKY = {{ hostvars['fw']['network6']['blocky']['server'] }}
|
define HOSTS6_BLOCKY = {{ hostvars['fw']['network6']['blocky']['server'] }}
|
||||||
@@ -81,6 +82,8 @@ table inet filter {
|
|||||||
chain global {
|
chain global {
|
||||||
# invalid packets
|
# invalid packets
|
||||||
ct state invalid drop comment "deny invalid connection"
|
ct state invalid drop comment "deny invalid connection"
|
||||||
|
# VPN connection exception handling
|
||||||
|
udp dport $PORTS_VPN return comment "return vpn connection to input and forward chain"
|
||||||
# crowdsec
|
# crowdsec
|
||||||
ip saddr @crowdsec-blacklists counter drop comment "deny all crowdsec blacklist"
|
ip saddr @crowdsec-blacklists counter drop comment "deny all crowdsec blacklist"
|
||||||
ip6 saddr @crowdsec6-blacklists counter drop comment "deny all ipv6 crowdsec blacklist"
|
ip6 saddr @crowdsec6-blacklists counter drop comment "deny all ipv6 crowdsec blacklist"
|
||||||
@@ -146,6 +149,8 @@ table inet filter {
|
|||||||
# Kopia/NAS Console > NAS
|
# Kopia/NAS Console > NAS
|
||||||
oifname $IF_CLIENT ip saddr $HOSTS4_CONSOLE ip daddr $HOSTS4_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv4 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS"
|
oifname $IF_CLIENT ip saddr $HOSTS4_CONSOLE ip daddr $HOSTS4_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv4 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS"
|
||||||
oifname $IF_CLIENT ip6 saddr $HOSTS6_CONSOLE ip6 daddr $HOSTS6_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv6 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS"
|
oifname $IF_CLIENT ip6 saddr $HOSTS6_CONSOLE ip6 daddr $HOSTS6_NAS tcp dport { $PORTS_NAS, $PORTS_KOPIA } accept comment "allow ipv6 web connection (DSM, KOPIA): CONSOLE > FW > CLIENT NAS"
|
||||||
|
# Printer
|
||||||
|
oifname $IF_CLIENT ip saddr $HOSTS4_CONSOLE ip daddr $HOSTS4_PRINTER accept comment "allow ipv4 printer connection: CONSOLE > FW > PRINTER"
|
||||||
|
|
||||||
iifname $IF_WAN jump wan comment "set WAN interface rules"
|
iifname $IF_WAN jump wan comment "set WAN interface rules"
|
||||||
iifname $IF_CLIENT jump client comment "set CLIENT interface rules"
|
iifname $IF_CLIENT jump client comment "set CLIENT interface rules"
|
||||||
|
|||||||
@@ -113,6 +113,13 @@ postgresql:
|
|||||||
ldap: ENC[AES256_GCM,data:mJrxIhXynHxJhncw3upHpOkXIw+Ka9bmDBJwkDjYl+D9Pg4RDvL6WzBjthw=,iv:y8MUYo6VhgTzbWh/+n7/hf1Jw+L2KcdxKvulPJ67xn8=,tag:4ZFpj1UdOwXmaZjYvC/s3A==,type:str]
|
ldap: ENC[AES256_GCM,data:mJrxIhXynHxJhncw3upHpOkXIw+Ka9bmDBJwkDjYl+D9Pg4RDvL6WzBjthw=,iv:y8MUYo6VhgTzbWh/+n7/hf1Jw+L2KcdxKvulPJ67xn8=,tag:4ZFpj1UdOwXmaZjYvC/s3A==,type:str]
|
||||||
grafana: ENC[AES256_GCM,data:P9okJ7bcsqmeGstkSwbDq/RgnG+lFrgAOvcj8A5lOTpmHaSlXGiKG+ybXa0=,iv:Di1ghnxIbAb/u7uo/mJCC3QYVjdweTHaQDZmXTx8OG4=,tag:DT3a1zgU9sTr0BXpyoZ/SQ==,type:str]
|
grafana: ENC[AES256_GCM,data:P9okJ7bcsqmeGstkSwbDq/RgnG+lFrgAOvcj8A5lOTpmHaSlXGiKG+ybXa0=,iv:Di1ghnxIbAb/u7uo/mJCC3QYVjdweTHaQDZmXTx8OG4=,tag:DT3a1zgU9sTr0BXpyoZ/SQ==,type:str]
|
||||||
authelia: ENC[AES256_GCM,data:OqyloAADO6KKEaBjGLsJc9GTe77wn6IvA1VCD2dfCWxx+zgzUYh87fK1XX8=,iv:QIOHNTdNnzcY/f3Co8dPdNHykhBnYRhm43nt35hbALM=,tag:DLQq58GrZd+Ul7MSn6s9uQ==,type:str]
|
authelia: ENC[AES256_GCM,data:OqyloAADO6KKEaBjGLsJc9GTe77wn6IvA1VCD2dfCWxx+zgzUYh87fK1XX8=,iv:QIOHNTdNnzcY/f3Co8dPdNHykhBnYRhm43nt35hbALM=,tag:DLQq58GrZd+Ul7MSn6s9uQ==,type:str]
|
||||||
|
vaultwarden: ENC[AES256_GCM,data:BPj5eFo54DTZ82n3yTIqEbm7kb/jWT0n2kZY//oV5q48eRch3C2RBuxn/Ko=,iv:DGC4ipHMyVs25gc4sNMt8LN1RsHjiR/b303vgiFoxMY=,tag:k1eb4DoRPLKvvMstSI1faQ==,type:str]
|
||||||
|
gitea: ENC[AES256_GCM,data:l+pBCzyQa3000SE9z1R4htD0V0ONsBtKy92dfgsVYsZ3XlEyVJDIBOsugwM=,iv:5t/oHW1vFAmV/s2Ze/cV9Vuqo96Qu6QvZeRbio7VX2s=,tag:4zeQaXiXIzBpy+tXsxmN7Q==,type:str]
|
||||||
|
immich: ENC[AES256_GCM,data:11jvxTKA/RL0DGL6y2/X092hnDohj6yTrYGK4IVojqBd1gCOBnDvUjgmx14=,iv:oBfHxsx9nxhyKY/WOuWfybxEX2bf+lHEtsaifFRS9lg=,tag:tAfkBdgQ8ZEkLIFcDICKDw==,type:str]
|
||||||
|
paperless: ENC[AES256_GCM,data:6VBrBbjVoam7SkZCSvoBTdrfkUoDghdGTiBmFLul04X/okXOHeC5zusJffY=,iv:iZumcJ3TWwZD77FzYx8THwCqC+EbnXUBrEKuPh3zgV8=,tag:u2m8SppAdxZ/duNdpuS3oQ==,type:str]
|
||||||
|
affine: ENC[AES256_GCM,data:XPXrcszsV06YqCJZ7CDqc4rCwqqNlbtLCFYfLAQ8jamLtft8L2UVrMA4WZo=,iv:vrWdBeckxB9tmEE628j4jhU+hSpE6TXYMGt0hh1Cg84=,tag:hlWwWUGht8NqWTZREMsa1Q==,type:str]
|
||||||
|
nextcloud: ENC[AES256_GCM,data:ROsximNuWYMTZktmLJPx7W1Qol/uT+APgwoCtFO/6ZYYc3KxKvlk344eqEc=,iv:4d+MrfIHjJKAcwhvZ3g4go66uZcieuL7lngKErJd+fg=,tag:QbWOtxeCbiu62GyrE2atXg==,type:str]
|
||||||
|
sure: ENC[AES256_GCM,data:FULJ2gjJ2gZC3s324itW+CjGRBHIP9RnOqw5TT1UaiUhb7UHAPm1na+LsZk=,iv:c0GnVZkxprJUzPPq3TCQaZvAes9QQuvDXqgVLLaiQIg=,tag:uDxy/Lkd2hNK4AWwMNMslw==,type:str]
|
||||||
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -131,7 +138,7 @@ ldap:
|
|||||||
authelia: ENC[AES256_GCM,data:G8ZGsLKqEmMzQ5NMAgirF5BQraHNqixtI6dyyaeNhTdXebjJZML52xL36p4=,iv:ZtHAsFYmrQxr+qoQLPW/eme0+nsT148KRsXmW/LNLlU=,tag:Pvjs/eylkgxJpmGBsRmjcw==,type:str]
|
authelia: ENC[AES256_GCM,data:G8ZGsLKqEmMzQ5NMAgirF5BQraHNqixtI6dyyaeNhTdXebjJZML52xL36p4=,iv:ZtHAsFYmrQxr+qoQLPW/eme0+nsT148KRsXmW/LNLlU=,tag:Pvjs/eylkgxJpmGBsRmjcw==,type:str]
|
||||||
grafana: ENC[AES256_GCM,data:vWmU3ZKcolETWAY74C3OMD8gMXDeYk+DqssACL0xefIPi5IkbrhYWmnWAnA=,iv:wcRms3Zp8kPM4USRPVa0UHpCTK36SWhK9C8yHSWu2Cs=,tag:gU5S/6fdMZVd/ih3Yd5uJA==,type:str]
|
grafana: ENC[AES256_GCM,data:vWmU3ZKcolETWAY74C3OMD8gMXDeYk+DqssACL0xefIPi5IkbrhYWmnWAnA=,iv:wcRms3Zp8kPM4USRPVa0UHpCTK36SWhK9C8yHSWu2Cs=,tag:gU5S/6fdMZVd/ih3Yd5uJA==,type:str]
|
||||||
il: ENC[AES256_GCM,data:/CyMeo1+rIUAYiB25nI0,iv:jsyiiRN5z9GqcUnTZ0CZo4s+umTc2zeY2FPp+tVOC9o=,tag:cwOHcqMysCxX57w3a+Pzpg==,type:str]
|
il: ENC[AES256_GCM,data:/CyMeo1+rIUAYiB25nI0,iv:jsyiiRN5z9GqcUnTZ0CZo4s+umTc2zeY2FPp+tVOC9o=,tag:cwOHcqMysCxX57w3a+Pzpg==,type:str]
|
||||||
morsalin: null
|
morsalin: ENC[AES256_GCM,data:YryNch8hF6rx,iv:bNIBur3Jcib8BvKjJ0MejpemsurYTP8rCxo6b2R5yEo=,tag:9dIIgqEPtbeixtgJ1OtMnQ==,type:str]
|
||||||
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -170,6 +177,80 @@ authelia:
|
|||||||
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
#ENC[AES256_GCM,data:MiobmVqj3dPargzws5q7Cpggnvw=,iv:VzBh1ZWqyByyTDn90pl0//TsjAYO5QLpfbrxnMF5OU4=,tag:7Y16L9i/homdtEpWynzsdg==,type:comment]
|
||||||
|
vaultwarden:
|
||||||
|
admin:
|
||||||
|
password: ENC[AES256_GCM,data:FzD80H5lPNyjTRGd/IcIGir35KLF8gN3qmTzEQrlfutHh08mk0Vh9X8irHA=,iv:cfn5432g2MvkuBJLB2zDJmU0sLgMefVvpy0bP/4/oPY=,tag:7MHEv8XswdQZNTARvxs55g==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:Ae7bhnL5pxfNV3+r/PCDIpxx0tHcNiB/s4sm7OoxVpp+tcEpXZ9vsv38sZjx+Z8t2vlmiYHc72PEdapcAihleuLMBPM1dAVn8LqzzWtVhfmCOoUZI8Z5L3VL8eyyz6npiw==,iv:c2MEIbrnVsR+bUx3zLLTnKSElFTH7JRl23HmmTlWEBg=,tag:mnMrER9pQEKAdloYMeRa3g==,type:str]
|
||||||
|
il:
|
||||||
|
password: ENC[AES256_GCM,data:mhLb55ENatpE59Rbzk2Uq6iBKc0Jj/9x4fOANJOHR0WvSxTQRKJ94cCq9Ykp/chWbdgYYPrwU5oD0Yo17zqb,iv:6bzKq5WaKhuOsQ8zSSH9ZrQYbDPB1nv/bFoQou1ycL4=,tag:bSmuUodl+/9nzxZ7YBoezA==,type:str]
|
||||||
|
morsalin:
|
||||||
|
password: ENC[AES256_GCM,data:ibg5/MfLH7pSY2pEmjM=,iv:+aV5muP/9BYoKwTGQxKEL+IGY9P+O3GVKGgSuTzT+U0=,tag:rgqcmJvd1RtvWJ91PCxYIg==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#ENC[AES256_GCM,data:HAN9BBEl1CW11LAf3x8=,iv:hwqCErtmPqGJ+y86D9MoxJwixvbcJONlyT900Y5DOug=,tag:kCxsG353ltbOCKLe85adCg==,type:comment]
|
||||||
|
gitea:
|
||||||
|
il:
|
||||||
|
password: ENC[AES256_GCM,data:Bs5/t5mNbSv5+ek9gNHZp5qqxitM4Kq0Xgh2JV6LiFw9lZJSOVT4JPLRP5M=,iv:z50+naWOTVL8lEgBgm51j6hLjS8ve2UcRRKukvtykM0=,tag:TF9rPxjoLe/vAyvl23PiCg==,type:str]
|
||||||
|
token: ENC[AES256_GCM,data:CiYEXEKLLRDp++iga5YmhyPB2bSvqhhDgSOhmiulp9n9SsBVQ3s5MQ==,iv:+oetgEH/IORz74Xoz5zgDjD3BLyledZTqlYlCWaDrRk=,tag:S9O09YEMuSexuNW3ojEw5Q==,type:str]
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:qjQosi83oaK47wX4VtDktDFlIU3FQgmDpwyiSgJNPDq2Dtc/QEKzdv5/ZpQ=,iv:aUJx5a6Wj7lhaD19aPiZWIE/MWKUgH0muxtTSkwfg8M=,tag:DttjXee7ntxRAbqbFq6qeQ==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:iVls8UzdP6JTfRosET6nsk3RcEtFQ8ak6GtPuBjcqAv3lyA9oSLwvvC8MvGaT1aHCB+5y/lspuloHEaAcVGNuzGCIVLg9Adut4a7LYDTHNOZnJIKLj8ldL1ytD5XVdbeBhZGCqoTs088oO0HVCQiDzpJL5NdmM3Ru6egyYBCLLUOlPA=,iv:er63GEC+kxNDscvspvvLiq17VSg0GeZ2w3jmGojF9PM=,tag:F1pDpaQrVdomIlZ8psVpAw==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#ENC[AES256_GCM,data:HvMeGuC8JwK50pO1E/nm,iv:5NFTyjesMX0ZnBpH+hEv8jQ0G2NvrDtT23CUyLbQcUo=,tag:qWmPvQpADTeD+W8nWXRQvA==,type:comment]
|
||||||
|
immich:
|
||||||
|
il:
|
||||||
|
password: ENC[AES256_GCM,data:PbDFc4m7rNPPN1mCjcvhbKwf/EbiJxdvO/iMspf9jMuCqQyGv7h6VrZqk98=,iv:hlMAp5wXXkFO9+ekq3A2/ioF/EX8Uau0puhb4TAHkRQ=,tag:pfS0W2JNaFNMpBlKgZ3Pjw==,type:str]
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:9ENcp2Ns21OLXDY05zRoSdP+93EiwSH8MGzZZpxK7sToe4QLUXWt9w6xQIE=,iv:Q/VcnArZHs/J2YLRVFXt3Mp+LYfuq4PD/trqO8Simig=,tag:BY/mOyZpYmoAc7NrASlmSA==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:mrML2CWFFtGjq8wfWipVpv+pjJRSHe74VGC7Eoa6588R5C/sCnC3W5aI+dsRCZN3LRCjHAkOJJgjeYrwcXYdKRauXsAYR51dNSsHqqSN3WebLxapRDwcYu5e4j5RN1aPHsysr7GaQ4hhe5rKW4ORCGC3Cp3Ob+LChPy4bdCAZG3bN9k=,iv:Q4hmqhq+dvIr7DxCpcqP4E0NKyFZkOeTnDpGctmCxXM=,tag:/gji6AFkHnYwkQf3FSQUxA==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#ENC[AES256_GCM,data:McPUAbIUvtC1gdPaxTgAxAMCMWcLfg==,iv:Tp6idRf7he3sYzo8LW596C905JAaoTIhIoDUzSyRT0k=,tag:4mZQ0Swu1X9uuwjsRNhr2A==,type:comment]
|
||||||
|
paperless:
|
||||||
|
session_secret: ENC[AES256_GCM,data:siwCs2noeVpg9DCEZybnmo/oz11BdrHSTnHciMOu/6g=,iv:XVjhu10TIujIdUopN9+TVVqRade9EvItDWxym6YXnZs=,tag:TxLYm+4Bo7IMaTQBtMg9pQ==,type:str]
|
||||||
|
il:
|
||||||
|
password: ENC[AES256_GCM,data:9bJHf+chTg1rppgNVafNgEuvwQ69Gx+w5d65hu68q9XeeaVb2pO9HE4BOgg=,iv:1kaXBg/iOoIZxDjEVEdaMJLDtp6zQjep3vxLmIgQN5o=,tag:+MgX8Oa3tmhjx6u9aHkDfQ==,type:str]
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:wjRDVCJsINM4z5946a6uZD+6bhN5BChLMdRzgMEJFGRGFNcXd7A1p2Iqn4I=,iv:Y4QDA09L8ULKr4hhvoiduzCD8Hifo1gAnpzjCr8e520=,tag:R0RvGxYnXo3zwykXJykRug==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:pali6WwPNhJA+6QL4O+tKv42PnpGqmojb8JQUZLqxGizv1bJSCgdUN8upCy5Ke0DYZs5P+JY5vh23xfMZFnHduGxGwOuPX6J5lYgvJRV58LqS3/+yIBBprTJyro3MwsurTTEWesgKMr8/2H9lirhaLjWUOSPxAmQ6e4wPNpHycDVyj4=,iv:cg2trI7t1MfIcMo1/M+IY6JEl2msDoKRGgAx/Y5nyGk=,tag:gnOq7sBq9z5zrRY0yhIabg==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#ENC[AES256_GCM,data:k55osvepVeB1RC5hZ4IF,iv:AlhfmWwn/DiSESWc+ULJSOLUhnrKAIfWr7MeiwV8qc8=,tag:hOgptwUcY6nVxPIhu+DYgw==,type:comment]
|
||||||
|
affine:
|
||||||
|
secret_key: ENC[AES256_GCM,data:LLX78DpYnha1JWhgw0sHLzIVq/oIzvT+nB7zgli4mroGbnt7WZaXCx34zKkYRwYj/+0L4IFFVdkzKtK5DO84SgFkS2Bk2iNdCMqIx80CpyiD8IWAcyRu5d6hh82PlgyxU80T/4nbLbIn0GLubPTTeUX8GC3VxRU=,iv:DnmvbhlygSHes0jAkIm4+WXMUQLzr4R4dNa33rO67v8=,tag:+2wlh+/ekiTyShWM4XBbUw==,type:str]
|
||||||
|
il:
|
||||||
|
password: ENC[AES256_GCM,data:4zxiQAzXTR+fraRjYT657BIwSqrih3lMPFFSibQdardRMjskAbuRYIQA6mo=,iv:ub3giRG9vCFSuwRXDazYTqWbjENzQUWR36290Kruj1o=,tag:C2Ixd2eTEgzBvUNCNBtJuA==,type:str]
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:eRDBrqLZR7MFLlsUwk7Wg7FzxDov7vJLIWQRuKq7vrXbPSJkMcy9jfG2rL4=,iv:UaSoi7gODXgjzihJIDVIdDHJcSAZNV8UKfGeM6YzxqI=,tag:cOUDblcMStP8E4fp+s1WRQ==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:jE1CvFo+mjb/Xc3Ft5ky7on03vcnv79cw/5g/xaldXsv94VRrIjmfGMgHAj07r8j5mDpP34A5bYO1PSe9DYrwRcsXa9OUQuzm/8avFy9wVZDhBUUAGR+jiW1BP9hc6nmSpPVPtle+3sbqOB0ZMjXWwlcAcuknOtuhH1mzwmaDP9yf+M=,iv:CSSaXY/6MpHBMhPLUWPkabIeJ9zpZkcVjiEhxVF0zJM=,tag:f72ekkjJs7Qmh1K9wC8L9w==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#ENC[AES256_GCM,data:PZS7EbvMHqHGorNUGAWj4dk1,iv:vOE+djRAvBTMM51kHi6kG5Arw3uPXlJt1d/BpcEaD0c=,tag:AuoCHLQz42CYvVVdKFWu1Q==,type:comment]
|
||||||
|
nextcloud:
|
||||||
|
admin-local:
|
||||||
|
password: ENC[AES256_GCM,data:mIwF5A09oqYbdK3bOKid9A896Q5J5Q6Ax+vDNqEJFGNdzd/mJ4oQS6rva+s=,iv:QroUMST2wnEJzk6DySe9tPZaWuqdxzJZ0+oi6mW6x00=,tag:3UTzjupK7+omrI3Hvyr8bA==,type:str]
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:Sr4KkKkYdkU0UWdpfUF7PyiGoerjBiw+sOFcENyLxw0FRXGG0Y8gv5uGb4Q=,iv:LbGsNM3+iY7bWFQe88TepVKUdiRQWZ+K7Ubn6ze6lV4=,tag:SbcfIAMW9ZprgahOFU4IQQ==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:CkstbIYQmi72QhsbJZN0lQedgCn7TmGpYcYj0n+NvJIoTlol8G9N/88cwGbVoGK9nEISv54FL94cEJFppnMIuj0BHrhasrZsyI2/Lj52YLWdwNJWNQ+iYt+Ifp/1kI0zqmdoajzZ5DS2w/1evCBC1+JdfTRlpVXmSsHUIPIHelBRj90=,iv:vwvT5TTkF4woxXOvrRRqmrdLXf19s47NIDtdT+zLp0U=,tag:KC0MS0DTH6j3zIHOjCFOSA==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#ENC[AES256_GCM,data:Fsqc2JDp9dvfgiCjdQ==,iv:3DALKKEXaP8hzXRvxD4CgfFpOiPPsOa16OB94n8WKp8=,tag:K+FF3zGrc0YLXWK/R2L3Ow==,type:comment]
|
||||||
|
sure:
|
||||||
|
session_secret: ENC[AES256_GCM,data:InHsz/jld8E9TwI8MWpxk9x2I7dxlIsY9R6jtDK2pBA=,iv:HY5yXEC2Dce26e9/vXTIWELvVd9ZjhcCwFD0jhz5pPw=,tag:LLSJovZ0RH3CUK+se7R4Ag==,type:str]
|
||||||
|
oidc:
|
||||||
|
secret: ENC[AES256_GCM,data:9BSvpcU9BJctSN9bkPIAsRxg8JNHTWvOKdpJFhm//CUDm/Xc7oC/ANHf5no=,iv:JVQLl/rp65kZSK/4SpVXxtiac3Z35XNkxWm2+lEdq/c=,tag:WgfaORiNlrO+wHSdnl4CWQ==,type:str]
|
||||||
|
hash: ENC[AES256_GCM,data:EjJ+1fP7/9wG2jG0Jv2hxMLtErqxjHBstRjru79dd5ZXhqwT7S+jpLfl9WpZU9qi20ps9YP4qe7G08p6NJNXjYhQj852GQxEORRh/9StAZsPt3p8w+ePZSVbivPQH+FpPKWYxoH0VR7y3TnL66R0tKRLh1fNTc5jRy5rU5r1bfs1jZ0=,iv:0y9FxW4QdD7qHz3bPRWlwHFpvOsvlYhVrOItB6BzaE8=,tag:Wc7MZhP3QRYmvZcjpoEWtQ==,type:str]
|
||||||
|
#ENC[AES256_GCM,data:ODXFUxxxdQ==,iv:s9zJVx6wo6x517tbNvC+FZ0dFzqbjqeLI6rXBq72hQA=,tag:bXoV2I3LbpmQyddJrtS3Qg==,type:comment]
|
||||||
|
#
|
||||||
|
#
|
||||||
#ENC[AES256_GCM,data:T4Wtn49AAxPd2QUFTR+q,iv:bH5goGWBDqumAat9dUv2OwfCUJUpuVqncTMqMBZUXhI=,tag:G+W6hHA+yftQ+4RJpXrxHg==,type:comment]
|
#ENC[AES256_GCM,data:T4Wtn49AAxPd2QUFTR+q,iv:bH5goGWBDqumAat9dUv2OwfCUJUpuVqncTMqMBZUXhI=,tag:G+W6hHA+yftQ+4RJpXrxHg==,type:comment]
|
||||||
switch:
|
switch:
|
||||||
password: ENC[AES256_GCM,data:qu0f9L7A0eFq/UCpaRs=,iv:W8LLOp3MSfd/+EfNEZNf91K8GgI5eUfVPoWTRES2C0Y=,tag:Q5FlAOfwqwJwPvd7k6i+0g==,type:str]
|
password: ENC[AES256_GCM,data:qu0f9L7A0eFq/UCpaRs=,iv:W8LLOp3MSfd/+EfNEZNf91K8GgI5eUfVPoWTRES2C0Y=,tag:Q5FlAOfwqwJwPvd7k6i+0g==,type:str]
|
||||||
@@ -199,7 +280,7 @@ sops:
|
|||||||
UmliaFNxVTBqRkI1QWJpWGpTRWxETW8KEY/8AfU73UOzCGhny1cNnd5dCNv7bHXt
|
UmliaFNxVTBqRkI1QWJpWGpTRWxETW8KEY/8AfU73UOzCGhny1cNnd5dCNv7bHXt
|
||||||
k+uyWPPi+enFkVaceSwMFrA66uaWWrwAj11sXEB7yzvGFPrnAGezjQ==
|
k+uyWPPi+enFkVaceSwMFrA66uaWWrwAj11sXEB7yzvGFPrnAGezjQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-03-14T19:40:47Z"
|
lastmodified: "2026-05-09T14:26:51Z"
|
||||||
mac: ENC[AES256_GCM,data:EUVSxs6FPhKMSSmHe8P/d0IyBZsNb3q7AYj06j98bklAMYYVOludVePdh45MSvn92lDn712Muy6pqcJzDpsPWyxgXngywTu2SGV1yRCyA7U7RloRxlNROuDiugMkJWOtHcKArytVChUHT2PnzagAJR2kBSApbjUsC/xUTMBpsNM=,iv:SsJW2fMNEJHT2M+gjW5TKu6AYoxsf9jKf5T9KgJoF40=,tag:ItVweaSxts2Cm1VKkLp0/w==,type:str]
|
mac: ENC[AES256_GCM,data:TYs08ZSS2kcO5lYuhQ/IySUSQ3DpL+ba3/uNLyszht4OttR110/W/WQLiRuu/Ql6FwtDtjq6I3iNpOhmCHSv1kMCam1l99GEIYCaPUIY+TY3Zw0j7518dFXe8p/DrKRwIVXfK5lIKLIEd+eizD50HzwXXJFmU+7YDkQ1Dx+55kw=,iv:arJKJ4wO4sdQlu3GZbtultsfM6s8vbhG93tnf2EjJDc=,tag:m95gUqvn4w85XI8qVvCZpQ==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.12.1
|
version: 3.12.1
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=AFFiNE
|
||||||
|
|
||||||
|
After=redis_affine.service manticore_affine.service
|
||||||
|
Wants=redis_affine.service manticore_affine.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/toeverything/affine:{{ version['containers']['affine'] }}
|
||||||
|
ContainerName=affine
|
||||||
|
HostName=affine
|
||||||
|
|
||||||
|
PublishPort={{ services['affine']['ports']['http'] }}:3010
|
||||||
|
|
||||||
|
Volume=%h/data/containers/affine:/root/.affine/storage:rw
|
||||||
|
Volume=%h/containers/affine/config:/root/.affine/config
|
||||||
|
Volume=%h/containers/affine/ssl:/etc/ssl/affine:ro
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
## OIDC callback URIs
|
||||||
|
Environment="AFFINE_SERVER_HOST={{ services['affine']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
Environment="AFFINE_SERVER_EXTERNAL_URL=https://{{ services['affine']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
Environment="AFFINE_SERVER_HTTPS=true"
|
||||||
|
|
||||||
|
Secret=AFFINE_PRIVATE_KEY,type=env
|
||||||
|
|
||||||
|
# Database
|
||||||
|
Secret=AFFINE_DATABASE_URL,type=env,target=DATABASE_URL
|
||||||
|
## Enable AI function: this needs pgvector
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
Environment="REDIS_SERVER_HOST=host.containers.internal"
|
||||||
|
Environment="REDIS_SERVER_PORT={{ services['affine']['ports']['redis'] }}"
|
||||||
|
|
||||||
|
# Indexer
|
||||||
|
Environment="AFFINE_INDEXER_ENABLED=true"
|
||||||
|
Environment="AFFINE_INDEXER_SEARCH_ENDPOINT=http://host.containers.internal:{{ services['affine']['ports']['manticore'] }}"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Collabora Online
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/collabora/code:{{ version['containers']['collabora'] }}
|
||||||
|
ContainerName=collabora
|
||||||
|
HostName=collabora
|
||||||
|
|
||||||
|
PublishPort={{ services['collabora']['ports']['http'] }}:9980/tcp
|
||||||
|
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
Environment="aliasgroup1=https://{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
# Environment="aliasgroup2=other_server_FQDN"
|
||||||
|
Environment="extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:server_name={{ services['collabora']['domain']['public'] }}.{{ domain['public'] }} --o:admin_console.enable=false"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Gitea
|
||||||
|
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/gitea/gitea:{{ version['containers']['gitea'] }}
|
||||||
|
|
||||||
|
ContainerName=gitea
|
||||||
|
HostName=gitea
|
||||||
|
|
||||||
|
PublishPort={{ services['gitea']['ports']['http'] }}:3000/tcp
|
||||||
|
|
||||||
|
Volume=%h/data/containers/gitea:/data:rw
|
||||||
|
Volume=%h/containers/gitea/ssl:/etc/ssl/gitea:ro
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
Environment="GITEA__server__DISABLE_SSH=true"
|
||||||
|
# Database
|
||||||
|
Environment="GITEA__database__DB_TYPE=postgres"
|
||||||
|
Environment="GITEA__database__HOST={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}"
|
||||||
|
Environment="GITEA__database__NAME=gitea_db"
|
||||||
|
Environment="GITEA__database__USER=gitea"
|
||||||
|
Secret=GITEA__database__PASSWD,type=env
|
||||||
|
Environment="GITEA__database__SSL_MODE=verify-full"
|
||||||
|
Environment="PGSSLROOTCERT=/etc/ssl/gitea/{{ root_cert_filename }}"
|
||||||
|
# OAuth2 client
|
||||||
|
Environment="GITEA__oauth2_client__ACCOUNT_LINKING=auto"
|
||||||
|
# OIDC configuration
|
||||||
|
Environment="GITEA__openid__ENABLE_OPENID_SIGNIN=false"
|
||||||
|
Environment="GITEA__openid__ENABLE_OPENID_SIGNUP=true"
|
||||||
|
Environment="GITEA__openid__WHITELISTED_URIS={{ services['authelia']['domain'] }}.{{ domain['public'] }}"
|
||||||
|
# automatic create user via authelia
|
||||||
|
Environment="GITEA__service__DISABLE_REGISTRATION=false"
|
||||||
|
Environment="GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION=true"
|
||||||
|
Environment="GITEA__service__SHOW_REGISTRATION_BUTTON=false"
|
||||||
|
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Immich Machine Learning
|
||||||
|
|
||||||
|
After=immich.service
|
||||||
|
Wants=immich.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/immich-app/immich-machine-learning:{{ version['containers']['immich'] }}-openvino
|
||||||
|
|
||||||
|
ContainerName=immich-ml
|
||||||
|
HostName=immich-ml
|
||||||
|
|
||||||
|
PublishPort={{ services['immich-ml']['ports']['http'] }}:3003
|
||||||
|
|
||||||
|
# iGPU access for OpenVINO
|
||||||
|
AddDevice=/dev/dri:/dev/dri
|
||||||
|
PodmanArgs=--group-add keep-groups
|
||||||
|
|
||||||
|
Volume=%h/containers/immich/ml/cache:/cache:rw
|
||||||
|
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Immich
|
||||||
|
|
||||||
|
After=redis_immich.service
|
||||||
|
Wants=redis_immich.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/immich-app/immich-server:{{ version['containers']['immich'] }}
|
||||||
|
|
||||||
|
ContainerName=immich
|
||||||
|
HostName=immich
|
||||||
|
|
||||||
|
PublishPort={{ services['immich']['ports']['http'] }}:2283
|
||||||
|
|
||||||
|
# iGPU access
|
||||||
|
AddDevice=/dev/dri:/dev/dri
|
||||||
|
PodmanArgs=--group-add keep-groups
|
||||||
|
|
||||||
|
# Volumes
|
||||||
|
Volume=%h/data/containers/immich:/data:rw
|
||||||
|
Volume=%h/containers/immich/ssl:/etc/ssl/immich:ro
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
# The new environment from version 2.7.0 to enable CSP
|
||||||
|
Environment="IMMICH_HELMET_FILE=true"
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
Environment="REDIS_HOSTNAME=host.containers.internal"
|
||||||
|
Environment="REDIS_PORT={{ services['immich']['ports']['redis'] }}"
|
||||||
|
Environment="REDIS_DBINDEX=0"
|
||||||
|
|
||||||
|
# Database
|
||||||
|
Environment="DB_HOSTNAME={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}"
|
||||||
|
Environment="DB_PORT={{ services['postgresql']['ports']['tcp'] }}"
|
||||||
|
Environment="DB_USERNAME=immich"
|
||||||
|
Environment="DB_DATABASE_NAME=immich_db"
|
||||||
|
Environment="DB_PASSWORD_FILE=/run/secrets/DB_PASSWORD"
|
||||||
|
Environment="DB_SSL_MODE=verify-full"
|
||||||
|
Environment="NODE_EXTRA_CA_CERTS=/etc/ssl/immich/{{ root_cert_filename }}"
|
||||||
|
Secret=IMMICH_DB_PASSWORD,target=/run/secrets/DB_PASSWORD
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Manticore - {{ manticore_service }}
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/manticoresearch/manticore:{{ version['containers']['manticore'] }}
|
||||||
|
ContainerName=manticore_{{ manticore_service }}
|
||||||
|
HostName=manticore_{{ manticore_service }}
|
||||||
|
|
||||||
|
PublishPort={{ services[manticore_service]['ports']['manticore'] }}:9308
|
||||||
|
|
||||||
|
Volume=%h/data/containers/manticore/{{ manticore_service }}:/var/lib/manticore:rw
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
$CONFIG = [
|
||||||
|
// Background jobs mode is auto-detected as 'cron' when nextcloud-cron.timer runs cron.php via CLI. No explicit config required.
|
||||||
|
'maintenance_window_start' => 18,
|
||||||
|
];
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
$CONFIG = [
|
||||||
|
'memcache.local' => '\OC\Memcache\APCu',
|
||||||
|
'memcache.distributed' => '\OC\Memcache\Redis',
|
||||||
|
'memcache.locking' => '\OC\Memcache\Redis',
|
||||||
|
'redis' => [
|
||||||
|
'host' => 'host.containers.internal',
|
||||||
|
'port' => {{ services['nextcloud']['ports']['redis'] }},
|
||||||
|
'timeout' => 1.5,
|
||||||
|
'dbindex' => 0,
|
||||||
|
],
|
||||||
|
];
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
$CONFIG = [
|
||||||
|
'trusted_domains' => [
|
||||||
|
'{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}',
|
||||||
|
],
|
||||||
|
'overwritehost' => '{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}',
|
||||||
|
'overwriteprotocol' => 'https',
|
||||||
|
'overwrite.cli.url' => 'https://{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}',
|
||||||
|
];
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
$CONFIG = [
|
||||||
|
'allow_local_remote_servers' => true,
|
||||||
|
];
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
$CONFIG = [
|
||||||
|
'user_oidc' => [
|
||||||
|
'default_token_endpoint_auth_method' => 'client_secret_post',
|
||||||
|
'auto_provision' => true,
|
||||||
|
'soft_auto_provision' => true,
|
||||||
|
'disable_account_creation' => false,
|
||||||
|
],
|
||||||
|
];
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
; /usr/local/etc/php/conf.d/opcache-recommended.ini
|
||||||
|
; OPcache tuning
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.enable_cli=1
|
||||||
|
opcache.memory_consumption=512
|
||||||
|
opcache.interned_strings_buffer=32
|
||||||
|
opcache.max_accelerated_files=20000
|
||||||
|
opcache.validate_timestamps=0
|
||||||
|
opcache.save_comments=1
|
||||||
|
opcache.revalidate_freq=60
|
||||||
|
opcache.fast_shutdown=1
|
||||||
|
|
||||||
|
; APCu CLI activate
|
||||||
|
apc.enable_cli=1
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
; /usr/local/etc/php/conf.d/nextcloud-upload.ini
|
||||||
|
upload_max_filesize=16G
|
||||||
|
post_max_size=16G
|
||||||
|
memory_limit=1024M
|
||||||
|
max_execution_time=3600
|
||||||
|
max_input_time=3600
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Nextcloud
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/library/nextcloud:{{ version['containers']['nextcloud'] }}
|
||||||
|
ContainerName=nextcloud
|
||||||
|
HostName=nextcloud
|
||||||
|
|
||||||
|
PublishPort={{ services['nextcloud']['ports']['http'] }}:80
|
||||||
|
|
||||||
|
Volume=%h/containers/nextcloud/ssl:/etc/ssl/nextcloud:ro
|
||||||
|
Volume=%h/containers/nextcloud/ini/opcache.ini:/usr/local/etc/php/conf.d/opcache-recommended.ini:ro
|
||||||
|
Volume=%h/containers/nextcloud/ini/upload.ini:/usr/local/etc/php/conf.d/upload.ini:ro
|
||||||
|
Volume=%h/data/containers/nextcloud/html:/var/www/html:rw
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
# PostgreSQL
|
||||||
|
Environment="PGSSLMODE=verify-full"
|
||||||
|
Environment="PGSSLROOTCERT=/etc/ssl/nextcloud/{{ root_cert_filename }}"
|
||||||
|
## libpq in Nextcloud automatically tries to use a client certificate for mTLS. Therefore, when only TLS is required, then disable the option explicitly.
|
||||||
|
Environment="PGSSLCERTMODE=disable"
|
||||||
|
# Redis
|
||||||
|
Environment="REDIS_HOST=host.containers.internal"
|
||||||
|
Environment="REDIS_HOST_PORT={{ services['nextcloud']['ports']['redis'] }}"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Nextcloud cron.php
|
||||||
|
Requires=nextcloud.service
|
||||||
|
After=nextcloud.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/podman exec -u www-data nextcloud php -f /var/www/html/cron.php
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Run Nextcloud cron every 5 minutes
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=5min
|
||||||
|
OnUnitActiveSec=5min
|
||||||
|
Unit=nextcloud-cron.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Paperless
|
||||||
|
|
||||||
|
After=redis_paperless.service
|
||||||
|
Wants=redis_paperless.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/paperless-ngx/paperless-ngx:{{ version['containers']['paperless'] }}
|
||||||
|
ContainerName=paperless
|
||||||
|
HostName=paperless
|
||||||
|
PublishPort={{ services['paperless']['ports']['http'] }}:8000/tcp
|
||||||
|
|
||||||
|
# Volumes
|
||||||
|
Volume=%h/data/containers/paperless/data:/usr/src/paperless/data:rw
|
||||||
|
Volume=%h/data/containers/paperless/media:/usr/src/paperless/media:rw
|
||||||
|
Volume=%h/data/containers/paperless/consume:/usr/src/paperless/consume:rw
|
||||||
|
Volume=%h/containers/paperless/ssl:/etc/ssl/paperless:ro
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
Environment="PAPERLESS_TIME_ZONE=Asia/Seoul"
|
||||||
|
Environment="PAPERLESS_URL=https://{{ services['paperless']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
Environment="PAPERLESS_OCR_LANGUAGE=kor+eng"
|
||||||
|
Environment="PAPERLESS_OCR_LANGUAGES=kor"
|
||||||
|
# Environment="PAPERLESS_OCR_MODE=force"
|
||||||
|
# Environment="PAPERLESS_TASK_WORKERS=1"
|
||||||
|
# Environment="PAPERLESS_THREADS_PER_WORKER=1"
|
||||||
|
Environment="PAPERLESS_WORKER_TIMEOUT=7200"
|
||||||
|
Secret=PAPERLESS_SECRET_KEY,type=env
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
Environment="PAPERLESS_REDIS=redis://host.containers.internal:{{ services['paperless']['ports']['redis'] }}"
|
||||||
|
|
||||||
|
# Database
|
||||||
|
Environment="PAPERLESS_DBHOST={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}"
|
||||||
|
Environment="PAPERLESS_DBPORT={{ services['postgresql']['ports']['tcp'] }}"
|
||||||
|
Environment="PAPERLESS_DBNAME=paperless_db"
|
||||||
|
Environment="PAPERLESS_DBUSER=paperless"
|
||||||
|
Environment="PAPERLESS_DBSSLMODE=verify-full"
|
||||||
|
Environment="PAPERLESS_DBSSLROOTCERT=/etc/ssl/paperless/{{ root_cert_filename }}"
|
||||||
|
Secret=PAPERLESS_DBPASS,type=env
|
||||||
|
|
||||||
|
# OIDC
|
||||||
|
Environment="PAPERLESS_APPS=allauth.socialaccount.providers.openid_connect"
|
||||||
|
Environment="PAPERLESS_SOCIAL_AUTO_SIGNUP=true"
|
||||||
|
Environment="PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS=true"
|
||||||
|
Secret=PAPERLESS_SOCIALACCOUNT_PROVIDERS,type=env
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
databases 16
|
||||||
|
bind 0.0.0.0
|
||||||
|
port 6379
|
||||||
|
protected-mode no
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Redis - {{ redis_service }}
|
||||||
|
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/library/redis:{{ version['containers']['redis'] }}
|
||||||
|
|
||||||
|
ContainerName=redis_{{ redis_service }}
|
||||||
|
HostName=redis_{{ redis_service }}
|
||||||
|
|
||||||
|
PublishPort={{ services[redis_service]['ports']['redis'] }}:6379
|
||||||
|
|
||||||
|
Volume=%h/containers/redis/{{ redis_service }}/data:/data:rw
|
||||||
|
Volume=%h/containers/redis/{{ redis_service }}/redis.conf:/usr/local/etc/redis/redis.conf:ro
|
||||||
|
|
||||||
|
Exec=redis-server /usr/local/etc/redis/redis.conf
|
||||||
|
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Sure Web
|
||||||
|
|
||||||
|
After=network-online.target redis_sure.service
|
||||||
|
Wants=network-online.target redis_sure.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/we-promise/sure:{{ version['containers']['sure'] }}
|
||||||
|
ContainerName=sure-web
|
||||||
|
HostName=sure-web
|
||||||
|
|
||||||
|
PublishPort={{ services['sure']['ports']['http'] }}:3000/tcp
|
||||||
|
|
||||||
|
Volume=%h/data/containers/sure/storage:/rails/storage:rw
|
||||||
|
Volume=%h/containers/sure/ssl:/etc/ssl/sure:ro
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
Environment="SELF_HOSTED=true"
|
||||||
|
Environment="ONBOARDING_STATE=closed"
|
||||||
|
Environment="RAILS_FORCE_SSL=false"
|
||||||
|
Environment="RAILS_ASSUME_SSL=true"
|
||||||
|
Environment="APP_DOMAIN={{ services['sure']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
Secret=SURE_SECRET_KEY_BASE,type=env,target=SECRET_KEY_BASE
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
Environment="POSTGRES_USER=sure"
|
||||||
|
Environment="POSTGRES_DB=sure_db"
|
||||||
|
Environment="DB_HOST={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}"
|
||||||
|
Environment="DB_PORT={{ services['postgresql']['ports']['tcp'] }}"
|
||||||
|
Environment="PGSSLMODE=verify-full"
|
||||||
|
Environment="PGSSLROOTCERT=/etc/ssl/sure/{{ root_cert_filename }}"
|
||||||
|
Secret=SURE_POSTGRES_PASSWORD,type=env,target=POSTGRES_PASSWORD
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
Environment="REDIS_URL=redis://host.containers.internal:{{ services['sure']['ports']['redis'] }}/1"
|
||||||
|
|
||||||
|
# OIDC - Authelia
|
||||||
|
Environment="OIDC_CLIENT_ID=sure"
|
||||||
|
Environment="OIDC_ISSUER=https://{{ services['authelia']['domain'] }}.{{ domain['public'] }}"
|
||||||
|
Environment="OIDC_REDIRECT_URI=https://{{ services['sure']['domain']['public'] }}.{{ domain['public'] }}/auth/openid_connect/callback"
|
||||||
|
Secret=SURE_OIDC_CLIENT_SECRET,type=env,target=OIDC_CLIENT_SECRET
|
||||||
|
Environment="OIDC_BUTTON_LABEL=Sign in with Authelia"
|
||||||
|
Environment="AUTH_JIT_MODE=create_and_link"
|
||||||
|
# email's domain, e.g. ilnmors.internal then only user@ilnmors.internal is allowed to sign-up
|
||||||
|
Environment="ALLOWED_OIDC_DOMAINS="
|
||||||
|
|
||||||
|
# WebAuthn / Passkey
|
||||||
|
Environment="WEBAUTHN_RP_ID={{ domain['public'] }}"
|
||||||
|
Environment="WEBAUTHN_ALLOWED_ORIGINS=https://{{ services['sure']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
|
||||||
|
# Provider
|
||||||
|
## Currency
|
||||||
|
Environment="EXCHANGE_RATE_PROVIDER=yahoo_finance"
|
||||||
|
Environment="SECURITIES_PROVIDER=yahoo_finance"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Sure Worker
|
||||||
|
|
||||||
|
After=network-online.target redis_sure.service
|
||||||
|
Wants=network-online.target redis_sure.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=ghcr.io/we-promise/sure:{{ version['containers']['sure'] }}
|
||||||
|
ContainerName=sure-worker
|
||||||
|
HostName=sure-worker
|
||||||
|
|
||||||
|
Volume=%h/data/containers/sure/storage:/rails/storage:rw
|
||||||
|
Volume=%h/containers/sure/ssl:/etc/ssl/sure:ro
|
||||||
|
|
||||||
|
Exec=bundle exec sidekiq
|
||||||
|
|
||||||
|
# General
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
Environment="SELF_HOSTED=true"
|
||||||
|
Environment="ONBOARDING_STATE=closed"
|
||||||
|
Environment="RAILS_FORCE_SSL=false"
|
||||||
|
Environment="RAILS_ASSUME_SSL=true"
|
||||||
|
Environment="APP_DOMAIN={{ services['sure']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
Secret=SURE_SECRET_KEY_BASE,type=env,target=SECRET_KEY_BASE
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
Environment="POSTGRES_USER=sure"
|
||||||
|
Environment="POSTGRES_DB=sure_db"
|
||||||
|
Environment="DB_HOST={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}"
|
||||||
|
Environment="DB_PORT={{ services['postgresql']['ports']['tcp'] }}"
|
||||||
|
Environment="PGSSLMODE=verify-full"
|
||||||
|
Environment="PGSSLROOTCERT=/etc/ssl/sure/{{ root_cert_filename }}"
|
||||||
|
Secret=SURE_POSTGRES_PASSWORD,type=env,target=POSTGRES_PASSWORD
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
Environment="REDIS_URL=redis://host.containers.internal:{{ services['sure']['ports']['redis'] }}/1"
|
||||||
|
|
||||||
|
# OIDC - Authelia
|
||||||
|
Environment="OIDC_CLIENT_ID=sure"
|
||||||
|
Environment="OIDC_ISSUER=https://{{ services['authelia']['domain'] }}.{{ domain['public'] }}"
|
||||||
|
Environment="OIDC_REDIRECT_URI=https://{{ services['sure']['domain']['public'] }}.{{ domain['public'] }}/auth/openid_connect/callback"
|
||||||
|
Secret=SURE_OIDC_CLIENT_SECRET,type=env,target=OIDC_CLIENT_SECRET
|
||||||
|
Environment="OIDC_BUTTON_LABEL=Sign in with Authelia"
|
||||||
|
Environment="AUTH_JIT_MODE=create_and_link"
|
||||||
|
# email's domain, e.g. ilnmors.internal then only user@ilnmors.internal is allowed to sign-up
|
||||||
|
Environment="ALLOWED_OIDC_DOMAINS="
|
||||||
|
|
||||||
|
# WebAuthn / Passkey
|
||||||
|
Environment="WEBAUTHN_RP_ID={{ domain['public'] }}"
|
||||||
|
Environment="WEBAUTHN_ALLOWED_ORIGINS=https://{{ services['sure']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
|
||||||
|
# Provider
|
||||||
|
## Currency
|
||||||
|
Environment="EXCHANGE_RATE_PROVIDER=yahoo_finance"
|
||||||
|
Environment="SECURITIES_PROVIDER=yahoo_finance"
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
[Quadlet]
|
||||||
|
DefaultDependencies=false
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Vaultwarden
|
||||||
|
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=docker.io/vaultwarden/server:{{ version['containers']['vaultwarden'] }}
|
||||||
|
|
||||||
|
ContainerName=vaultwarden
|
||||||
|
HostName=vaultwarden
|
||||||
|
|
||||||
|
PublishPort={{ services['vaultwarden']['ports']['http'] }}:80/tcp
|
||||||
|
|
||||||
|
Volume=%h/data/containers/vaultwarden:/data:rw
|
||||||
|
Volume=%h/containers/vaultwarden/ssl:/etc/ssl/vaultwarden:ro
|
||||||
|
|
||||||
|
Environment="TZ=Asia/Seoul"
|
||||||
|
Environment="DOMAIN=https://{{ services['vaultwarden']['domain']['public'] }}.{{ domain['public'] }}"
|
||||||
|
Environment="SIGNUPS_ALLOWED=false"
|
||||||
|
Secret=VW_ADMIN_TOKEN,type=env,target=ADMIN_TOKEN
|
||||||
|
Secret=VW_DATABASE_URL,type=env,target=DATABASE_URL
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10s
|
||||||
|
TimeoutStopSec=120
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -15,7 +15,7 @@ ContainerName=authelia
|
|||||||
HostName=authelia
|
HostName=authelia
|
||||||
|
|
||||||
# Web UI
|
# Web UI
|
||||||
PublishPort=9091:9091/tcp
|
PublishPort={{ services['authelia']['ports']['http'] }}:9091/tcp
|
||||||
|
|
||||||
|
|
||||||
Volume=%h/containers/authelia/config:/config:rw
|
Volume=%h/containers/authelia/config:/config:rw
|
||||||
@@ -56,8 +56,9 @@ Exec=--config /config/authelia.yaml
|
|||||||
# Wait for dependency
|
# Wait for dependency
|
||||||
# They run as rootless podman container, so their port is not opened until they are normaly running
|
# They run as rootless podman container, so their port is not opened until they are normaly running
|
||||||
# Check their ports with nc command
|
# Check their ports with nc command
|
||||||
ExecStartPre=/usr/bin/nc -zv {{ infra_uri['postgresql']['domain'] }} {{ infra_uri['postgresql']['ports']['tcp'] }}
|
ExecStartPre=/usr/bin/nc -zv {{ services['postgresql']['domain'] }}.{{ domain['internal'] }} {{ services['postgresql']['ports']['tcp'] }}
|
||||||
ExecStartPre=/usr/bin/nc -zv {{ infra_uri['ldap']['domain'] }} {{ infra_uri['ldap']['ports']['ldaps'] }}
|
# services['ldap']['ports']['ldaps'] is 6360, but nftables works on 636 the original port
|
||||||
|
ExecStartPre=/usr/bin/nc -zv {{ services['ldap']['domain'] }}.{{ domain['internal'] }} 636
|
||||||
ExecStartPre=sleep 5
|
ExecStartPre=sleep 5
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=10s
|
RestartSec=10s
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ theme: 'auto'
|
|||||||
# Server configuration
|
# Server configuration
|
||||||
server:
|
server:
|
||||||
# TLS will be applied on caddy
|
# TLS will be applied on caddy
|
||||||
address: 'tcp://:9091/'
|
address: 'tcp://:{{ services['authelia']['ports']['http'] }}/'
|
||||||
|
|
||||||
# Log configuration
|
# Log configuration
|
||||||
log:
|
log:
|
||||||
@@ -20,7 +20,7 @@ log:
|
|||||||
# TOTP configuration
|
# TOTP configuration
|
||||||
totp:
|
totp:
|
||||||
# issure option is for 2FA app. It works as identifier. "My homelab' or 'ilnmors.internal', 'Authelia - ilnmors'
|
# issure option is for 2FA app. It works as identifier. "My homelab' or 'ilnmors.internal', 'Authelia - ilnmors'
|
||||||
issuer: 'ilnmors.internal'
|
issuer: '{{ domain['internal'] }}'
|
||||||
|
|
||||||
# Identity validation confituration
|
# Identity validation confituration
|
||||||
identity_validation:
|
identity_validation:
|
||||||
@@ -31,21 +31,21 @@ identity_validation:
|
|||||||
authentication_backend:
|
authentication_backend:
|
||||||
ldap:
|
ldap:
|
||||||
# ldaps uses 636 -> NAT automatically change port 636 in output packet -> 2636 which lldap server uses.
|
# ldaps uses 636 -> NAT automatically change port 636 in output packet -> 2636 which lldap server uses.
|
||||||
address: 'ldaps://ldap.ilnmors.internal'
|
address: 'ldaps://{{ services['ldap']['domain'] }}.{{ domain['internal'] }}'
|
||||||
implementation: 'lldap'
|
implementation: 'lldap'
|
||||||
# tls configruation, it uses certificates_directory's /etc/ssl/authelia/ilnmors_root_ca.crt
|
# tls configruation, it uses certificates_directory's /etc/ssl/authelia/{{ root_cert_filename }}
|
||||||
tls:
|
tls:
|
||||||
server_name: 'ldap.ilnmors.internal'
|
server_name: '{{ services['ldap']['domain'] }}.{{ domain['internal'] }}'
|
||||||
skip_verify: false
|
skip_verify: false
|
||||||
# LLDAP base DN
|
# LLDAP base DN
|
||||||
base_dn: 'dc=ilnmors,dc=internal'
|
base_dn: '{{ domain['dc'] }}'
|
||||||
additional_users_dn: 'ou=people'
|
additional_users_dn: 'ou=people'
|
||||||
additional_groups_dn: 'ou=groups'
|
additional_groups_dn: 'ou=groups'
|
||||||
# LLDAP filters
|
# LLDAP filters
|
||||||
users_filter: '(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))'
|
users_filter: '(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))'
|
||||||
groups_filter: '(&(member={dn})(objectClass=groupOfNames))'
|
groups_filter: '(&(member={dn})(objectClass=groupOfNames))'
|
||||||
# LLDAP bind account configuration
|
# LLDAP bind account configuration
|
||||||
user: 'uid=authelia,ou=people,dc=ilnmors,dc=internal'
|
user: 'uid=authelia,ou=people,{{ domain['dc'] }}'
|
||||||
password: '' # $AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE option is designated in container file
|
password: '' # $AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE option is designated in container file
|
||||||
|
|
||||||
# Access control configuration
|
# Access control configuration
|
||||||
@@ -53,14 +53,12 @@ access_control:
|
|||||||
default_policy: 'deny'
|
default_policy: 'deny'
|
||||||
rules:
|
rules:
|
||||||
# authelia portal
|
# authelia portal
|
||||||
- domain: 'authelia.ilnmors.internal'
|
- domain: '{{ services['authelia']['domain'] }}.{{ domain['public'] }}'
|
||||||
policy: 'bypass'
|
policy: 'bypass'
|
||||||
- domain: 'authelia.ilnmors.com'
|
# - domain: 'test.ilnmors.com'
|
||||||
policy: 'bypass'
|
# policy: 'one_factor'
|
||||||
- domain: 'test.ilnmors.com'
|
# subject:
|
||||||
policy: 'one_factor'
|
# - 'group:admins'
|
||||||
subject:
|
|
||||||
- 'group:admins'
|
|
||||||
# Session provider configuration
|
# Session provider configuration
|
||||||
session:
|
session:
|
||||||
secret: '' # $AUTHELIA_SESSION_SECRET_FILE is designated in container file
|
secret: '' # $AUTHELIA_SESSION_SECRET_FILE is designated in container file
|
||||||
@@ -68,8 +66,8 @@ session:
|
|||||||
inactivity: '24 hours' # Session maintains for 24 hours without actions
|
inactivity: '24 hours' # Session maintains for 24 hours without actions
|
||||||
cookies:
|
cookies:
|
||||||
- name: 'authelia_public_session'
|
- name: 'authelia_public_session'
|
||||||
domain: 'ilnmors.com'
|
domain: '{{ domain['public'] }}'
|
||||||
authelia_url: 'https://authelia.ilnmors.com'
|
authelia_url: 'https://{{ services['authelia']['domain'] }}.{{ domain['public'] }}'
|
||||||
same_site: 'lax'
|
same_site: 'lax'
|
||||||
|
|
||||||
# This authelia doesn't use Redis.
|
# This authelia doesn't use Redis.
|
||||||
@@ -78,12 +76,12 @@ session:
|
|||||||
storage:
|
storage:
|
||||||
encryption_key: '' # $AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE is designated in container file
|
encryption_key: '' # $AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE is designated in container file
|
||||||
postgres:
|
postgres:
|
||||||
address: 'tcp://{{ infra_uri['postgresql']['domain'] }}:{{ infra_uri['postgresql']['ports']['tcp'] }}'
|
address: 'tcp://{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}'
|
||||||
database: 'authelia_db'
|
database: 'authelia_db'
|
||||||
username: 'authelia'
|
username: 'authelia'
|
||||||
password: '' # $AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE is designated in container file
|
password: '' # $AUTHELIA_STORAGE_POSTGRES_PASSWORD_FILE is designated in container file
|
||||||
tls:
|
tls:
|
||||||
server_name: '{{ infra_uri['postgresql']['domain'] }}'
|
server_name: '{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}'
|
||||||
skip_verify: false
|
skip_verify: false
|
||||||
|
|
||||||
# Notification provider
|
# Notification provider
|
||||||
@@ -101,7 +99,7 @@ identity_providers:
|
|||||||
key: {{ secret "/run/secrets/AUTHELIA_JWKS_RS256" | mindent 10 "|" | msquote }}
|
key: {{ secret "/run/secrets/AUTHELIA_JWKS_RS256" | mindent 10 "|" | msquote }}
|
||||||
- algorithm: 'ES256'
|
- algorithm: 'ES256'
|
||||||
use: 'sig'
|
use: 'sig'
|
||||||
key: {{ secret "/run/secrets/AUTHELIA_JWKS_ES256" | mindent 10 "|" | msquote }}{% endraw %}
|
key: {{ secret "/run/secrets/AUTHELIA_JWKS_ES256" | mindent 10 "|" | msquote }}{% endraw %}
|
||||||
clients:
|
clients:
|
||||||
# https://www.authelia.com/integration/openid-connect/clients/synology-dsm/
|
# https://www.authelia.com/integration/openid-connect/clients/synology-dsm/
|
||||||
- client_id: 'dsm'
|
- client_id: 'dsm'
|
||||||
@@ -117,7 +115,7 @@ identity_providers:
|
|||||||
require_pkce: false
|
require_pkce: false
|
||||||
pkce_challenge_method: ''
|
pkce_challenge_method: ''
|
||||||
redirect_uris:
|
redirect_uris:
|
||||||
- 'https://{{ infra_uri['nas']['domain'] }}:{{ infra_uri['nas']['ports']['https'] }}'
|
- 'https://{{ services['nas']['domain'] }}.{{ domain['internal'] }}:{{ services['nas']['ports']['https'] }}'
|
||||||
scopes:
|
scopes:
|
||||||
- 'openid'
|
- 'openid'
|
||||||
- 'profile'
|
- 'profile'
|
||||||
@@ -131,3 +129,134 @@ identity_providers:
|
|||||||
userinfo_signed_response_alg: 'none'
|
userinfo_signed_response_alg: 'none'
|
||||||
# [ client_secret_post | client_secret_basic ]
|
# [ client_secret_post | client_secret_basic ]
|
||||||
token_endpoint_auth_method: 'client_secret_post'
|
token_endpoint_auth_method: 'client_secret_post'
|
||||||
|
# https://www.authelia.com/integration/openid-connect/clients/gitea/
|
||||||
|
- client_id: 'gitea'
|
||||||
|
client_name: 'gitea'
|
||||||
|
client_secret: '{{ hostvars['console']['gitea']['oidc']['hash'] }}'
|
||||||
|
public: false
|
||||||
|
authorization_policy: 'one_factor'
|
||||||
|
require_pkce: false
|
||||||
|
pkce_challenge_method: ''
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://{{ services['gitea']['domain']['public'] }}.{{ domain['public'] }}/user/oauth2/authelia/callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'email'
|
||||||
|
- 'profile'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
access_token_signed_response_alg: 'none'
|
||||||
|
userinfo_signed_response_alg: 'none'
|
||||||
|
token_endpoint_auth_method: 'client_secret_basic'
|
||||||
|
# https://www.authelia.com/integration/openid-connect/clients/immich/
|
||||||
|
- client_id: 'immich'
|
||||||
|
client_name: 'immich'
|
||||||
|
client_secret: '{{ hostvars['console']['immich']['oidc']['hash'] }}'
|
||||||
|
public: false
|
||||||
|
authorization_policy: 'one_factor'
|
||||||
|
require_pkce: false
|
||||||
|
pkce_challenge_method: ''
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://{{ services['immich']['domain']['public'] }}.{{ domain['public'] }}/auth/login'
|
||||||
|
- 'https://{{ services['immich']['domain']['public'] }}.{{ domain['public'] }}/user-settings'
|
||||||
|
- 'app.immich:///oauth-callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
access_token_signed_response_alg: 'none'
|
||||||
|
userinfo_signed_response_alg: 'none'
|
||||||
|
token_endpoint_auth_method: 'client_secret_post'
|
||||||
|
# https://www.authelia.com/integration/openid-connect/clients/paperless/
|
||||||
|
- client_id: 'paperless'
|
||||||
|
client_name: 'Paperless'
|
||||||
|
client_secret: '{{ hostvars['console']['paperless']['oidc']['hash'] }}'
|
||||||
|
public: false
|
||||||
|
authorization_policy: 'one_factor'
|
||||||
|
require_pkce: true
|
||||||
|
pkce_challenge_method: 'S256'
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://{{ services['paperless']['domain']['public'] }}.{{ domain['public'] }}/accounts/oidc/authelia/login/callback/'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
||||||
|
- 'groups'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
access_token_signed_response_alg: 'none'
|
||||||
|
userinfo_signed_response_alg: 'none'
|
||||||
|
token_endpoint_auth_method: 'client_secret_post'
|
||||||
|
# https://docs.affine.pro/self-host-affine/administer/oauth-2-0
|
||||||
|
- client_id: 'affine'
|
||||||
|
client_name: 'Affine'
|
||||||
|
client_secret: '{{ hostvars['console']['affine']['oidc']['hash'] }}'
|
||||||
|
public: false
|
||||||
|
authorization_policy: 'one_factor'
|
||||||
|
require_pkce: false
|
||||||
|
pkce_challenge_method: ''
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://{{ services['affine']['domain']['public'] }}.{{ domain['public'] }}/oauth/callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
access_token_signed_response_alg: 'none'
|
||||||
|
userinfo_signed_response_alg: 'none'
|
||||||
|
token_endpoint_auth_method: 'client_secret_post'
|
||||||
|
# https://www.authelia.com/integration/openid-connect/clients/nextcloud/#openid-connect-user-backend-app
|
||||||
|
- client_id: 'nextcloud'
|
||||||
|
client_name: 'Nextcloud'
|
||||||
|
client_secret: '{{ hostvars['console']['nextcloud']['oidc']['hash'] }}'
|
||||||
|
public: false
|
||||||
|
authorization_policy: 'one_factor'
|
||||||
|
require_pkce: true
|
||||||
|
pkce_challenge_method: 'S256'
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}/apps/user_oidc/code'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'profile'
|
||||||
|
- 'email'
|
||||||
|
- 'groups'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
access_token_signed_response_alg: 'none'
|
||||||
|
userinfo_signed_response_alg: 'none'
|
||||||
|
token_endpoint_auth_method: 'client_secret_post'
|
||||||
|
# https://www.authelia.com/integration/openid-connect/clients/sure/
|
||||||
|
- client_id: 'sure'
|
||||||
|
client_name: 'Sure'
|
||||||
|
client_secret: '{{ hostvars['console']['sure']['oidc']['hash'] }}'
|
||||||
|
public: false
|
||||||
|
authorization_policy: 'one_factor'
|
||||||
|
require_pkce: true
|
||||||
|
pkce_challenge_method: 'S256'
|
||||||
|
redirect_uris:
|
||||||
|
- 'https://{{ services['sure']['domain']['public'] }}.{{ domain['public'] }}/auth/openid_connect/callback'
|
||||||
|
scopes:
|
||||||
|
- 'openid'
|
||||||
|
- 'email'
|
||||||
|
- 'profile'
|
||||||
|
- 'groups'
|
||||||
|
response_types:
|
||||||
|
- 'code'
|
||||||
|
grant_types:
|
||||||
|
- 'authorization_code'
|
||||||
|
access_token_signed_response_alg: 'none'
|
||||||
|
userinfo_signed_response_alg: 'none'
|
||||||
|
token_endpoint_auth_method: 'client_secret_basic'
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ RUN xcaddy build \
|
|||||||
FROM docker.io/library/caddy:{{ version['containers']['caddy'] }}
|
FROM docker.io/library/caddy:{{ version['containers']['caddy'] }}
|
||||||
|
|
||||||
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
||||||
COPY ./ilnmors_root_ca.crt /usr/local/share/ca-certificates/ilnmors_root_ca.crt
|
COPY ./{{ root_cert_filename }} /usr/local/share/ca-certificates/{{ root_cert_filename }}
|
||||||
|
|
||||||
RUN update-ca-certificates
|
RUN update-ca-certificates
|
||||||
|
|||||||
@@ -14,18 +14,18 @@ Wants=network-online.target
|
|||||||
|
|
||||||
|
|
||||||
[Container]
|
[Container]
|
||||||
Image=ilnmors.internal/{{ node['name'] }}/caddy:{{ version['containers']['caddy'] }}
|
Image={{ domain['internal'] }}/{{ node['name'] }}/caddy:{{ version['containers']['caddy'] }}
|
||||||
|
|
||||||
ContainerName=caddy_{{ node['name'] }}
|
ContainerName=caddy_{{ node['name'] }}
|
||||||
HostName=caddy_{{ node['name'] }}
|
HostName=caddy_{{ node['name'] }}
|
||||||
{% if node['name'] == 'infra' %}
|
{% if node['name'] == 'infra' %}
|
||||||
AddHost={{ infra_uri['ca']['domain'] }}:host-gateway
|
AddHost={{ services['ca']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
AddHost={{ infra_uri['prometheus']['domain'] }}:host-gateway
|
AddHost={{ services['prometheus']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
AddHost={{ infra_uri['loki']['domain'] }}:host-gateway
|
AddHost={{ services['loki']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
PublishPort=2080:80/tcp
|
PublishPort={{ services['caddy']['ports']['http'] }}:80/tcp
|
||||||
PublishPort=2443:443/tcp
|
PublishPort={{ services['caddy']['ports']['https'] }}:443/tcp
|
||||||
|
|
||||||
Volume=%h/containers/caddy/etc:/etc/caddy:ro
|
Volume=%h/containers/caddy/etc:/etc/caddy:ro
|
||||||
Volume=%h/containers/caddy/data:/data:rw
|
Volume=%h/containers/caddy/data:/data:rw
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
servers {
|
||||||
|
# Only accept packets from auth main caddy
|
||||||
|
trusted_proxies static {{ hostvars['fw']['network4']['auth']['server'] }} {{ hostvars['fw']['network6']['auth']['server'] }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Private TLS ACME with DNS-01-challenge
|
||||||
|
(private_tls) {
|
||||||
|
tls {
|
||||||
|
issuer acme {
|
||||||
|
dir https://{{ services['ca']['domain'] }}.{{ domain['internal'] }}:{{ services['ca']['ports']['https'] }}/acme/acme@{{ domain['internal'] }}/directory
|
||||||
|
dns rfc2136 {
|
||||||
|
server {{ services['bind']['domain'] }}.{{ domain['internal'] }}:{{ services['bind']['ports']['dns'] }}
|
||||||
|
key_name acme-key
|
||||||
|
key_alg hmac-sha256
|
||||||
|
key "{file./run/secrets/CADDY_ACME_KEY}"
|
||||||
|
}
|
||||||
|
resolvers {{ services['bind']['domain'] }}.{{ domain['internal'] }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{ node['name'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
metrics
|
||||||
|
}
|
||||||
|
# test.app.ilnmors.internal {
|
||||||
|
# import private_tls
|
||||||
|
# root * /usr/share/caddy
|
||||||
|
# file_server
|
||||||
|
# }
|
||||||
|
{{ services['vaultwarden']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['vaultwarden']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['gitea']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['gitea']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['immich']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['immich']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['paperless']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['paperless']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['affine']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['affine']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['nextcloud']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['nextcloud']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['collabora']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['collabora']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['sure']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
import private_tls
|
||||||
|
reverse_proxy host.containers.internal:{{ services['sure']['ports']['http'] }} {
|
||||||
|
header_up Host {http.request.header.X-Forwarded-Host}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
# CrowdSec LAPI connection
|
# CrowdSec LAPI connection
|
||||||
crowdsec {
|
crowdsec {
|
||||||
api_url https://{{ infra_uri['crowdsec']['domain'] }}:{{ infra_uri['crowdsec']['ports']['https'] }}
|
api_url https://{{ services['crowdsec']['domain'] }}.{{ domain['internal'] }}:{{ services['crowdsec']['ports']['https'] }}
|
||||||
api_key "{file./run/secrets/CADDY_CROWDSEC_KEY}"
|
api_key "{file./run/secrets/CADDY_CROWDSEC_KEY}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,48 +15,130 @@
|
|||||||
roll_size 100MiB
|
roll_size 100MiB
|
||||||
roll_keep 1
|
roll_keep 1
|
||||||
}
|
}
|
||||||
format json
|
format json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# Private TLS ACME with DNS-01-challenge
|
# Private TLS ACME with DNS-01-challenge
|
||||||
(private_tls) {
|
(private_tls) {
|
||||||
tls {
|
tls {
|
||||||
issuer acme {
|
issuer acme {
|
||||||
dir https://{{ infra_uri['ca']['domain'] }}:{{ infra_uri['ca']['ports']['https'] }}/acme/acme@ilnmors.internal/directory
|
dir https://{{ services['ca']['domain'] }}.{{ domain['internal'] }}:{{ services['ca']['ports']['https'] }}/acme/acme@{{ domain['internal'] }}/directory
|
||||||
dns rfc2136 {
|
dns rfc2136 {
|
||||||
server {{ infra_uri['bind']['domain'] }}:{{ infra_uri['bind']['ports']['dns'] }}
|
server {{ services['bind']['domain'] }}.{{ domain['internal'] }}:{{ services['bind']['ports']['dns'] }}
|
||||||
key_name acme-key
|
key_name acme-key
|
||||||
key_alg hmac-sha256
|
key_alg hmac-sha256
|
||||||
key "{file./run/secrets/CADDY_ACME_KEY}"
|
key "{file./run/secrets/CADDY_ACME_KEY}"
|
||||||
}
|
}
|
||||||
|
resolvers {{ services['bind']['domain'] }}.{{ domain['internal'] }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Public domain
|
# Public domain
|
||||||
authelia.ilnmors.com {
|
{{ services['authelia']['domain'] }}.{{ domain['public'] }} {
|
||||||
import crowdsec_log
|
import crowdsec_log
|
||||||
route {
|
route {
|
||||||
crowdsec
|
crowdsec
|
||||||
reverse_proxy host.containers.internal:9091
|
reverse_proxy host.containers.internal:{{ services['authelia']['ports']['http'] }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test.ilnmors.com {
|
# test.ilnmors.com {
|
||||||
|
# import crowdsec_log
|
||||||
|
# route {
|
||||||
|
# crowdsec
|
||||||
|
# forward_auth host.containers.internal:9091 {
|
||||||
|
# # Authelia Forward Auth endpoint URI
|
||||||
|
# uri /api/authz/forward-auth
|
||||||
|
# copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
||||||
|
# }
|
||||||
|
# root * /usr/share/caddy
|
||||||
|
# file_server
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# test.app.ilnmors.com {
|
||||||
|
# import crowdsec_log
|
||||||
|
# route {
|
||||||
|
# crowdsec
|
||||||
|
# reverse_proxy https://test.app.ilnmors.internal {
|
||||||
|
# header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
{{ services['vaultwarden']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
import crowdsec_log
|
import crowdsec_log
|
||||||
route {
|
route {
|
||||||
crowdsec
|
crowdsec
|
||||||
forward_auth host.containers.internal:9091 {
|
reverse_proxy https://{{ services['vaultwarden']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
# Authelia Forward Auth endpoint URI
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
uri /api/authz/forward-auth
|
}
|
||||||
copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
|
}
|
||||||
|
}
|
||||||
|
{{ services['gitea']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{ services['gitea']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['immich']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{ services['immich']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['paperless']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{ services['paperless']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['affine']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{ services['affine']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{services['nextcloud']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['collabora']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{services['collabora']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ services['sure']['domain']['public'] }}.{{ domain['public'] }} {
|
||||||
|
import crowdsec_log
|
||||||
|
route {
|
||||||
|
crowdsec
|
||||||
|
reverse_proxy https://{{services['sure']['domain']['internal'] }}.{{ domain['internal'] }} {
|
||||||
|
header_up Host {http.reverse_proxy.upstream.host}
|
||||||
}
|
}
|
||||||
root * /usr/share/caddy
|
|
||||||
file_server
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Internal domain
|
# Internal domain
|
||||||
auth.ilnmors.internal {
|
{{ node['name'] }}.{{ domain['internal'] }} {
|
||||||
import private_tls
|
import private_tls
|
||||||
metrics
|
metrics
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,39 +2,40 @@
|
|||||||
(private_tls) {
|
(private_tls) {
|
||||||
tls {
|
tls {
|
||||||
issuer acme {
|
issuer acme {
|
||||||
dir https://{{ infra_uri['ca']['domain'] }}:{{ infra_uri['ca']['ports']['https'] }}/acme/acme@ilnmors.internal/directory
|
dir https://{{ services['ca']['domain'] }}.{{ domain['internal'] }}:{{ services['ca']['ports']['https'] }}/acme/acme@{{ domain['internal'] }}/directory
|
||||||
dns rfc2136 {
|
dns rfc2136 {
|
||||||
server {{ infra_uri['bind']['domain'] }}:{{ infra_uri['bind']['ports']['dns'] }}
|
server {{ services['bind']['domain'] }}.{{ domain['internal'] }}:{{ services['bind']['ports']['dns'] }}
|
||||||
key_name acme-key
|
key_name acme-key
|
||||||
key_alg hmac-sha256
|
key_alg hmac-sha256
|
||||||
key "{file./run/secrets/CADDY_ACME_KEY}"
|
key "{file./run/secrets/CADDY_ACME_KEY}"
|
||||||
}
|
}
|
||||||
|
resolvers {{ services['bind']['domain'] }}.{{ domain['internal'] }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
infra.ilnmors.internal {
|
{{ node['name'] }}.{{ domain['internal'] }} {
|
||||||
import private_tls
|
import private_tls
|
||||||
metrics
|
metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
{{ infra_uri['ldap']['domain'] }} {
|
{{ services['ldap']['domain'] }}.{{ domain['internal'] }} {
|
||||||
import private_tls
|
import private_tls
|
||||||
route {
|
route {
|
||||||
reverse_proxy host.containers.internal:{{ infra_uri['ldap']['ports']['http'] }}
|
reverse_proxy host.containers.internal:{{ services['ldap']['ports']['http'] }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{ infra_uri['prometheus']['domain'] }} {
|
{{ services['prometheus']['domain'] }}.{{ domain['internal'] }} {
|
||||||
import private_tls
|
import private_tls
|
||||||
route {
|
route {
|
||||||
reverse_proxy https://{{ infra_uri['prometheus']['domain'] }}:{{ infra_uri['prometheus']['ports']['https'] }}
|
reverse_proxy https://{{ services['prometheus']['domain'] }}.{{ domain['internal'] }}:{{ services['prometheus']['ports']['https'] }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
grafana.ilnmors.internal {
|
{{ services['grafana']['domain'] }}.{{ domain['internal'] }} {
|
||||||
import private_tls
|
import private_tls
|
||||||
route {
|
route {
|
||||||
reverse_proxy host.containers.internal:3000
|
reverse_proxy host.containers.internal:{{ services['grafana']['ports']['http'] }}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Image=docker.io/smallstep/step-ca:{{ version['containers']['step'] }}
|
|||||||
ContainerName=ca
|
ContainerName=ca
|
||||||
HostName=ca
|
HostName=ca
|
||||||
|
|
||||||
PublishPort=9000:9000/tcp
|
PublishPort={{ services['ca']['ports']['https'] }}:9000/tcp
|
||||||
|
|
||||||
Volume=%h/containers/ca/certs:/home/step/certs:ro
|
Volume=%h/containers/ca/certs:/home/step/certs:ro
|
||||||
Volume=%h/containers/ca/secrets:/home/step/secrets:ro
|
Volume=%h/containers/ca/secrets:/home/step/secrets:ro
|
||||||
@@ -22,14 +22,17 @@ Volume=%h/containers/ca/db:/home/step/db:rw
|
|||||||
Volume=%h/containers/ca/templates:/home/step/templates:rw
|
Volume=%h/containers/ca/templates:/home/step/templates:rw
|
||||||
|
|
||||||
Environment="TZ=Asia/Seoul"
|
Environment="TZ=Asia/Seoul"
|
||||||
Environment="PWDPATH=/run/secrets/STEP_CA_PASSWORD"
|
# Since 0.30.0, Docker CMD no longer expands PWDPATH.
|
||||||
|
#Environment="PWDPATH=/run/secrets/STEP_CA_PASSWORD"
|
||||||
|
|
||||||
Secret=STEP_CA_PASSWORD,target=/run/secrets/STEP_CA_PASSWORD
|
Secret=STEP_CA_PASSWORD,target=/run/secrets/STEP_CA_PASSWORD
|
||||||
|
|
||||||
|
Exec=/usr/local/bin/step-ca --password-file /run/secrets/STEP_CA_PASSWORD /home/step/config/ca.json
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=10s
|
RestartSec=10s
|
||||||
TimeoutStopSec=120
|
TimeoutStopSec=120
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"root": "/home/step/certs/ilnmors_root_ca.crt",
|
"root": "/home/step/certs/{{ root_cert_filename }}",
|
||||||
"federatedRoots": null,
|
"federatedRoots": null,
|
||||||
"crt": "/home/step/certs/ilnmors_intermediate_ca.crt",
|
"crt": "/home/step/certs/{{ intermediate_cert_filename }}",
|
||||||
"key": "/home/step/secrets/ilnmors_intermediate_ca.key",
|
"key": "/home/step/secrets/{{ intermediate_key_filename }}",
|
||||||
"address": ":9000",
|
"address": ":9000",
|
||||||
"insecureAddress": "",
|
"insecureAddress": "",
|
||||||
"dnsNames": [
|
"dnsNames": [
|
||||||
"{{ infra_uri['ca']['domain'] }}"
|
"{{ services['ca']['domain'] }}.{{ domain['internal'] }}"
|
||||||
],
|
],
|
||||||
"logger": {
|
"logger": {
|
||||||
"format": "text"
|
"format": "text"
|
||||||
@@ -21,8 +21,9 @@
|
|||||||
"x509": {
|
"x509": {
|
||||||
"allow": {
|
"allow": {
|
||||||
"dns": [
|
"dns": [
|
||||||
"ilnmors.internal",
|
"{{ domain['internal'] }}",
|
||||||
"*.ilnmors.internal"
|
"*.{{ domain['internal'] }}",
|
||||||
|
"*.app.{{ domain['internal'] }}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"allowWildcardNames": true
|
"allowWildcardNames": true
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
"provisioners": [
|
"provisioners": [
|
||||||
{
|
{
|
||||||
"type": "ACME",
|
"type": "ACME",
|
||||||
"name": "acme@ilnmors.internal",
|
"name": "acme@{{ domain['internal'] }}",
|
||||||
"claims": {
|
"claims": {
|
||||||
"defaultTLSCertDuration": "2160h0m0s",
|
"defaultTLSCertDuration": "2160h0m0s",
|
||||||
"enableSSHCA": true,
|
"enableSSHCA": true,
|
||||||
@@ -57,5 +58,5 @@
|
|||||||
"maxVersion": 1.3,
|
"maxVersion": 1.3,
|
||||||
"renegotiation": false
|
"renegotiation": false
|
||||||
},
|
},
|
||||||
"commonName": "ilnmors Online CA"
|
"commonName": "{{ domain['internal'] }} Online CA"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ca-url": "https://{{ infra_uri['ca']['domain'] }}:{{ infra_uri['ca']['ports']['https'] }}",
|
"ca-url": "https://{{ services['ca']['domain'] }}.{{ domain['internal'] }}:{{ services['ca']['ports']['https'] }}",
|
||||||
"ca-config": "/home/step/config/ca.json",
|
"ca-config": "/home/step/config/ca.json",
|
||||||
"fingerprint": "215c851d2d0d2dbf90fc3507425207c29696ffd587c640c94a68dddb1d84d8e8",
|
"fingerprint": "215c851d2d0d2dbf90fc3507425207c29696ffd587c640c94a68dddb1d84d8e8",
|
||||||
"root": "/home/step/certs/ilnmors_root_ca.crt"
|
"root": "/home/step/certs/{{ root_cert_filename }}"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ provisioning = /etc/grafana/provisioning
|
|||||||
|
|
||||||
[server]
|
[server]
|
||||||
protocol = http
|
protocol = http
|
||||||
http_port = 3000
|
http_port = {{ services['grafana']['ports']['http'] }}
|
||||||
domain = grafana.ilnmors.internal
|
domain = {{ services['grafana']['domain'] }}.{{ domain['internal'] }}
|
||||||
root_url = http://grafana.ilnmors.internal/
|
root_url = http://{{ services['grafana']['domain'] }}.{{ domain['internal'] }}/
|
||||||
router_logging = false
|
router_logging = false
|
||||||
|
|
||||||
[database]
|
[database]
|
||||||
type = postgres
|
type = postgres
|
||||||
host = {{ infra_uri['postgresql']['domain'] }}:{{ infra_uri['postgresql']['ports']['tcp'] }}
|
host = {{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}
|
||||||
name = grafana_db
|
name = grafana_db
|
||||||
user = grafana
|
user = grafana
|
||||||
password = $__file{/run/secrets/GF_DB_PASSWORD}
|
password = $__file{/run/secrets/GF_DB_PASSWORD}
|
||||||
ssl_mode = verify-full
|
ssl_mode = verify-full
|
||||||
ca_cert_path = /etc/ssl/grafana/ilnmors_root_ca.crt
|
ca_cert_path = /etc/ssl/grafana/{{ root_cert_filename }}
|
||||||
|
|
||||||
[auth.ldap]
|
[auth.ldap]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# https://github.com/lldap/lldap/blob/main/example_configs/grafana_ldap_config.toml
|
# https://github.com/lldap/lldap/blob/main/example_configs/grafana_ldap_config.toml
|
||||||
[[servers]]
|
[[servers]]
|
||||||
host = "{{ infra_uri['ldap']['domain'] }}"
|
host = "{{ services['ldap']['domain'] }}.{{ domain['internal'] }}"
|
||||||
port = {{ infra_uri['ldap']['ports']['ldaps'] }}
|
port = {{ services['ldap']['ports']['ldaps'] }}
|
||||||
# Activate STARTTLS or LDAPS
|
# Activate STARTTLS or LDAPS
|
||||||
use_ssl = true
|
use_ssl = true
|
||||||
# true = STARTTLS, false = LDAPS
|
# true = STARTTLS, false = LDAPS
|
||||||
@@ -9,16 +9,16 @@ start_tls = false
|
|||||||
tls_ciphers = []
|
tls_ciphers = []
|
||||||
min_tls_version = ""
|
min_tls_version = ""
|
||||||
ssl_skip_verify = false
|
ssl_skip_verify = false
|
||||||
root_ca_cert = "/etc/ssl/grafana/ilnmors_root_ca.crt"
|
root_ca_cert = "/etc/ssl/grafana/{{ root_cert_filename }}"
|
||||||
# mTLS option, it is not needed
|
# mTLS option, it is not needed
|
||||||
# client_cert = "/path/to/client.crt"
|
# client_cert = "/path/to/client.crt"
|
||||||
# client_key = "/path/to/client.key"
|
# client_key = "/path/to/client.key"
|
||||||
|
|
||||||
bind_dn = "uid=grafana,ou=people,dc=ilnmors,dc=internal"
|
bind_dn = "uid=grafana,ou=people,{{ domain['dc'] }}"
|
||||||
bind_password = "$__file{/run/secrets/LDAP_BIND_PASSWORD}"
|
bind_password = "$__file{/run/secrets/LDAP_BIND_PASSWORD}"
|
||||||
|
|
||||||
search_filter = "(|(uid=%s)(mail=%s))"
|
search_filter = "(|(uid=%s)(mail=%s))"
|
||||||
search_base_dns = ["dc=ilnmors,dc=internal"]
|
search_base_dns = ["{{ domain['dc'] }}"]
|
||||||
|
|
||||||
[servers.attributes]
|
[servers.attributes]
|
||||||
member_of = "memberOf"
|
member_of = "memberOf"
|
||||||
@@ -28,20 +28,20 @@ surname = "sn"
|
|||||||
username = "uid"
|
username = "uid"
|
||||||
|
|
||||||
group_search_filter = "(&(objectClass=groupOfUniqueNames)(uniqueMember=%s))"
|
group_search_filter = "(&(objectClass=groupOfUniqueNames)(uniqueMember=%s))"
|
||||||
group_search_base_dns = ["ou=groups,dc=ilnmors,dc=internal"]
|
group_search_base_dns = ["ou=groups,{{ domain['dc'] }}"]
|
||||||
group_search_filter_user_attribute = "uid"
|
group_search_filter_user_attribute = "uid"
|
||||||
|
|
||||||
[[servers.group_mappings]]
|
[[servers.group_mappings]]
|
||||||
group_dn = "cn=lldap_admin,ou=groups,dc=ilnmors,dc=internal"
|
group_dn = "cn=lldap_admin,ou=groups,{{ domain['dc'] }}"
|
||||||
org_role = "Admin"
|
org_role = "Admin"
|
||||||
grafana_admin = true
|
grafana_admin = true
|
||||||
|
|
||||||
[[servers.group_mappings]]
|
[[servers.group_mappings]]
|
||||||
group_dn = "cn=admins,ou=groups,dc=ilnmors,dc=internal"
|
group_dn = "cn=admins,ou=groups,{{ domain['dc'] }}"
|
||||||
org_role = "Editor"
|
org_role = "Editor"
|
||||||
grafana_admin = false
|
grafana_admin = false
|
||||||
|
|
||||||
[[servers.group_mappings]]
|
[[servers.group_mappings]]
|
||||||
group_dn = "cn=users,ou=groups,dc=ilnmors,dc=internal"
|
group_dn = "cn=users,ou=groups,{{ domain['dc'] }}"
|
||||||
org_role = "Viewer"
|
org_role = "Viewer"
|
||||||
grafana_admin = false
|
grafana_admin = false
|
||||||
|
|||||||
+5
-5
@@ -4,7 +4,7 @@ apiVersion: 1
|
|||||||
datasources:
|
datasources:
|
||||||
- name: Prometheus
|
- name: Prometheus
|
||||||
type: prometheus
|
type: prometheus
|
||||||
url: https://prometheus.ilnmors.internal:9090
|
url: https://{{ services['prometheus']['domain'] }}.{{ domain['internal'] }}:{{ services['prometheus']['ports']['https'] }}
|
||||||
access: proxy
|
access: proxy
|
||||||
isDefault: true
|
isDefault: true
|
||||||
jsonData:
|
jsonData:
|
||||||
@@ -12,11 +12,11 @@ datasources:
|
|||||||
tlsAuthWithCACert: true
|
tlsAuthWithCACert: true
|
||||||
httpMethod: POST
|
httpMethod: POST
|
||||||
secureJsonData:
|
secureJsonData:
|
||||||
tlsCACert: "$__file{/etc/ssl/grafana/ilnmors_root_ca.crt}"
|
tlsCACert: "$__file{/etc/ssl/grafana/{{ root_cert_filename }}}"
|
||||||
|
|
||||||
- name: Loki
|
- name: Loki
|
||||||
type: loki
|
type: loki
|
||||||
url: https://loki.ilnmors.internal:3100
|
url: https://{{ services['loki']['domain'] }}.{{ domain['internal'] }}:{{ services['loki']['ports']['https'] }}
|
||||||
access: proxy
|
access: proxy
|
||||||
jsonData:
|
jsonData:
|
||||||
tlsAuth: false
|
tlsAuth: false
|
||||||
@@ -25,5 +25,5 @@ datasources:
|
|||||||
httpHeaderName1: "X-Scope-OrgID"
|
httpHeaderName1: "X-Scope-OrgID"
|
||||||
maxLines: 1000
|
maxLines: 1000
|
||||||
secureJsonData:
|
secureJsonData:
|
||||||
tlsCACert: "$__file{/etc/ssl/grafana/ilnmors_root_ca.crt}"
|
tlsCACert: "$__file{/etc/ssl/grafana/{{ root_cert_filename }}}"
|
||||||
httpHeaderValue1: "ilnmors.internal"
|
httpHeaderValue1: "{{ domain['internal'] }} "
|
||||||
@@ -13,12 +13,12 @@ Image=docker.io/grafana/grafana:{{ version['containers']['grafana'] }}
|
|||||||
ContainerName=grafana
|
ContainerName=grafana
|
||||||
HostName=grafana
|
HostName=grafana
|
||||||
|
|
||||||
AddHost={{ infra_uri['postgresql']['domain'] }}:host-gateway
|
AddHost={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
AddHost={{ infra_uri['ldap']['domain'] }}:host-gateway
|
AddHost={{ services['ldap']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
AddHost={{ infra_uri['prometheus']['domain'] }}:host-gateway
|
AddHost={{ services['prometheus']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
AddHost={{ infra_uri['loki']['domain'] }}:host-gateway
|
AddHost={{ services['loki']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
|
|
||||||
PublishPort=3000:3000/tcp
|
PublishPort={{ services['grafana']['ports']['http'] }}:3000/tcp
|
||||||
|
|
||||||
Volume=%h/containers/grafana/data:/var/lib/grafana:rw
|
Volume=%h/containers/grafana/data:/var/lib/grafana:rw
|
||||||
Volume=%h/containers/grafana/etc:/etc/grafana:ro
|
Volume=%h/containers/grafana/etc:/etc/grafana:ro
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ Image=docker.io/lldap/lldap:{{ version['containers']['ldap'] }}
|
|||||||
ContainerName=ldap
|
ContainerName=ldap
|
||||||
HostName=ldap
|
HostName=ldap
|
||||||
# They are at the same host (for Pasta, it is needed)
|
# They are at the same host (for Pasta, it is needed)
|
||||||
AddHost={{ infra_uri['postgresql']['domain'] }}:host-gateway
|
AddHost={{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:host-gateway
|
||||||
# For LDAPS - 636 > 6360 nftables
|
# For LDAPS - 636 > 6360 nftables
|
||||||
PublishPort=6360:6360/tcp
|
PublishPort={{ services['ldap']['ports']['ldaps'] }}:6360/tcp
|
||||||
# Web UI
|
# Web UI
|
||||||
PublishPort=17170:17170/tcp
|
PublishPort={{ services['ldap']['ports']['http'] }}:17170/tcp
|
||||||
|
|
||||||
|
|
||||||
Volume=%h/containers/ldap/data:/data:rw
|
Volume=%h/containers/ldap/data:/data:rw
|
||||||
@@ -27,7 +27,7 @@ Volume=%h/containers/ldap/ssl:/etc/ssl/ldap:ro
|
|||||||
Environment="TZ=Asia/Seoul"
|
Environment="TZ=Asia/Seoul"
|
||||||
|
|
||||||
# Domain
|
# Domain
|
||||||
Environment="LLDAP_LDAP_BASE_DN=dc=ilnmors,dc=internal"
|
Environment="LLDAP_LDAP_BASE_DN={{ domain['dc'] }}"
|
||||||
|
|
||||||
# LDAPS
|
# LDAPS
|
||||||
Environment="LLDAP_LDAPS_OPTIONS__ENABLED=true"
|
Environment="LLDAP_LDAPS_OPTIONS__ENABLED=true"
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
server:
|
server:
|
||||||
http_listen_address: "::"
|
http_listen_address: "::"
|
||||||
http_listen_port: 3100
|
http_listen_port: {{ services['loki']['ports']['https'] }}
|
||||||
http_tls_config:
|
http_tls_config:
|
||||||
cert_file: /etc/ssl/loki/loki.crt
|
cert_file: /etc/ssl/loki/loki.crt
|
||||||
key_file: /etc/ssl/loki/loki.key
|
key_file: /etc/ssl/loki/loki.key
|
||||||
@@ -13,7 +13,7 @@ Image=docker.io/grafana/loki:{{ version['containers']['loki'] }}
|
|||||||
ContainerName=loki
|
ContainerName=loki
|
||||||
HostName=loki
|
HostName=loki
|
||||||
|
|
||||||
PublishPort=3100:3100/tcp
|
PublishPort={{ services['loki']['ports']['https'] }}:3100/tcp
|
||||||
|
|
||||||
Volume=%h/containers/loki/data:/loki:rw
|
Volume=%h/containers/loki/data:/loki:rw
|
||||||
Volume=%h/containers/loki/etc:/etc/loki:ro
|
Volume=%h/containers/loki/etc:/etc/loki:ro
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ listen_addresses = '*'
|
|||||||
# Max connections
|
# Max connections
|
||||||
max_connections = 250
|
max_connections = 250
|
||||||
# listen_port
|
# listen_port
|
||||||
port = 5432
|
port = {{ services['postgresql']['ports']['tcp'] }}
|
||||||
|
|
||||||
# SSL
|
# SSL
|
||||||
ssl = on
|
ssl = on
|
||||||
ssl_ca_file = '/etc/ssl/postgresql/ilnmors_root_ca.crt'
|
ssl_ca_file = '/etc/ssl/postgresql/{{ root_cert_filename }}'
|
||||||
ssl_cert_file = '/etc/ssl/postgresql/postgresql.crt'
|
ssl_cert_file = '/etc/ssl/postgresql/postgresql.crt'
|
||||||
ssl_key_file = '/etc/ssl/postgresql/postgresql.key'
|
ssl_key_file = '/etc/ssl/postgresql/postgresql.key'
|
||||||
ssl_ciphers = 'HIGH:!aNULL:!MD5'
|
ssl_ciphers = 'HIGH:!aNULL:!MD5'
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ After=network-online.target
|
|||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
|
|
||||||
[Container]
|
[Container]
|
||||||
Image=ilnmors.internal/{{ node['name'] }}/postgres:pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}
|
Image={{ domain['internal'] }}/{{ node['name'] }}/postgres:pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}
|
||||||
|
|
||||||
ContainerName=postgresql
|
ContainerName=postgresql
|
||||||
HostName=postgresql
|
HostName=postgresql
|
||||||
|
|
||||||
PublishPort=5432:5432/tcp
|
PublishPort={{ services['postgresql']['ports']['tcp'] }}:5432/tcp
|
||||||
|
|
||||||
Volume=%h/containers/postgresql/data:/var/lib/postgresql:rw
|
Volume=%h/containers/postgresql/data:/var/lib/postgresql:rw
|
||||||
Volume=%h/containers/postgresql/config:/config:ro
|
Volume=%h/containers/postgresql/config:/config:ro
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ scrape_configs:
|
|||||||
# metrics_path defaults to '/metrics'
|
# metrics_path defaults to '/metrics'
|
||||||
scheme: "https"
|
scheme: "https"
|
||||||
tls_config:
|
tls_config:
|
||||||
ca_file: "/etc/ssl/prometheus/ilnmors_root_ca.crt"
|
ca_file: "/etc/ssl/prometheus/{{ root_cert_filename }}"
|
||||||
server_name: "{{ infra_uri['prometheus']['domain'] }}"
|
server_name: "{{ services['prometheus']['domain'] }}.{{ domain['internal'] }}"
|
||||||
static_configs:
|
static_configs:
|
||||||
- targets: ["localhost:9090"]
|
- targets: ["localhost:9090"]
|
||||||
# The label name is added as a label `label_name=<label_value>` to any timeseries scraped from this config.
|
# The label name is added as a label `label_name=<label_value>` to any timeseries scraped from this config.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Image=docker.io/prom/prometheus:{{ version['containers']['prometheus'] }}
|
|||||||
ContainerName=prometheus
|
ContainerName=prometheus
|
||||||
HostName=prometheus
|
HostName=prometheus
|
||||||
|
|
||||||
PublishPort=9090:9090/tcp
|
PublishPort={{ services['prometheus']['ports']['https'] }}:9090/tcp
|
||||||
|
|
||||||
Volume=%h/containers/prometheus/data:/prometheus:rw
|
Volume=%h/containers/prometheus/data:/prometheus:rw
|
||||||
Volume=%h/containers/prometheus/etc:/etc/prometheus:ro
|
Volume=%h/containers/prometheus/etc:/etc/prometheus:ro
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
server:
|
||||||
|
listen: :9793
|
||||||
|
|
||||||
|
sources:
|
||||||
|
- kind: file
|
||||||
|
name: homelab-certs
|
||||||
|
paths:
|
||||||
|
- /certs/*.crt
|
||||||
|
- /certs/*.pem
|
||||||
|
- /certs/*.cer
|
||||||
|
refreshInterval: 1m
|
||||||
@@ -11,11 +11,12 @@ Image=docker.io/enix/x509-certificate-exporter:{{ version['containers']['x509-ex
|
|||||||
ContainerName=x509-exporter
|
ContainerName=x509-exporter
|
||||||
HostName=X509-exporter
|
HostName=X509-exporter
|
||||||
|
|
||||||
|
Volume=%h/containers/x509-exporter/config/config.yaml:/etc/config.yaml:ro
|
||||||
Volume=%h/containers/x509-exporter/certs:/certs:ro
|
Volume=%h/containers/x509-exporter/certs:/certs:ro
|
||||||
|
|
||||||
PublishPort=9793:9793
|
PublishPort={{ services['x509-exporter']['ports']['http'] }}:9793
|
||||||
|
|
||||||
Exec=--listen-address :9793 --watch-dir=/certs
|
Exec=--config /etc/config.yaml
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=BTRFS auto scrub
|
||||||
|
ConditionPathIsMountPoint={{ storage['btrfs']['mount_point'] }}
|
||||||
|
RequiresMountsFor={{ storage['btrfs']['mount_point'] }}
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/btrfs scrub start -Bd {{ storage['btrfs']['mount_point'] }}
|
||||||
|
Nice=19
|
||||||
|
IOSchedulingClass=idle
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Monthly BTRFS auto scrub
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-01 04:00:00
|
||||||
|
Persistent=true
|
||||||
|
RandomizedDelaySec=300
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
//// Metric ouput
|
//// Metric ouput
|
||||||
prometheus.remote_write "prometheus" {
|
prometheus.remote_write "prometheus" {
|
||||||
endpoint {
|
endpoint {
|
||||||
url = "https://{{ infra_uri['prometheus']['domain'] }}:{{ infra_uri['prometheus']['ports']['https'] }}/api/v1/write"
|
url = "https://{{ services['prometheus']['domain'] }}.{{ domain['internal'] }}:{{ services['prometheus']['ports']['https'] }}/api/v1/write"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,8 +71,8 @@ prometheus.scrape "system" {
|
|||||||
////// For Crowdsec metrics
|
////// For Crowdsec metrics
|
||||||
prometheus.scrape "crowdsec" {
|
prometheus.scrape "crowdsec" {
|
||||||
targets = [
|
targets = [
|
||||||
{ "__address__" = "{{ infra_uri['crowdsec']['domain'] }}:6060", "job" = "crowdsec" },
|
{ "__address__" = "{{ services['crowdsec']['domain'] }}.{{ domain['internal'] }}:6060", "job" = "crowdsec" },
|
||||||
{ "__address__" = "{{ infra_uri['crowdsec']['domain'] }}:60601", "job" = "crowdsec-bouncer" },
|
{ "__address__" = "{{ services['crowdsec']['domain'] }}.{{ domain['internal'] }}:60601", "job" = "crowdsec-bouncer" },
|
||||||
]
|
]
|
||||||
honor_labels = true
|
honor_labels = true
|
||||||
forward_to = [prometheus.relabel.default_label.receiver]
|
forward_to = [prometheus.relabel.default_label.receiver]
|
||||||
@@ -83,7 +83,7 @@ prometheus.scrape "crowdsec" {
|
|||||||
////// For postgresql metrics
|
////// For postgresql metrics
|
||||||
prometheus.exporter.postgres "postgresql" {
|
prometheus.exporter.postgres "postgresql" {
|
||||||
data_source_names = [
|
data_source_names = [
|
||||||
"postgres://alloy@{{ infra_uri['postgresql']['domain'] }}:{{ infra_uri['postgresql']['ports']['tcp'] }}/postgres?sslmode=verify-full",
|
"postgres://alloy@{{ services['postgresql']['domain'] }}.{{ domain['internal'] }}:{{ services['postgresql']['ports']['tcp'] }}/postgres?sslmode=verify-full",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
prometheus.scrape "postgresql" {
|
prometheus.scrape "postgresql" {
|
||||||
@@ -93,7 +93,7 @@ prometheus.scrape "postgresql" {
|
|||||||
///// For certificates metrics
|
///// For certificates metrics
|
||||||
prometheus.scrape "x509" {
|
prometheus.scrape "x509" {
|
||||||
targets = [
|
targets = [
|
||||||
{ "__address__" = "{{ node['name'] }}.ilnmors.internal:9793" },
|
{ "__address__" = "{{ node['name'] }}.{{ domain['internal'] }}:{{ services['x509-exporter']['ports']['http'] }}" },
|
||||||
]
|
]
|
||||||
forward_to = [prometheus.relabel.default_label.receiver]
|
forward_to = [prometheus.relabel.default_label.receiver]
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ prometheus.scrape "x509" {
|
|||||||
////// For Input Caddy metrics
|
////// For Input Caddy metrics
|
||||||
prometheus.scrape "caddy" {
|
prometheus.scrape "caddy" {
|
||||||
targets = [
|
targets = [
|
||||||
{ "__address__" = "{{ node['name'] }}.ilnmors.internal:443" },
|
{ "__address__" = "{{ node['name'] }}.{{ domain['internal'] }}:443" },
|
||||||
]
|
]
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
forward_to = [prometheus.relabel.default_label.receiver]
|
forward_to = [prometheus.relabel.default_label.receiver]
|
||||||
@@ -114,8 +114,8 @@ prometheus.scrape "caddy" {
|
|||||||
//// Logs output
|
//// Logs output
|
||||||
loki.write "loki" {
|
loki.write "loki" {
|
||||||
endpoint {
|
endpoint {
|
||||||
url = "https://{{ infra_uri['loki']['domain'] }}:{{ infra_uri['loki']['ports']['https'] }}/loki/api/v1/push"
|
url = "https://{{ services['loki']['domain'] }}.{{ domain['internal'] }}:{{ services['loki']['ports']['https'] }}/loki/api/v1/push"
|
||||||
tenant_id = "ilnmors.internal"
|
tenant_id = "{{ domain['internal'] }}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//// Logs relabel
|
//// Logs relabel
|
||||||
@@ -203,12 +203,11 @@ loki.relabel "caddy_relabel" {
|
|||||||
loki.process "journal_parser" {
|
loki.process "journal_parser" {
|
||||||
forward_to = [loki.write.loki.receiver]
|
forward_to = [loki.write.loki.receiver]
|
||||||
// Severity parsing
|
// Severity parsing
|
||||||
// If content of log includes "level" information, change the level
|
stage.regex {
|
||||||
stage.logfmt {
|
// Regex to extract the log level from the content.
|
||||||
mapping = {
|
expression = "(?i)(?:level[\"\\s:=]+|\\[|\\s|^)(?P<content_level>info|warn|warning|error|debug|fatal|critical|trace)(?:[\"\\]\\s]|$)"
|
||||||
"content_level" = "level",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stage.labels {
|
stage.labels {
|
||||||
values = {
|
values = {
|
||||||
"level" = "content_level",
|
"level" = "content_level",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ log_compression: true
|
|||||||
log_max_size: 100
|
log_max_size: 100
|
||||||
log_max_backups: 3
|
log_max_backups: 3
|
||||||
log_max_age: 30
|
log_max_age: 30
|
||||||
api_url: "https://{{ infra_uri['crowdsec']['domain'] }}:{{ infra_uri['crowdsec']['ports']['https'] }}"
|
api_url: "https://{{ services['crowdsec']['domain'] }}.{{ domain['internal'] }}:{{ services['crowdsec']['ports']['https'] }}"
|
||||||
api_key: "{{ hostvars['console']['crowdsec']['bouncer']['fw'] }}"
|
api_key: "{{ hostvars['console']['crowdsec']['bouncer']['fw'] }}"
|
||||||
insecure_skip_verify: false
|
insecure_skip_verify: false
|
||||||
disable_ipv6: false
|
disable_ipv6: false
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
name: crowdsecurity/whitelists
|
name: crowdsecurity/whitelists
|
||||||
description: "Whitelist console/admin hosts only"
|
description: "Local whitelist policy"
|
||||||
whitelist:
|
whitelist:
|
||||||
reason: "trusted admin hosts"
|
reason: "rules"
|
||||||
ip:
|
ip:
|
||||||
|
# Console IP lists
|
||||||
- "127.0.0.1"
|
- "127.0.0.1"
|
||||||
- "::1"
|
- "::1"
|
||||||
- "{{ hostvars['fw']['network4']['console']['client'] }}"
|
- "{{ hostvars['fw']['network4']['console']['client'] }}"
|
||||||
- "{{ hostvars['fw']['network4']['console']['wg'] }}"
|
- "{{ hostvars['fw']['network4']['console']['wg'] }}"
|
||||||
- "{{ hostvars['fw']['network6']['console']['client'] }}"
|
- "{{ hostvars['fw']['network6']['console']['client'] }}"
|
||||||
- "{{ hostvars['fw']['network6']['console']['wg'] }}"
|
- "{{ hostvars['fw']['network6']['console']['wg'] }}"
|
||||||
|
{% if node['name'] == 'auth' %}
|
||||||
|
expression:
|
||||||
|
# immich thumbnail request 404 error false positive
|
||||||
|
- "evt.Meta.target_fqdn == '{{ services['immich']['domain']['public'] }}.{{ domain['public'] }}' && evt.Meta.http_status == '404' && evt.Meta.http_verb == 'GET' && evt.Meta.http_path contains '/api/assets/' && evt.Meta.http_path contains '/thumbnail'"
|
||||||
|
# nextcloud thumbnail/preview request error false positive
|
||||||
|
- "evt.Meta.target_fqdn == '{{ services['nextcloud']['domain']['public'] }}.{{ domain['public'] }}' && evt.Meta.http_status == '404' && evt.Meta.http_verb == 'GET' && evt.Meta.http_path startsWith '/index.php/core/preview?'"
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
url: https://{{ infra_uri['crowdsec']['domain'] }}:{{ infra_uri['crowdsec']['ports']['https'] }}
|
url: https://{{ services['crowdsec']['domain'] }}.{{ domain['internal'] }}:{{ services['crowdsec']['ports']['https'] }}
|
||||||
login: {{ node['name'] }}
|
login: {{ node['name'] }}
|
||||||
password: {{ hostvars['console']['crowdsec']['machine'][node['name']] }}
|
password: {{ hostvars['console']['crowdsec']['machine'][node['name']] }}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ ProtectHome=tmpfs
|
|||||||
InaccessiblePaths=/boot /root
|
InaccessiblePaths=/boot /root
|
||||||
|
|
||||||
{% if node['name'] == 'infra' %}
|
{% if node['name'] == 'infra' %}
|
||||||
BindReadOnlyPaths=/home/infra/containers/postgresql/backups
|
BindReadOnlyPaths={{ node['home_path'] }}/containers/postgresql/backups
|
||||||
{% elif node['name'] == 'app' %}
|
{% elif node['name'] == 'app' %}
|
||||||
BindReadOnlyPaths=/home/app/data
|
BindReadOnlyPaths={{ node['home_path'] }}/data
|
||||||
{% endif %}
|
{% endif %}
|
||||||
# In root namescope, %u always bring 0
|
# In root namescope, %u always bring 0
|
||||||
BindPaths=/etc/kopia
|
BindPaths=/etc/kopia
|
||||||
@@ -32,16 +32,16 @@ BindPaths=/var/cache/kopia
|
|||||||
EnvironmentFile=/etc/secrets/{{ kopia_uid }}/kopia.env
|
EnvironmentFile=/etc/secrets/{{ kopia_uid }}/kopia.env
|
||||||
|
|
||||||
ExecStartPre=/usr/bin/kopia repository connect server \
|
ExecStartPre=/usr/bin/kopia repository connect server \
|
||||||
--url=https://{{ infra_uri['kopia']['domain'] }}:{{ infra_uri['kopia']['ports']['https'] }} \
|
--url=https://{{ services['kopia']['domain'] }}.{{ domain['internal'] }}:{{ services['kopia']['ports']['https'] }} \
|
||||||
--override-username={{ node['name'] }} \
|
--override-username={{ node['name'] }} \
|
||||||
--override-hostname={{ node['name'] }}.ilnmors.internal
|
--override-hostname={{ node['name'] }}.{{ domain['internal'] }}
|
||||||
|
|
||||||
{% if node['name'] == 'infra' %}
|
{% if node['name'] == 'infra' %}
|
||||||
ExecStart=/usr/bin/kopia snapshot create \
|
ExecStart=/usr/bin/kopia snapshot create \
|
||||||
/home/infra/containers/postgresql/backups
|
{{ node['home_path'] }}/containers/postgresql/backups
|
||||||
{% elif node['name'] == 'app' %}
|
{% elif node['name'] == 'app' %}
|
||||||
ExecStart=/usr/bin/kopia snapshot create \
|
ExecStart=/usr/bin/kopia snapshot create \
|
||||||
/home/app/data
|
{{ node['home_path'] }}/data
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -12,4 +12,4 @@ StandardError=journal
|
|||||||
EnvironmentFile=/etc/secrets/%U/ddns.env
|
EnvironmentFile=/etc/secrets/%U/ddns.env
|
||||||
|
|
||||||
# Run the script
|
# Run the script
|
||||||
ExecStart=/usr/local/bin/ddns.sh -d "ilnmors.com"
|
ExecStart=/usr/local/bin/ddns.sh -d "{{ domain['public'] }}"
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "domain-name",
|
"name": "domain-name",
|
||||||
"data": "ilnmors.internal."
|
"data": "{{ domain['internal'] }}."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"reservations": [
|
"reservations": [
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "domain-name",
|
"name": "domain-name",
|
||||||
"data": "ilnmors.internal."
|
"data": "{{ domain['internal'] }}."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"id": 2,
|
"id": 2,
|
||||||
|
|||||||
Regular → Executable
@@ -14,22 +14,22 @@
|
|||||||
## Context
|
## Context
|
||||||
|
|
||||||
- Maintaining multi nodes requires a huge amount of resources, including hardware, electricity, even administrative efforts
|
- Maintaining multi nodes requires a huge amount of resources, including hardware, electricity, even administrative efforts
|
||||||
- All units which responsible for a single role should follow the Principle of Least Privilege \(PoLP\).
|
- All units which responsible for a single role should follow the Principle of Least Privilege (PoLP).
|
||||||
- All units should be interchangeable on standard to avoid vendor lock-in.
|
- All units should be interchangeable on standard to avoid vendor lock-in.
|
||||||
|
|
||||||
## Consideration
|
## Consideration
|
||||||
|
|
||||||
### Hypervisor
|
### Hypervisor
|
||||||
|
|
||||||
- Proxmox Virutal Environment \(PVE\)
|
- Proxmox Virutal Environment (PVE)
|
||||||
- Based on Debian.
|
- Based on Debian.
|
||||||
- PVE uses `qm` command which is not a standard to implement the virtual environment.
|
- PVE uses `qm` command which is not a standard to implement the virtual environment.
|
||||||
- VMware ESXi
|
- VMware ESXi
|
||||||
- Based on UNIX, deveoped by VMware \(Licence is not free\)
|
- Based on UNIX, deveoped by VMware (Licence is not free)
|
||||||
- Hyper-V
|
- Hyper-V
|
||||||
- Based on Microsoft Windows \(Licence is not free\)
|
- Based on Microsoft Windows (Licence is not free)
|
||||||
- Debian Stable
|
- Debian Stable
|
||||||
- Based on standard linux \(conservative\)
|
- Based on standard linux (conservative)
|
||||||
- Standard virtualization technology 'Libvirt, QEMU, KVM'
|
- Standard virtualization technology 'Libvirt, QEMU, KVM'
|
||||||
|
|
||||||
### Container
|
### Container
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
- Docker
|
- Docker
|
||||||
- Daemon is used to run containers
|
- Daemon is used to run containers
|
||||||
- Root authority required
|
- Root authority required
|
||||||
- Socket and network problem is complex \(Docker bridge\)
|
- Socket and network problem is complex (Docker bridge)
|
||||||
- docker-compose is an orchestration tool
|
- docker-compose is an orchestration tool
|
||||||
- Rootless Podman
|
- Rootless Podman
|
||||||
- Daemonless design
|
- Daemonless design
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
## Decisions
|
## Decisions
|
||||||
|
|
||||||
- Use Libvirt/KVM/QEMU on pure linux \(Debian stable\).
|
- Use Libvirt/KVM/QEMU on pure linux (Debian stable).
|
||||||
- Separate all services by VM, and podman rootless containers without K3S.
|
- Separate all services by VM, and podman rootless containers without K3S.
|
||||||
- Orchestration stack is not needed in single node system
|
- Orchestration stack is not needed in single node system
|
||||||
- Services will be defined by Quadelt to integrate into systemd and to manage them declaratively
|
- Services will be defined by Quadelt to integrate into systemd and to manage them declaratively
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user