Compare commits

..

1 Commits

Author SHA1 Message Date
renovate[bot] 4d62efb6a2 Add renovate.json 2025-09-25 20:42:40 +00:00
176 changed files with 1009 additions and 4772 deletions
+7 -18
View File
@@ -5,17 +5,18 @@ updates:
schedule: schedule:
interval: weekly interval: weekly
directories: directories:
- "/docker/gitea-actions"
- "/docker/home/esphome" - "/docker/home/esphome"
- "/docker/home/ha-linky"
- "/docker/home/home-assistant"
- "/docker/home/matter-server" - "/docker/home/matter-server"
- "/docker/home/mosquitto-mqtt" - "/docker/home/mosquitto-mqtt"
- "/docker/home/n8n"
- "/docker/home/node-red" - "/docker/home/node-red"
- "/docker/home/zigbee2mqtt" - "/docker/home/zigbee2mqtt"
- "/docker/infrastructure/mail/roundcube" - "/docker/infrastructure/mail/roundcube"
- "/docker/infrastructure/mail/stalwart"
- "/docker/infrastructure/network/traefik" - "/docker/infrastructure/network/traefik"
- "/docker/infrastructure/squid"
- "/docker/infrastructure/sshportal" - "/docker/infrastructure/sshportal"
- "/docker/personal/fireshare"
- "/docker/personal/gramps" - "/docker/personal/gramps"
- "/docker/personal/media/films-series/jackett" - "/docker/personal/media/films-series/jackett"
- "/docker/personal/media/films-series/jellyfin" - "/docker/personal/media/films-series/jellyfin"
@@ -31,10 +32,11 @@ updates:
- "/docker/personal/syncthing" - "/docker/personal/syncthing"
- "/docker/personal/tandoor" - "/docker/personal/tandoor"
- "/docker/production/alexscript" - "/docker/production/alexscript"
- "/docker/production/buildpath"
- "/docker/production/semeryfr" - "/docker/production/semeryfr"
- "/docker/production/vhaudiquetfr"
- "/docker/tools/excalidraw" - "/docker/tools/excalidraw"
- "/docker/tools/obsidian-livesync" - "/docker/tools/hedgedoc"
- "/docker/tools/notesnook"
- "/docker/tools/stirling-pdf" - "/docker/tools/stirling-pdf"
- package-ecosystem: "helm" - package-ecosystem: "helm"
open-pull-requests-limit: 15 open-pull-requests-limit: 15
@@ -43,23 +45,10 @@ updates:
directories: directories:
- "/kubernetes/code/gitea" - "/kubernetes/code/gitea"
- "/kubernetes/code/harbor" - "/kubernetes/code/harbor"
- "/kubernetes/home/home-assistant"
- "/kubernetes/home/zigbee2mqtt"
- "/kubernetes/infrastructure/authentik" - "/kubernetes/infrastructure/authentik"
- "/kubernetes/infrastructure/mail/stalwart"
- "/kubernetes/personal/linkwarden" - "/kubernetes/personal/linkwarden"
- "/kubernetes/personal/notesnook"
- "/kubernetes/personal/photoprism" - "/kubernetes/personal/photoprism"
- "/kubernetes/production/umami"
- "/kubernetes/production/vhaudiquet-fr"
- "/kubernetes/system/blocky"
- "/kubernetes/system/caddy"
- "/kubernetes/system/cert-manager"
- "/kubernetes/system/cert-manager-webhook-ovh"
- "/kubernetes/system/coredns"
- "/kubernetes/system/csi-driver-nfs" - "/kubernetes/system/csi-driver-nfs"
- "/kubernetes/system/external-dns" - "/kubernetes/system/external-dns"
- "/kubernetes/system/longhorn"
- "/kubernetes/system/traefik" - "/kubernetes/system/traefik"
- "/kubernetes/tools/dashy"
- "/kubernetes/tools/glance" - "/kubernetes/tools/glance"
-21
View File
@@ -1,21 +0,0 @@
name: DNS
on:
push:
branches: [main]
defaults:
run:
working-directory: ./dns
jobs:
update-records:
name: octodns
runs-on: ubuntu-latest
container: octodns/cloudflare:latest
steps:
- uses: actions/checkout@v4
- name: octodns-sync - production
run: octodns-sync --config-file ./config/production.yaml --doit
env:
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
-3
View File
@@ -9,6 +9,3 @@ terraform.tfstate.backup
kubeconfig kubeconfig
talosconfig talosconfig
# Ignore rendered Talos machine configs (may contain cluster secrets)
p330.yaml
-5
View File
@@ -16,8 +16,3 @@ repos:
entry: generate-docker-swarmcd.sh entry: generate-docker-swarmcd.sh
language: script language: script
pass_filenames: false pass_filenames: false
- id: validate-kustomize
name: validate kustomize build
entry: bash -c 'kubectl kustomize kubernetes/ > /dev/null'
language: system
pass_filenames: false
+1 -1
View File
@@ -3,7 +3,7 @@ creation_rules:
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$ encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
pgp: DC6910268E657FF70BA7EC289974494E76938DDC pgp: DC6910268E657FF70BA7EC289974494E76938DDC
- path_regex: .*.yaml - path_regex: .*.yaml
encrypted_regex: ^(data|stringData|.*.key|.*.crt)$ encrypted_regex: ^(data|stringData)$
pgp: DC6910268E657FF70BA7EC289974494E76938DDC pgp: DC6910268E657FF70BA7EC289974494E76938DDC
- path_regex: .*.env$ - path_regex: .*.env$
input_type: dotenv input_type: dotenv
+39 -27
View File
@@ -1,8 +1,27 @@
gitea-actions:
repo: homeprod
branch: main
compose_file: docker/gitea-actions/docker-compose.yml
sops_files:
- docker/gitea-actions/.env
esphome: esphome:
repo: homeprod repo: homeprod
branch: main branch: main
compose_file: docker/home/esphome/docker-compose.yml compose_file: docker/home/esphome/docker-compose.yml
ha-linky:
repo: homeprod
branch: main
compose_file: docker/home/ha-linky/docker-compose.yml
sops_files:
- docker/home/ha-linky/.env
home-assistant:
repo: homeprod
branch: main
compose_file: docker/home/home-assistant/docker-compose.yml
matter-server: matter-server:
repo: homeprod repo: homeprod
branch: main branch: main
@@ -13,11 +32,6 @@ mosquitto-mqtt:
branch: main branch: main
compose_file: docker/home/mosquitto-mqtt/docker-compose.yml compose_file: docker/home/mosquitto-mqtt/docker-compose.yml
n8n:
repo: homeprod
branch: main
compose_file: docker/home/n8n/docker-compose.yml
node-red: node-red:
repo: homeprod repo: homeprod
branch: main branch: main
@@ -33,28 +47,21 @@ roundcube:
branch: main branch: main
compose_file: docker/infrastructure/mail/roundcube/docker-compose.yml compose_file: docker/infrastructure/mail/roundcube/docker-compose.yml
stalwart:
repo: homeprod
branch: main
compose_file: docker/infrastructure/mail/stalwart/docker-compose.yml
traefik: traefik:
repo: homeprod repo: homeprod
branch: main branch: main
compose_file: docker/infrastructure/network/traefik/docker-compose.yml compose_file: docker/infrastructure/network/traefik/docker-compose.yml
squid:
repo: homeprod
branch: main
compose_file: docker/infrastructure/squid/docker-compose.yml
sshportal: sshportal:
repo: homeprod repo: homeprod
branch: main branch: main
compose_file: docker/infrastructure/sshportal/docker-compose.yml compose_file: docker/infrastructure/sshportal/docker-compose.yml
fireshare:
repo: homeprod
branch: main
compose_file: docker/personal/fireshare/docker-compose.yml
sops_files:
- docker/personal/fireshare/.env
gramps: gramps:
repo: homeprod repo: homeprod
branch: main branch: main
@@ -136,29 +143,34 @@ alexscript:
branch: main branch: main
compose_file: docker/production/alexscript/docker-compose.yml compose_file: docker/production/alexscript/docker-compose.yml
buildpath:
repo: homeprod
branch: main
compose_file: docker/production/buildpath/docker-compose.yml
sops_files:
- docker/production/buildpath/.env
semeryfr: semeryfr:
repo: homeprod repo: homeprod
branch: main branch: main
compose_file: docker/production/semeryfr/docker-compose.yml compose_file: docker/production/semeryfr/docker-compose.yml
vhaudiquetfr:
repo: homeprod
branch: main
compose_file: docker/production/vhaudiquetfr/docker-compose.yml
excalidraw: excalidraw:
repo: homeprod repo: homeprod
branch: main branch: main
compose_file: docker/tools/excalidraw/docker-compose.yml compose_file: docker/tools/excalidraw/docker-compose.yml
obsidian-livesync: hedgedoc:
repo: homeprod repo: homeprod
branch: main branch: main
compose_file: docker/tools/obsidian-livesync/docker-compose.yml compose_file: docker/tools/hedgedoc/docker-compose.yml
sops_files: sops_files:
- docker/tools/obsidian-livesync/.env - docker/tools/hedgedoc/.env
notesnook:
repo: homeprod
branch: main
compose_file: docker/tools/notesnook/docker-compose.yml
sops_files:
- docker/tools/notesnook/.env
stirling-pdf: stirling-pdf:
repo: homeprod repo: homeprod
+9 -19
View File
@@ -7,17 +7,17 @@ Personal home production environment mono-repo
### Hardware and operating systems ### Hardware and operating systems
#### Dell R740 <img align="left" width="100" src="https://vhaudiquet.fr/public/github_assets/homeprod/p330_sff.png"/>
#### Lenovo ThinkStation P330 SFF
Specifications : Specifications :
``` ```
2* Intel Xeon Gold 6138 @ 2GHz (20 cores, 40 threads) Intel Xeon E-2134 @ 3.50GHz (4 cores, 8 threads)
144 GiB DDR4 ECC RAM 64 GiB DDR4 ECC RAM
2* 2 TiB SAS SSD (mirror) 1 TiB nVME SSD
10Gbps 4* RJ45 network card Intel X520-DA2 SFP+ 10Gbps network card
H730P, 16* SFF 2.5 drive bays nVIDIA Quadro P620 graphics card
SAS9300-8E external SAS card
NVIDIA RTX 3060 12G graphics card
``` ```
Running as single-node Proxmox Running as single-node Proxmox
@@ -61,7 +61,7 @@ This setup allows running multiple applications, either self-hosted applications
| Icon | Software | Description | | Icon | Software | Description |
|------|--------------|-------------| |------|--------------|-------------|
| <img width=30 src="https://buildpath.win/_ipx/w_60&f_webp/buildpath-high-resolution-logo-transparent.png"> | BuildPath | https://buildpath.win, website for League of Legends champion builds | | <img width=30 src="https://buildpath.win/_ipx/w_60&f_webp/buildpath-high-resolution-logo-transparent.png"> | BuildPath | https://buildpath.win, website for League of Legends champion builds |
| <img width=32 src="https://vhaudiquet.fr/favicon.ico_256x256.png"> | vhaudiquet.fr | https://vhaudiquet.fr, personal website | | <img width=32 src="https://vhaudiquet.fr/assets/favicon.ico_256x256.png"> | vhaudiquet.fr | https://vhaudiquet.fr, personal website |
#### Personal applications #### Personal applications
@@ -80,13 +80,3 @@ This setup allows running multiple applications, either self-hosted applications
| <img width=32 src="https://avatars.githubusercontent.com/u/26692192"> | Navidrome | Personal music streaming service | | <img width=32 src="https://avatars.githubusercontent.com/u/26692192"> | Navidrome | Personal music streaming service |
| <img width=32 src="https://avatars.githubusercontent.com/u/102734415"> | TubeArchivist | YouTube archiver | | <img width=32 src="https://avatars.githubusercontent.com/u/102734415"> | TubeArchivist | YouTube archiver |
| <img width=24 src="https://radicale.org/assets/logo.svg"> | Radicale | Calendar and contacts server | | <img width=24 src="https://radicale.org/assets/logo.svg"> | Radicale | Calendar and contacts server |
## Docs (internal, using this repository)
This repository uses pre-commit hooks to automate tasks like file encryption and configuration generation.
After cloning, install the pre-commit hooks:
```bash
pre-commit install
```
-16
View File
@@ -1,16 +0,0 @@
providers:
config:
class: octodns.provider.yaml.YamlProvider
directory: ./production
default_ttl: 3600
enforce_order: True
cloudflare:
class: octodns_cloudflare.CloudflareProvider
token: env/CLOUDFLARE_TOKEN
zones:
'*':
sources:
- config
targets:
- cloudflare
-28
View File
@@ -1,28 +0,0 @@
---
? ''
: - octodns:
cloudflare:
auto-ttl: true
proxied: false
ttl: 300
type: A
value: 83.113.30.49
- type: TXT
value: google-site-verification=BvFkK7orKeezgxGcdPiGa67PUm9RPI6ZjyyykhSJ24A
_acme-challenge:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
values:
- 15ks77ymwx2rPrwai5lV0KbySgDrN6AwDqt8e3LNc3Y
- ypJ7zk6-P0TPrdp4Ag2BTJ0NIaY9XNdndqlGOLaFACc
www:
octodns:
cloudflare:
auto-ttl: true
proxied: false
ttl: 300
type: A
value: 83.113.30.49
-442
View File
@@ -1,442 +0,0 @@
---
? ''
: - octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
- octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: MX
values:
- exchange: mail.vhaudiquet.fr.
preference: 10
- exchange: vhaudiquet.fr.
preference: 10
- octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
values:
- v=spf1 a ra=postmaster -all
- v=spf1 mx ra=postmaster -all
202412e._domainkey:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
values:
- v=DKIM1\; k=ed25519\; h=sha256\; p=jln+6mPae83WbgR5FHA1yw0exmcGVmkEwNx1ZpISv7k=
- v=DKIM1\; k=ed25519\; h=sha256\; p=zue5tDdPhC91KvjPj28r1F3RoQNiQamYahX371tPmd8=
202412r._domainkey:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
values:
- v=DKIM1\; k=rsa\; h=sha256\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Pzzsp4MALfuXDoYsmXotp5mCidcKsDeWycjCMyhGvBDjfaX8l0ZCPemPOjD+uMPhbZV7e1RkzIt6A0qmutDixT1Dup3uhYhnyblp4Gkx1e85vaIncE1V2paJ85EOsDH/4rcGtdcPQfANbPw9LlqcdU3S+X9KpYaMf2DqPPfYa7emhJxBklUMymY06lssqb7+3ltLujGH8J+qNIYJmPa0s1tf2Pu1/opBKkk1qeUyF/wLmW0UTwNB3UyRCSMwR4DzburfHfE9cSNcm/STzrWcPmDnro2E3S69pTmzECU0g2xRqBBq3eYfQO8KxtGGQy63KUqAAhN5D8n9BZ4+TbD5QIDAQAB
- v=DKIM1\; k=rsa\; h=sha256\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs7vM7V1LhJJ6NRazIFyZ5bGseKOABnwBwzNspD+hdeVa7bbE38L+xfbhKKopXwQCCV8lJ+BgDpLJQvTYgRR+6UjuYm7/b/BX8qewPZUGphamkNRExBalsMAxAf9zeMqPUfpjDEKggten90RdrklQCnn5ebyUcTFk+uKfImqn3S2L34vSHfuCtsaZExu8mCych2Q3ZBdx3gsAtmMsmqrAJqBOlF/d/1xVloNMMWBIUNY9NYdC+ZspTvoakIrTOIzHCfoiG3lzpWLM8Du7GWd2umpXOsM4RpJL1vTRDOWjnd25N63L3GlCnAfr8Yu2K77A2PvloOIwZXYrLFOB5S7jxwIDAQAB
202508e._domainkey:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=DKIM1\; k=ed25519\; h=sha256\; p=B25PCl1mN4ajiGlVW/CZnWlZzfUxKaB8EhIal4bAHEo=
202508r._domainkey:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=DKIM1\; k=rsa\; h=sha256\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1PMbJghh91KpUfghVLVuDiwyo3ChtYiphsR6Z/YJcCGcoNIInH4SJCfL43M5WDboWLzOw8ddGCZLERgY6AOt7LjpzXJpH8ReeZjBNvo57ZJLV9PYdr7Ejrj+ZB/9GAHk4WChWBWIPtbOvFrKyRUNABI2c5fVNPp2c57im+G10rgpCOrp1Y34PaNYpqKu2YyLpkWyAZc4kMUsuxKd9iSIDUCBPKibmQaKt1xJk8Wo1fqsXgVqRJ1iAvTFRyEjGkcA1g1m11mO7aXNuJmr7J41i6MqSwG2vQEPpadqJdqA9TkK2HcMeVV9Tn+4XLxpAHN31e96kXET+9CZlUW1lrSyfQIDAQAB
202510e._domainkey:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=DKIM1\; k=ed25519\; h=sha256\; p=ieEhnbQlDTWNsK8s38f392ef/Fvfrj511kHz9OoN06c=
202510r._domainkey:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=DKIM1\; k=rsa\; h=sha256\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvlO5KyPBJAYmGnIoaerGzNlWiiWCOiKaluIauTmRKArSDfDafDiy+k30mwtGRn4i4Q8EAWgplG4Xd3fRYCZsjsEna7QV0GDHsX5fY3eFPOnzdU0M5bbXne9UIztej+qUuPTq5BIZhCCNboAIKCKXbRdAJ+hVGnPkPUq+JjfD1EB2E4aoZ/ukoA+QYfq8A86X2TU1WQKNARRsQvGob1No1xyjtztu+1mt8FC15q/YGYfrNt9GxgPnWlsp2PuHgLblX8COiJMejWJ8DgRTmLc0ncEI3qVVpNICDzl0I8+cvkEgJxF6QA4EKB/SjzlfRooHbf7zwfxmcc5ndTsxix9NawIDAQAB
_25._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TLSA
values:
- certificate_association_data: CC6230E3A88A173D11C7F614ACFB4FE7B57A01F649ED1ADEE5F953213D4C6607
certificate_usage: 3
matching_type: 1
selector: 1
- certificate_association_data: 731B7CD6FA08C4A56060172BF8E30563919139F16265A38EC35B2A1F41CE2B6B
certificate_usage: 3
matching_type: 1
selector: 0
_caldavs._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
value:
port: 443
priority: 0
target: vhaudiquet.fr.
weight: 1
_carddavs._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
value:
port: 443
priority: 0
target: vhaudiquet.fr.
weight: 1
_dmarc:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=DMARC1\; p=reject\; rua=mailto:postmaster@vhaudiquet.fr\; ruf=mailto:postmaster@vhaudiquet.fr
_dmarc.ligory:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=DMARC1\; p=reject\; rua=mailto:postmaster@ligory.vhaudiquet.fr\; ruf=mailto:postmaster@ligory.vhaudiquet.fr
_imap._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 143
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 143
priority: 0
target: vhaudiquet.fr.
weight: 1
_imaps._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 993
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 993
priority: 0
target: vhaudiquet.fr.
weight: 1
_jmap._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 443
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 443
priority: 0
target: vhaudiquet.fr.
weight: 1
_mta-sts:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
values:
- v=STSv1\; id=12286879188751086068
- v=STSv1\; id=15827089775314309854
_pop3._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 110
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 110
priority: 0
target: vhaudiquet.fr.
weight: 1
_pop3s._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 995
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 995
priority: 0
target: vhaudiquet.fr.
weight: 1
_smtp._tls:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=TLSRPTv1\; rua=mailto:postmaster@vhaudiquet.fr
_smtp._tls.ligory:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=TLSRPTv1\; rua=mailto:postmaster@ligory.vhaudiquet.fr
_submission._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 587
priority: 0
target: ligory.vhaudiquet.fr.
weight: 1
- port: 587
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 587
priority: 0
target: vhaudiquet.fr.
weight: 1
_submissions._tcp:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: SRV
values:
- port: 465
priority: 0
target: ligory.vhaudiquet.fr.
weight: 1
- port: 465
priority: 0
target: mail.vhaudiquet.fr.
weight: 1
- port: 465
priority: 0
target: vhaudiquet.fr.
weight: 1
alexscript:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
auth-nook:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
authentik:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
autoconfig:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: CNAME
value: mail.vhaudiquet.fr.
autodiscover:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: CNAME
value: mail.vhaudiquet.fr.
canada:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 192.99.6.159
clips:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
flix:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
flux-webhook:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
git:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
jupyter:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
kasm:
octodns:
cloudflare:
auto-ttl: true
proxied: true
ttl: 300
type: A
value: 83.113.30.49
ligory:
- octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 82.64.154.58
- octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: MX
value:
exchange: ligory.vhaudiquet.fr.
preference: 20
lol:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
mail:
- octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
- octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: TXT
value: v=spf1 a ra=postmaster -all
md:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
mta-sts:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: CNAME
value: ligory.vhaudiquet.fr.
n:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
nook:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
notesnook:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
overleaf:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
sse-nook:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
umami:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
www:
octodns:
cloudflare:
auto-ttl: true
ttl: 300
type: A
value: 83.113.30.49
+11
View File
@@ -0,0 +1,11 @@
GITEA_INSTANCE_URL=ENC[AES256_GCM,data:PYjmpgDEvPEC1S7MrN6d91IUBnGbFA9Xag==,iv:m7YQOMnuEoT5wDyy47aaTqjJG+dhqTJKf5i3hQs6GwY=,tag:2ldKTNRqdJEXTxr3uAyLLQ==,type:str]
GITEA_RUNNER_REGISTRATION_TOKEN=ENC[AES256_GCM,data:RDnENtxQw80C7SwmMZV2DTlEx4+uvzVMy95leGb/1RR6egc6S4xWnQ==,iv:wThZ2+qukJqC+ApvXC9GBdneXJ00jkkTyq+2VXSDG+w=,tag:KygPnxauOpaI1goZ4+uf3g==,type:str]
GITEA_RUNNER_NAME=ENC[AES256_GCM,data:HvNmmQyKxk16WQV8dRfPOfCO39w=,iv:z1YuNWvglBYaXQwZXjMzXD4ZN2d7c3eD9GdSaG1maNY=,tag:FtX6wG47uTGjTQ8UNvGfcg==,type:str]
GITEA_RUNNER_LABELS=
sops_lastmodified=2025-09-16T19:22:00Z
sops_mac=ENC[AES256_GCM,data:JIp7wyaIsy2Jg9p3ybHAljkDn8vpDRHtf7Zm2/M4exe6CbWCRn1jGMle+SnKBv2DKVciquQ9B9cKtKnVCpEAQOceZ1WakwS/mCmjYTIHqcvm8/vst1BYiL1Ovbw2dDstzWo8g+UTKAmVC7E0TJ01vAbsOab+fVacKLHF97pBqW8=,iv:5tcuJntPXrWCeNTGQbXzLaGZnCc8rr+gKG+UTRBNUaY=,tag:g7EYMAaOmwjKFYfz1ID5xQ==,type:str]
sops_pgp__list_0__map_created_at=2025-09-16T19:22:00Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ//c0J+b0XwnMbLlQku3tAEutXuEkQPMMrdOpPYwrua9nNu\nSVPBSiamnTeoaP2kM5lcaQ7HUaRLiS1qjXNVPsnAdkGPPID3SxUJzUo7Ca/JOq7e\n39ihqetWAcn9dNDofTxVKyvKXhXKGaDFy2LhaKugj4tkx6qdMA/XAldvRD6ik1jK\nAZjl2xGYTvZ+XgTGtFs6u3Z9ugD6Q3yPjKRSfeIO8NPT5OFFzY70wqlZflxcpupD\npnsvXQkAK1Rnz6F9+dh6jJYYijTdEe9Q0i+0Uy3q+wMsf8KRWs4ARD05DpgIOnUA\nG0s2kdOOlvqoJ/m2fSV7vkIcCvCwhEirn5kfrdUGi3ENazh0g3vpppAfE0ynZdSo\nDiXI7dzCwMxYi8edieOhK3RrOn8bx7B8F1WE+mHL6StQmD2G+xfvgtKlsEJGY2Ed\n1CpMZSQ0TwFx58fYiK+HsZrwAw/3YVzPWryaYvJ6P8QnY3oJOJihSYGRMmyH5WRo\nle1Rxd+Lrt1UnWyZQ7rpqMsYiIzihsNgNix/2wS1R9R1wRFXPdNDfzjrv1BGm/aJ\nOOqUFo6Hd3jEwYcSsG7mbe+hCAAXoJjZSU43dVzeZ0k5ls/lpOjqjQrZZLgz33uF\nNVNRAKTYD2y+/mQ4vpDUsHhu5rtjxh8u1CJf0++q1W/w+Z4ooq5hcNm3ud3DHYjS\nXgF1JA9ThTS+Hs1fV5SFzGMyFMFGeiTVJeww26R+1Vws7fFwbyAYugOqAgkiNkIf\nS2dsxlH1TRjBq1XD4GYk6P3VDUU5UyxG/5XiOexGEVSxBL/wg6TwpyL1hjvgc9k=\n=fmOe\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
+6
View File
@@ -0,0 +1,6 @@
services:
runner:
image: docker.io/gitea/act_runner:nightly
env_file: .env
volumes:
- /var/run/docker.sock:/var/run/docker.sock
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
esphome: esphome:
image: ghcr.io/esphome/esphome:2026.6.4 image: ghcr.io/esphome/esphome:2025.9.1
ports: ports:
- "6052" - "6052"
networks: networks:
+8
View File
@@ -0,0 +1,8 @@
SUPERVISOR_TOKEN=ENC[AES256_GCM,data:jcW++S0qsqO3EqIHb8pP9UVtj6lAfJc2rPV5tkrOG+pxI+cCrr4BsJhMnzN4MBoUa0XbCvXlhkdo1/x3dUEcqsg4T25IaC72n7IkW/Wy3bwiVYB19y0Znl64hxHZkjFY00XbVBj6LXhtT40T72c4qAm5uzeBK4be2fomIB4FS9M1XKLL27BoH3q3IxoT04KrDUO/aReOUBCGEgGaK7zfeRj6Gm97lRNpkotxuPm0sma0bqsnGu+o,iv:Q0mD4wj2qv+k8sWntiIYe7LzTm6CaQ4QGgyG83YpyPc=,tag:yZrvtAL/+B0RYboTzGmwRA==,type:str]
sops_lastmodified=2025-09-16T19:22:03Z
sops_mac=ENC[AES256_GCM,data:LH5UglnUv7urj92vEukJXlF2bU4HyTeUPxtkGjLu9hB/mw7bRjV2f3BpbJqsOlPPDihQY2mxSJYYEVG5Y0DLYEfHhRy5pzMP6xKCMOAt2bH9fmYlGtdQK/FqoETK2WbB0yt66UGy2cOkYDgyRBzugyh/NpscOheKB+m7A2b4fDc=,iv:7uelheh5cbmVaZ78QIoWmbWJTCA6gscvtk1/qBCEW58=,tag:k75QaO0IRS98LJJCJdQljg==,type:str]
sops_pgp__list_0__map_created_at=2025-09-16T19:22:00Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ//aaSjU182qGrX5Dc+t2H/EAx3CYMIevjMjWZh2jPqSOP0\nhqd3HFic8gc5ZvYNB1SdqlZI/yqlDcbkuEyCqpOikifsic8j2u6Z3GhtkJWrhtFr\n4mkO3BF9tA+F45P07RRP3Jr5tCct36AjClaziEvM1EJctSgDpVmyqbvyRpDXmtFz\n58jzmZCIxKKajGeQ0aERlnRsMa2PrgtfQS77ewUDDq2Lgkf5wSZ8Yg91U7qfEzDE\nEqDKYuy3dJNI5FIQaK1dAeHikf47fZ8hT+YVfaY85OwJh+ojGHIJ1L9DI99DxYa+\nPTO+rswNkrPxHnRfu1eQkLZLnXMS914iW0Na8/+T0zLWrcWcnMWdDx054e3Fe/Gi\n3zTpRDTQAo69J24TYP2NNoF6pF97jVEXz9NY0gdngjM6WDLLc9N6l3ReWfwaFAD5\nZQh6w21vmseroRMgXFnddUlTJE2/8evKJS7+uR+Z86SAojlWXTXjYnJqqj29KlEw\npeSJ+Q+ZdAUWjYtRLS3afwhYnum1hbfWBWRdDgAVhYcD1Yyri37qjSA8Mr086y0S\nW+MriV2jzmtUiSyo0efYqCm+BguWgkeqQlL7YLzg4UHG0J8ZME0qV/vSbFATSzbL\ncPdv6UZY8dw1LNwCLeH9eeNrpPKItasK/pID7H1u6r+4lRFStfFta9XrWeXtZnXS\nXgHdsbBzxhFBxrHEtj2Fn4r9QdjDZhTw59Mnaf3IVp5nbDngPwMMUc9NDgZp5WGh\nqcOeIdI9nGWt6PRTLSPSJZSry/G8tqbJGHjED2imMEdXGWtf5aHy4Z2iKBTfUPw=\n=Xe2o\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
+9
View File
@@ -0,0 +1,9 @@
services:
ha-linky:
image: ha-linky
env_file: ".env"
environment:
- WS_URL=ws://homeassistant.lan/api/websocket
- TZ=Europe/Paris
volumes:
- /root/ha-linky:/data
@@ -0,0 +1,32 @@
services:
homeassistant:
container_name: homeassistant
image: "ghcr.io/home-assistant/home-assistant:2025.9.4"
ports:
- "8123"
networks:
- default
- proxy
environment:
- TZ=Europe/Paris
volumes:
- ha_config:/config
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.homeassistant.rule=Host(`homeassistant.lan`)"
volumes:
ha_config:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/home-assistant/config'
networks:
proxy:
external: true
name: proxy
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
matter-server: matter-server:
image: ghcr.io/matter-js/python-matter-server:8.1.2 image: ghcr.io/home-assistant-libs/python-matter-server:8.1.0
container_name: matter-server container_name: matter-server
restart: unless-stopped restart: unless-stopped
network_mode: host network_mode: host
@@ -1,12 +1,10 @@
services: services:
mosquitto: mosquitto:
image: eclipse-mosquitto:2.0.22 image: eclipse-mosquitto
container_name: mosquitto container_name: mosquitto
restart: unless-stopped restart: unless-stopped
ports: ports:
- target: 1883 - "1883:1883"
published: 1883
mode: host
- "9001:9001" - "9001:9001"
volumes: volumes:
- data:/mosquitto/data - data:/mosquitto/data
@@ -1,24 +1,20 @@
services: services:
n8n: n8n:
image: docker.n8n.io/n8nio/n8n:2.26.4 image: docker.n8n.io/n8nio/n8n
environment: environment:
- TZ=Europe/Paris - TZ=Europe/Paris
- N8N_SECURE_COOKIE=false - N8N_SECURE_COOKIE=false
- NODES_EXCLUDE="[]"
ports: ports:
- "5678" - "5678"
networks: networks:
- default - default
- proxy - proxy
volumes: volumes:
- data:/home/node/.n8n - data:/data
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.lan`)" - "traefik.http.routers.n8n.rule=Host(`n8n.lan`)"
redis:
image: redis:8.2.2
volumes: volumes:
data: data:
driver: local driver: local
+3 -2
View File
@@ -2,7 +2,7 @@ services:
zigbee2mqtt: zigbee2mqtt:
container_name: zigbee2mqtt container_name: zigbee2mqtt
restart: unless-stopped restart: unless-stopped
image: koenkk/zigbee2mqtt:2.12.1 image: koenkk/zigbee2mqtt:2.6.1
networks: networks:
- default - default
- proxy - proxy
@@ -13,10 +13,11 @@ services:
- "8080" - "8080"
environment: environment:
- TZ=Europe/Paris - TZ=Europe/Paris
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.zigbee2mqtt.rule=Host(`zigbee2mqtt.lan`)" - "traefik.http.routers.zigbee2mqtt.rule=Host(`zigbee2mqtt.lan`)"
- "traefik.http.services.zigbee2mqtt.loadbalancer.server.port=8080"
volumes: volumes:
data: data:
@@ -1,6 +1,6 @@
services: services:
roundcube: roundcube:
image: roundcube/roundcubemail:1.7.2-apache image: roundcube/roundcubemail:1.6.11-apache
container_name: roundcube container_name: roundcube
networks: networks:
- default - default
@@ -0,0 +1,32 @@
services:
stalwart:
image: stalwartlabs/stalwart:v0.13.3
container_name: stalwart
networks:
- default
- proxy
volumes:
- stalwart_data:/opt/stalwart
ports:
- "25:25" # SMTP port
- "465:465" # SMTPS port
- "993:993" # IMAPS port
- "587:587" # SMTP Submission STARTTLS
- "8080" # HTTP port
labels:
- "traefik.enable=true"
- "traefik.http.routers.stalwart.rule=Host(`mail.vhaudiquet.fr`)"
- "traefik.http.services.stalwart.loadbalancer.server.port=8080"
volumes:
stalwart_data:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/stalwart/data'
networks:
proxy:
name: proxy
external: true
@@ -1,13 +1,11 @@
services: services:
traefik: traefik:
image: traefik:v3.7 image: traefik:3.5
command: command:
- "--configFile=/etc/traefik/traefik.yml" - "--configFile=/etc/traefik/traefik.yml"
ports: ports:
- target: 80 - "80:80"
published: 80 - "8080:8080"
mode: host
- "8080"
networks: networks:
- default - default
- proxy - proxy
@@ -8,8 +8,6 @@ entryPoints:
trustedIPs: trustedIPs:
- "127.0.0.1/32" - "127.0.0.1/32"
- "10.1.2.11/32" # nginxproxymanager - "10.1.2.11/32" # nginxproxymanager
- "10.1.2.152/32" # caddy
- "10.0.0.0/8" # caddy pods
providers: providers:
docker: docker:
@@ -1,24 +0,0 @@
services:
squid:
image: ubuntu/squid:6.13-25.04_edge
ports:
- target: 3128
published: 3128
mode: host
environment:
- TZ=Europe/Paris
volumes:
- log:/var/log/squid
- cache:/var/spool/squid
- type: bind
source: /root/homeprod/docker/infrastructure/squid/squid.conf
target: /etc/squid/squid.conf
volumes:
log:
cache:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/squid/cache'
-49
View File
@@ -1,49 +0,0 @@
acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN)
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
# Caching
cache_dir aufs /var/spool/squid 40000 16 256
maximum_object_size 4 GB
## In-memory caching
cache_mem 256 MB
maximum_object_size_in_memory 5 MB
## Always refresh Packages and Release files
refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
## Handle meta-release and changelogs.ubuntu.com special
refresh_pattern changelogs.ubuntu.com\/.* 0 1% 1
## Archive files: cache them for 90 days
refresh_pattern deb$ 129600 100% 129600
refresh_pattern udeb$ 129600 100% 129600
refresh_pattern tar.gz$ 129600 100% 129600
refresh_pattern tar.xz$ 129600 100% 129600
refresh_pattern tar.bz2$ 129600 100% 129600
## Docker: cache for 24h (min) to 7 days (max)
refresh_pattern -i (/blobs/sha256) 1440 99% 10080 ignore-no-store ignore-private override-expire store-stale reload-into-ims
refresh_pattern -i (/images/sha256) 1440 99% 10080 ignore-no-store ignore-private override-expire store-stale reload-into-ims
refresh_pattern -i (/manifests/) 1440 99% 10080 ignore-no-store ignore-private override-expire store-stale reload-into-ims
## Default: cache everything for 0h (min) to 72h (max)
refresh_pattern . 0 20% 4320
http_port 3128
max_filedescriptors 1024
http_access allow localhost
http_access allow localnet
dns_v4_first on
-11
View File
@@ -1,11 +0,0 @@
ADMIN_USERNAME=ENC[AES256_GCM,data:8ngfC8VHpaaGCQ==,iv:Ze7ThfWmAWj0ZvV3A7Pd+aqAW/pahkTZhdFC/TnAwZ0=,tag:KCFdGV1dEw3e+q6FBgy2cw==,type:str]
ADMIN_PASSWORD=ENC[AES256_GCM,data:UhxEMnqYDyfgffqUf3Q=,iv:VvNX867P+w20Y7laG0R0c4BUw1uICeyF5SU3+waosRE=,tag:JL4GC+UZY3TqSmCq14CTpg==,type:str]
SECRET_KEY=ENC[AES256_GCM,data:uahYXYr4DvavNMTTdcDA0hdp5wj3OLret3fPF1DEc2lis+E7/fe45DWFuhUu8RAK76tuheA=,iv:Lofc+PP7Rtg99l36yOx6bt0i8hg1DJXzwSKQNJCRYPw=,tag:AiUGZOiLyjKItf++Gya+eA==,type:str]
DOMAIN=ENC[AES256_GCM,data:LyJ7RAgrioTltNQ/BKoPbEN8XQ==,iv:IHrT5TkaXuIhkfN/nHcapz4CNBG0t9lbzrHDjp04JLw=,tag:gjSa/tSVEqk6pXrfhjs7gQ==,type:str]
sops_lastmodified=2026-05-06T17:05:48Z
sops_mac=ENC[AES256_GCM,data:wRtDnVQkNsc1MtxSpbuVDuACkCwunYeyYSaQX2Tglm2kwOnx9iCyhuWY6RMYu5nfyJ1CT1kfqeGrGxhJ5uMDee29eLUv844X3hIXwpMT50jHFXEtfKLfRMfqpv9r9mbp2EP9VNDUtPyIwDk5vSjGeaYqEWtHW/q5y9qIrzqqy5g=,iv:UG4XGi3Qo8/nAddY+rzJm1AKIAmJjtR+2bDqSeaVxG4=,tag:SL2rvrxFmMfgyUyMqFIZEQ==,type:str]
sops_pgp__list_0__map_created_at=2026-05-06T17:05:48Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ//b6zlRVKrqzzszBJmnOUlfeZd5m2ekYv/zIBr4oxHyn5L\neLLff+N7hjBVSajg9Qg7GBQv7s3DX70vHTpdUP38UEO1aM0l3eU1JCwA4Hdh7Ds5\nnq330vUKhIAd+K8Vv4Ei9YHpj+kgMnt+R780qZUg18D39TAnx36q9b5SKzZCUsks\n3YM+G8pHLRipZhxp6zwhOPHVSnImOFjty4d6JV6Zes9zfslaETgva7p5DIKP0ttf\nI2JRacvL75MMp1USyqGKt7Bpl6Yz4VxY49aea+FxDlbzCVLuBBgZMoEjhPQifQfh\nB6OObmu1cVhECidrMHmqDBNqgKsNLble+g3Le+gJdn/zKxVc+q+cPPuk/JdT8tfv\nZTei6jg66IREZOrZCP3Gt4OB5LbkLdS0NET2CMVAYkGQvGrSC+diwUnFkI+WEh+p\noZhvgp/ytBgaw6ZyNPmvkGkFeFg1/ISpOHkVQ+P6Pnot8h4HvuI/KcBwJRCrtdbg\n+XMpqeQdmCnM04v5Uq1NVqRWHD0yvd7GHDOZCqJPMFHP0M6R+SwHq+8+pgbO3jxt\n+426MvhNKw8xWMtnUIO8sSSkzgOfT6vFXmzQvIawbXvitjGjiElkpmT5Hz3hn1Bm\nnu8CivqLwL4Gs1Uc2m6qHGkvGqxWwcHABWqftAk3VfhmjcFDwAyWROlCuD+A15PS\nXgE1wn9jLesXaiCwzAp4AOstkk0fR2yio4fa9dCeenzuedULNLuCyJfYtSm4QlSU\nvffH4iL8X/R24s6SdPsCIuNnAeKc0P4E55AlOaeZN4HcZzfspVikAZx+bK14JS8=\n=KGp6\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
@@ -1,58 +0,0 @@
services:
fireshare:
container_name: fireshare
image: shaneisrael/fireshare:1.7.3-lite
ports:
- "80"
volumes:
- data:/data
- processed:/processed
- video:/videos
- images:/images
env_file:
- .env
environment:
# PUID/PGID: the user/group ID the container runs as. Files written to your
# volumes (data, processed, videos, images) will be owned by this user. Set these to
# match the owner of your host directories to avoid permission errors.
# Run `id` on your host to find your UID and GID.
- PUID=1000
- PGID=1000
networks:
- default
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.fireshare.rule=Host(`clips.vhaudiquet.fr`)"
- "traefik.http.services.fireshare.loadbalancer.server.port=80"
volumes:
data:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/fireshare/data'
processed:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/fireshare/processed'
video:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/fireshare/video'
images:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/fireshare/images'
networks:
proxy:
external: true
name: proxy
+11 -12
View File
@@ -1,7 +1,7 @@
services: services:
grampsweb: grampsweb:
container_name: grampsweb container_name: grampsweb
image: ghcr.io/gramps-project/grampsweb:26.6.2 image: ghcr.io/gramps-project/grampsweb:25.8.0
restart: always restart: always
networks: networks:
- default - default
@@ -9,11 +9,10 @@ services:
ports: ports:
- "5000" - "5000"
environment: environment:
- GDK_BACKEND=- GRAMPSWEB_TREE: "Gramps Web" # will create a new tree if not exists
- GRAMPSWEB_TREE="Gramps Web" # will create a new tree if not exists GRAMPSWEB_CELERY_CONFIG__broker_url: "redis://grampsweb_redis:6379/0"
- GRAMPSWEB_CELERY_CONFIG__broker_url="redis://grampsweb_redis:6379/0" GRAMPSWEB_CELERY_CONFIG__result_backend: "redis://grampsweb_redis:6379/0"
- GRAMPSWEB_CELERY_CONFIG__result_backend="redis://grampsweb_redis:6379/0" GRAMPSWEB_RATELIMIT_STORAGE_URI: redis://grampsweb_redis:6379/1
- GRAMPSWEB_RATELIMIT_STORAGE_URI="redis://grampsweb_redis:6379/1"
depends_on: depends_on:
- grampsweb_redis - grampsweb_redis
volumes: volumes:
@@ -31,13 +30,13 @@ services:
grampsweb_celery: grampsweb_celery:
container_name: grampsweb_celery container_name: grampsweb_celery
image: ghcr.io/gramps-project/grampsweb:26.6.2 image: ghcr.io/gramps-project/grampsweb:latest
restart: always restart: always
environment: environment:
- GRAMPSWEB_TREE="Gramps Web" # will create a new tree if not exists GRAMPSWEB_TREE: "Gramps Web" # will create a new tree if not exists
- GRAMPSWEB_CELERY_CONFIG__broker_url="redis://grampsweb_redis:6379/0" GRAMPSWEB_CELERY_CONFIG__broker_url: "redis://grampsweb_redis:6379/0"
- GRAMPSWEB_CELERY_CONFIG__result_backend="redis://grampsweb_redis:6379/0" GRAMPSWEB_CELERY_CONFIG__result_backend: "redis://grampsweb_redis:6379/0"
- GRAMPSWEB_RATELIMIT_STORAGE_URI="redis://grampsweb_redis:6379/1" GRAMPSWEB_RATELIMIT_STORAGE_URI: redis://grampsweb_redis:6379/1
volumes: volumes:
- gramps_users:/app/users - gramps_users:/app/users
- gramps_index:/app/indexdir - gramps_index:/app/indexdir
@@ -52,7 +51,7 @@ services:
command: celery -A gramps_webapi.celery worker --loglevel=INFO --concurrency=2 command: celery -A gramps_webapi.celery worker --loglevel=INFO --concurrency=2
grampsweb_redis: grampsweb_redis:
image: docker.io/library/redis:8.8.0-alpine image: docker.io/library/redis:8.0.3-alpine
container_name: grampsweb_redis container_name: grampsweb_redis
restart: always restart: always
@@ -1,7 +1,7 @@
services: services:
jackett: jackett:
container_name: jackett container_name: jackett
image: ghcr.io/hotio/jackett:release-v0.24.2184 image: ghcr.io/hotio/jackett:release-0.23.48
ports: ports:
- "9117" - "9117"
networks: networks:
@@ -1,7 +1,8 @@
services: services:
jellyfin: jellyfin:
image: jellyfin/jellyfin:2026070606 image: jellyfin/jellyfin:2025090805
container_name: jellyfin container_name: jellyfin
user: "1000:1000"
networks: networks:
- default - default
- proxy - proxy
@@ -11,6 +12,7 @@ services:
- config:/etc/jellyfin - config:/etc/jellyfin
- data:/var/lib/jellyfin - data:/var/lib/jellyfin
- cache:/cache - cache:/cache
- log:/log
- nfs_films:/films - nfs_films:/films
- nfs_series:/series - nfs_series:/series
restart: 'unless-stopped' restart: 'unless-stopped'
@@ -19,6 +21,7 @@ services:
- JELLYFIN_PublishedServerUrl=https://flix.vhaudiquet.fr - JELLYFIN_PublishedServerUrl=https://flix.vhaudiquet.fr
- JELLYFIN_CONFIG_DIR=/etc/jellyfin - JELLYFIN_CONFIG_DIR=/etc/jellyfin
- JELLYFIN_DATA_DIR=/var/lib/jellyfin - JELLYFIN_DATA_DIR=/var/lib/jellyfin
- JELLYFIN_LOG_DIR=/log
- JELLYFIN_CACHE_DIR=/cache - JELLYFIN_CACHE_DIR=/cache
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
@@ -28,14 +31,15 @@ volumes:
nfs_films: nfs_films:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan,ro' o: 'addr=truenas.local,ro'
device: ':/mnt/media/films' device: ':/mnt/media/films'
nfs_series: nfs_series:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan,ro' o: 'addr=truenas.local,ro'
device: ':/mnt/media/series' device: ':/mnt/media/series'
cache: cache:
log:
config: config:
driver: local driver: local
driver_opts: driver_opts:
@@ -1,7 +1,7 @@
services: services:
radarr: radarr:
container_name: radarr container_name: radarr
image: ghcr.io/hotio/radarr:release-6.2.1.10461 image: ghcr.io/hotio/radarr:release-5.27.5.10198
ports: ports:
- "7878" - "7878"
networks: networks:
@@ -30,12 +30,12 @@ volumes:
data_movies: data_movies:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/media/films' device: ':/mnt/media/films'
data_downloads: data_downloads:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/media/download' device: ':/mnt/media/download'
networks: networks:
@@ -1,7 +1,7 @@
services: services:
sonarr: sonarr:
container_name: sonarr container_name: sonarr
image: ghcr.io/hotio/sonarr:release-4.0.19.2979 image: ghcr.io/hotio/sonarr:release-4.0.15.2941
ports: ports:
- "8989" - "8989"
networks: networks:
@@ -34,12 +34,12 @@ volumes:
data_series: data_series:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/media/series' device: ':/mnt/media/series'
data_downloads: data_downloads:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/media/download' device: ':/mnt/media/download'
networks: networks:
@@ -34,7 +34,7 @@ volumes:
downloads: downloads:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/media/download' device: ':/mnt/media/download'
@@ -1,7 +1,7 @@
services: services:
wizarr: wizarr:
container_name: wizarr container_name: wizarr
image: ghcr.io/wizarrrr/wizarr:v2026.7.1 image: ghcr.io/wizarrrr/wizarr:v2025.9.5
networks: networks:
- default - default
- proxy - proxy
@@ -1,6 +1,6 @@
services: services:
navidrome: navidrome:
image: deluan/navidrome:0.62.0 image: deluan/navidrome:0.58.0
user: 1000:1000 # should be owner of volumes user: 1000:1000 # should be owner of volumes
ports: ports:
- "4533" - "4533"
@@ -14,7 +14,7 @@ services:
ND_SESSIONTIMEOUT: 24h ND_SESSIONTIMEOUT: 24h
ND_BASEURL: "http://navidrome.lan" ND_BASEURL: "http://navidrome.lan"
ND_PORT: 4533 ND_PORT: 4533
ND_REVERSEPROXYWHITELIST: "172.20.0.0/16,10.1.2.11/32,10.1.2.152/32" ND_REVERSEPROXYWHITELIST: "172.20.0.0/16,10.1.2.11/32"
volumes: volumes:
- data:/data - data:/data
- "music:/music:ro" - "music:/music:ro"
@@ -26,7 +26,7 @@ volumes:
music: music:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan,ro' o: 'addr=truenas.local,ro'
device: ':/mnt/media/music' device: ':/mnt/media/music'
data: data:
driver: local driver: local
@@ -2,7 +2,7 @@ services:
tubearchivist: tubearchivist:
container_name: tubearchivist container_name: tubearchivist
restart: unless-stopped restart: unless-stopped
image: bbilly1/tubearchivist:v0.5.10 image: bbilly1/tubearchivist:v0.5.7
ports: ports:
- "8000" - "8000"
networks: networks:
@@ -31,7 +31,7 @@ services:
- archivist-redis - archivist-redis
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.tubearchivist.rule=Host(`tubearchivist.lan`)" - "traefik.http.routers.tubearchivist.rule=Host(`tubearchivist.local`)"
- "traefik.http.routers.tubearchivist.middlewares=tubearchivist-headers" - "traefik.http.routers.tubearchivist.middlewares=tubearchivist-headers"
- "traefik.http.middlewares.tubearchivist-headers.headers.accesscontrolalloworiginlist=*" - "traefik.http.middlewares.tubearchivist-headers.headers.accesscontrolalloworiginlist=*"
- "traefik.http.middlewares.tubearchivist-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" - "traefik.http.middlewares.tubearchivist-headers.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
@@ -49,7 +49,7 @@ services:
- archivist-es - archivist-es
archivist-es: archivist-es:
image: bbilly1/tubearchivist-es:8.19.0 # only for amd64, or use official es 8.16.0 image: bbilly1/tubearchivist-es:8.18.2 # only for amd64, or use official es 8.16.0
container_name: archivist-es container_name: archivist-es
restart: unless-stopped restart: unless-stopped
env_file: env_file:
@@ -72,7 +72,7 @@ volumes:
media: media:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/media/youtube' device: ':/mnt/media/youtube'
cache: cache:
redis: redis:
+13 -13
View File
@@ -1,16 +1,16 @@
PAPERLESS_URL=ENC[AES256_GCM,data:5Vt6SqefNzOKGzUaRukM7wKu7Nw=,iv:/x12Sv55XY1znKr2UFQB1Scp+T1cZBs5XlqxTNtBQck=,tag:xahglGfuW2wCkDMgX1nZGA==,type:str] PAPERLESS_URL=ENC[AES256_GCM,data:JODh8rdOgce1+CZf8QANKO+c4ug=,iv:EZ/PWCT43EzNwNwdzCj9Egr+2pDk+syozozgzsx1MGI=,tag:Nq7uUJ3ngUROIx2Y+Js1Gg==,type:str]
PAPERLESS_SECRET_KEY=ENC[AES256_GCM,data:CoWplCZsHbgFPkkBDnzaPnXcq9Fv4OpXuJHs0YTLDi+MmJjK4Lpd+Q==,iv:vX3uYJ0S6lSyHW3comqum5ncXUHFj7LCdNSbRRgY3/M=,tag:gwSwk1lVmoQdgqQ38sFN0A==,type:str] PAPERLESS_SECRET_KEY=ENC[AES256_GCM,data:haP1VefYx/PywNdze0atjcGsPFSOoXcRp3ZsNpT0lLPR5SeUK6y1lw==,iv:O3gNPia0t2e2HDe7BPohq51WGoWdqG6daNUoUMffO8E=,tag:aZt5HVntmX45pbjoONBmOg==,type:str]
PAPERLESS_TIME_ZONE=ENC[AES256_GCM,data:sDtE4GwXr9CScxyq,iv:7oGDO/5Dvj8/E4qzzIhncbboTRfJbTfT/FwUhF4tCNg=,tag:mEcg/i2TaCls+FgCTl6AlA==,type:str] PAPERLESS_TIME_ZONE=ENC[AES256_GCM,data:+UvrtDQ1EqlL0/UT,iv:UsRm2N//W6R6/gPIeULjYnyza1xcL3yoBmoVaXuG46A=,tag:VbOmuR+ZnEyPudvTxzfZBw==,type:str]
PAPERLESS_OCR_LANGUAGE=ENC[AES256_GCM,data:ihFV,iv:+xRvsrymSIB4z5K03bU6N+pugafhvHph3epj1HTDPag=,tag:RhBA2b1q3jIhE9bmcwtYxQ==,type:str] PAPERLESS_OCR_LANGUAGE=ENC[AES256_GCM,data:Bl30,iv:UrDNUb/l8vSx2ebCQnZp5XI4eS3Ax6/Refw73aUfVNk=,tag:95FZOTner1Pezn+K86bQjA==,type:str]
PAPERLESS_OCR_LANGUAGES=ENC[AES256_GCM,data:0pbc/9WMlw==,iv:HRnX25U1CasIvdU0h0G0SYvRjzzpmyPpDrcN6sAk+Ck=,tag:Ym08zaK+LqSDEafnUVvGnQ==,type:str] PAPERLESS_OCR_LANGUAGES=ENC[AES256_GCM,data:R4uuEaszmg==,iv:5wmrLWv1yKWciksBT5ZFxUeFUHrdJRlhHg1rZCWrkqE=,tag:zCd7o+0fm1eRKYRfNsP7ow==,type:str]
PAPERLESS_OCR_USER_ARGS=ENC[AES256_GCM,data:DdpIIK0k5wsJWhcVNtq6w1mK2nsBlXKs/bB3kCxUe9tj7tyff2yH,iv:htcBkWENiugF1T2N0JfJOGfn2F15Ti6icf6JnzmLNjQ=,tag:EACbCMn4aZ7zCWxd1voawA==,type:str] PAPERLESS_OCR_USER_ARGS=ENC[AES256_GCM,data:d6cARP14FbMK0kDGxD1GqY8MIsTnINL2g7DlStzLy+JU8wxuYiwXc4c=,iv:hhff8s1ZliL3SPL0sJT6AAzVE5nyoVg5ypbtTCWbP+0=,tag:gzZajS6DOBLTVQjVaBFpAA==,type:str]
PAPERLESS_SOCIALACCOUNT_PROVIDERS=ENC[AES256_GCM,data:vLWinFKXotVzhHqmwpJ6R93Ep44JL7D1P91DbbLcGawfl8Hx+cTtYX2zuBAzeqrlDd+pHVX9I/F/eq3sAFUJrHhwSiscPaw4lc0KWVj3yAbR6guu3ZGKLMZiltGi8adOt+ELvL4aJYNfsdcECaj71JXaqF08+DkLuG6k3BOp/5j+BRFTuAfyS8SXgSo9UTpfNqJWLA2YyNiEy1ht9sbNJYT5FbN9++ZFlJPVmJDyo/8kU2CdkowmLuFhij2hcCt/wvhQ5kjYIzr+LCuPGtF68CVChVguXxTj7w5Mqo9bkdIIUtjzubhbP7LiERE5vQdLve75ZE4mQFt/5H01qwqZkXw7DFn4sJXKQCpCyA+IanA1NO2ypd1plYiR8F+15LNtbfPuZo5hzpYdf3y1xgPrSHUMV0AvAbvJYXyDg2UprpGzxSwLmskZc+4Dqm8ZfTp8IdC9RvETets6fA6t1ucnYFbEB4t0RfF1wzI93m5acE0XvDe7PvnW9X10XDwAhKV6EY9V7OktiL1/swO7MxI5qV6NtxXMMg46V6l/63k5GDmM0FS4Sn9BeIQ=,iv:JwSeogftyoa4k0kQAf63nnoqbIiHWH0Iwa83Nhqlx9Y=,tag:9KrbSxSmN1CzqnVxcsvPgw==,type:str] PAPERLESS_SOCIALACCOUNT_PROVIDERS=ENC[AES256_GCM,data:uRfd5q+qbdMrXH8t/y2SpBYAYwfiUqukvVgfo9M8QOPQSugW8rfd2clOnb8xAyTqB2yXEOxdAk9KhqJqtK1gNjmYit9Fb11OVmlC/WflvRqofc9PcpPR/BwjVnnqLzISJ80gNP198jHQGx3Qd/sA7PpLuoVi3o0ZinSm1ndmtwSI7aKNd7aUJhsTWzfkzgFwThDmANDhiFVSqP3mlVVDVDBrfX3oL5f8cL8vtkIOTs/npN3fuyOSuGIgx9z5YjomnY8R0oSUUJ3mL5fekSfWkLTOg9rr9xsP3X0/a6Y2OK6Yz0kdQ5NcIsxXyzh2ab6cYW68uVsKWD7QjKUfS0nQCSJDo2yvR9vDAa5TKOQ182phWgi2V55mXLOS9S8rN+tHvu7KvEWOaEJpDgHpYN80c7O8PFD/mq84IpknDaQ52GX0ediVIaEK/q0MlWnCWjun6AB2/in+/vm7bo4iMc1UXLMcAywYLpTmt6yFznDoj8INtWTczx+7uuGyAbdkhwwSmrzQl2n2NtueTtPTe2PCdfwpb1nZjN8yfcTPhvjTUoqN6LLQ+aRPdd9xPQ==,iv:V2AXOh5lRgApSCyGqmZ1zBnnppndFWU5eG/jngaKQ7E=,tag:+hHb+io54meKYWQDuAkjpw==,type:str]
POSTGRES_USER=ENC[AES256_GCM,data:2IkvrQgFYj0v,iv:YxKokHIOsRhgRx2XZsCYsjtJwW0yOx+S5HKKiFQBKlY=,tag:HI4aSRYp7GotOXeF8VBHQw==,type:str] POSTGRES_USER=ENC[AES256_GCM,data:YqX4AEq64Sg8,iv:FnMj2DSIVtJlTDInIIABeUV+WgnGjDXtMcKPKpgDw4Y=,tag:s90Grdon0X90h+JOJ0VjVA==,type:str]
POSTGRES_PASSWORD=ENC[AES256_GCM,data:8IiqLOi+Xoln,iv:9zLPLvSe+7FjjunVQvcn5YiejZj0wN1mQu++B2JPy9o=,tag:HRIHXlmYTPCSaZ5BzPA/aQ==,type:str] POSTGRES_PASSWORD=ENC[AES256_GCM,data:4OAmFMXX0HOb,iv:D8ESA3pLlSZVCc7FsT/DNeXRJ7ew26r8cJN7we5Yads=,tag:BGmx/Y/10PTmYaAB5en5yg==,type:str]
sops_lastmodified=2025-10-08T19:39:41Z sops_lastmodified=2025-09-23T16:16:55Z
sops_mac=ENC[AES256_GCM,data:bjQBttibD3m6mjiDtQ/RqfSc0rt3eV/ip+UUzwF45k/+akQCM+kAvSVFiICpRYLQd90hGDSJJytGze0YQBIYS58u/PXovqT+BmbJ5S9jEVwDUnAnFwoVmuGI6dkorCGgLZFxbj/Vwde5v2R3K7nMTyPC/5EJPd4R9gZLgT8/+Bw=,iv:tyyjQXpBEDb+KOEFRNPxUIcEcxYAM+qw2pCyvOltuFE=,tag:xPfaZTAi1Sd0RW5PN0iKog==,type:str] sops_mac=ENC[AES256_GCM,data:ClQM+7txITye56fRWvnrOBRrlc2KnVpkE/2Wo79bWjv+/IhPZHymRIhQGTGpYWrH2RTX05K16jBoUKJBF6yoKybjLOrtBJgEGMe1W+0wXO+yk5gdwyEnTRZ2l03gUmG57g5MaQVbFVFAY9Vb7ksE3R0aduy7fgqrdP0QZc9MUvo=,iv:nGonrKjKW0a6qHxOj76mrfbLystM7Dj/3v5Wsgx5Kh4=,tag:Mkz30qB/9NRawVkz+zdkDA==,type:str]
sops_pgp__list_0__map_created_at=2025-10-08T19:39:41Z sops_pgp__list_0__map_created_at=2025-09-23T16:16:55Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ//WBbj9C5n7tOL8HBWRiiwRHS8nE3XWg7rAROnvEaD5QuE\nEubGw+PnsX3nSiv07Th23dN24IqpgLqz9grq1s6WDgRgQAFqu2f2FTYmIvcU/mko\n9I69i1E8iSYIvfRmReOn3L2GlhQrADYbCYC+mMEAXJtTuJ44KP0JtGTFPP0+m4vb\nspuuebFeES8cVsk2RPuRUQJC6uSk0E78ZaxMWgZm6P/6bnRwDbn4OE3NrQbkvhvn\nKupR01MQ7HAZh5jVi73aVnY0wfxe4fDToef1bjiiZUJEwJ57oKhOmj5EYlTurX0m\nzraNkpDIWQNJnVlMgUEOclmrnL0uz3wkaqu8BoUkyaWAJS2f545amJNUBO23Mogp\ng9VgFeOyivM0xx5JZAN2LRkK5CrpKNpjXYtFzGkxKZxAAs4iyrUGDecJtfZJM48M\ntvgzbL4jqJu6rrOH27e3F74HyEmX+f1sIJMSnvanEiyYxIpdbvMc8+ULtGzpsdUd\n4hQ/yYKqEkecyKwjPEN4OlAI2LdokTxeYOszjJ7iBO1jE2D7e3hgzpjsGZmj1i+J\nzTUGUSAEgfd2w+/xfYzWttMysthrGa0MMwEeKYttuoZjIJ04IDB6JBQWNWxbfGpp\nXlNd5G2+xrGl2oaYzc4fAJRZoQZRWgX1Dy78cvRm8OIUGJucz0cZeBPiI3/Ny5/S\nXgFC/aC1TJBNvFC/60oOrerjzf5LVrx6O3zevs7LCrVVq0iL/xSSU+DnTxdczKPt\nKh9x1LMKUQK5cnMOdoWt78uUNmLkKiSkht43ozLcqvb3cxgRyoSlMP2lvk9YWx4=\n=gnXz\n-----END PGP MESSAGE----- sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiARAArI3sIJzb+xpElZlHYKe9fHFcjLuGi3lN00imIgyDv6XS\ngfOkGTNE7HXLbGmH4cYqcr6TSTDLsWE9H46++jCWzOyCBZ0l+c+So8ciBs9w/YUG\nxZlBjpW39xKyPS0Oszuj6q6czFdyHw/+yDJh/dbZU3wJF5jQlorUqIZ/3fJRXxwY\nte7y1u2AZJT3RnaRjIKW6snKpQY6XiWglwKBQcuXtfz8zY63DXNDf6DfUZRquV42\ni9hFGVuM0iGvrEwe/xAcuVQNEC1i19SS2wI6DdyRY1WGzNzWmeFTGR6QTTw2Mwmr\nOPI8WajPwOuvHYrQr3+YP9bUkAljiKEDeKd/434C/S+jCcSbzqnql+MF/r2jO+bc\nS+FaU+sI0A+ICxHHXzyvRy6iC4+UjIC14m011w5HkhBDtfqGFIkr898xB3CGmTpt\nLjBoJ336KpD8QOYuK4QXLiOcy8amb3KwwWwpZrBL4hgQnsr7H7uvhz9T2Y6DCmMT\nDFmq275urc6R2NV6ktw67EiQanx6FBlHPSJi75YlEXswCD4Ryqm0Qjv0ICu/8yQ2\nVxI69woI455jZwYWNH9nRMFdlXVeA5gqj5Kmb+6aSYAdoZXKgkJPgryV4g6PalIS\nXwCLRMOne2xXDYgklXJyO67SUfWoERB2bQmVIrkGKFXEKdu4BmRJKCszHj555gLS\nUQE1oBpdIW426IYxES09Fh9SZwvbPDcUUH5iomJPMxkQEV7vrzmEhVOwGg81MxVB\nWjWV2zAdyJpWrqyEqisTnMZlLnc3LwyAraMvybM0SfTP9g==\n=0EsL\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2 sops_version=3.10.2
+1 -1
View File
@@ -16,7 +16,7 @@ services:
POSTGRES_DB: paperless POSTGRES_DB: paperless
paperless-webserver: paperless-webserver:
image: ghcr.io/paperless-ngx/paperless-ngx:2.20.15 image: ghcr.io/paperless-ngx/paperless-ngx:2.18.4
restart: unless-stopped restart: unless-stopped
networks: networks:
- default - default
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
radicale: radicale:
image: tomsquest/docker-radicale:3.7.5.0 image: tomsquest/docker-radicale:3.5.6.0
container_name: radicale container_name: radicale
ports: ports:
- 5232 - 5232
+10 -24
View File
@@ -1,8 +1,9 @@
services: services:
syncthing-valentin: syncthing-valentin:
image: syncthing/syncthing:2.1 image: syncthing/syncthing:2.0
container_name: syncthing-valentin container_name: syncthing-valentin
hostname: syncthing-valentin hostname: syncthing-valentin
network_mode: host
environment: environment:
- PUID=1000 - PUID=1000
- PGID=1000 - PGID=1000
@@ -11,26 +12,16 @@ services:
- valentin_documents:/valentin/Documents - valentin_documents:/valentin/Documents
- valentin_photos:/valentin/Photos - valentin_photos:/valentin/Photos
ports: ports:
- target: 22000 - 8384:8384 # Web UI
published: 22000 - 22000:22000/tcp # TCP file transfers
mode: host - 22000:22000/udp # QUIC file transfers
- target: 21027 - 21027:21027/udp # Receive local discovery broadcasts
published: 21027
mode: host
- 8384
networks:
- default
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.syncthing-valentin.rule=Host(`syncthing-valentin.lan`)"
- "traefik.http.services.syncthing-valentin.loadbalancer.server.port=8384"
restart: unless-stopped restart: unless-stopped
healthcheck: healthcheck:
test: curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1 test: curl -fkLsS -m 2 127.0.0.1:8384/rest/noauth/health | grep -o --color=never OK || exit 1
interval: 1m interval: 1m
timeout: 30s timeout: 10s
retries: 10 retries: 3
volumes: volumes:
config: config:
@@ -42,15 +33,10 @@ volumes:
valentin_documents: valentin_documents:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/main_storage/valentin/Documents' device: ':/mnt/main_storage/valentin/Documents'
valentin_photos: valentin_photos:
driver_opts: driver_opts:
type: 'nfs' type: 'nfs'
o: 'addr=truenas.lan' o: 'addr=truenas.local'
device: ':/mnt/main_storage/valentin/Photos' device: ':/mnt/main_storage/valentin/Photos'
networks:
proxy:
external: true
name: proxy
+15 -15
View File
@@ -1,18 +1,18 @@
#ENC[AES256_GCM,data:+dgva36e4X+kOQD6Lg7x3wN297bxXPWGm+yTqd7GuLyo3R0Ldfa9dELvEy86vqZcx6wVGyPfLZolf/7+1aZ0URQ8yyU7iinQLZRfuQ/i4zE39Wg+ug==,iv:nyTpn5naWcXC3/+2d5o84ttMKHKPqcdh1eW1Qhqu7KY=,tag:EMX20dvxj2xXxOF/uhA+qA==,type:comment] #ENC[AES256_GCM,data:nDJXRHo16C9LLtA8cRUD7Pu6G9k3z/JPMQyWh/sXmrYig78ocFi36KzRNut8u4gRDml/ykgHlLm94y1K5Gg4eHsaAi5Stk4CrPyPus/hDgd6nB61BA==,iv:y4BEf1FBUG5QSa4edDYFYczU9WUi4V9gqnC1NLcOYtU=,tag:revz/um+XirnUUxEY/hyOA==,type:comment]
SECRET_KEY=ENC[AES256_GCM,data:MQpLChGTbmiTJn1A4ujjs6yTi09Agip/0J3eT7SJ84qcgAgPV28l8RR5d1JE+kLzaEQ=,iv:00k/1vrnTgEG//mlrE8TAawDbyhMuGh3zuxxhHsLuEo=,tag:4FsnE6GRvjR/bRZfqaI1mg==,type:str] SECRET_KEY=ENC[AES256_GCM,data:OmutGAIPHz4l3oLil7LNGdY8Cv82B7dNrkZFoQn2GNsYzSOZoj7nge+0SieKSTqyob0=,iv:NiifR5odKEgXkfsRjU91hP0wrcLf7n10XiekDkKSnTQ=,tag:yZZ3LNr6FA6Xv1t+bwBJJg==,type:str]
#ENC[AES256_GCM,data:D9iipG6E4YUxpzUH51+6A4KFYAPPneU9AYSzNXhIK+asmUsk3ogN8QzncjTKUFeJ3IBRh3vR8q/w3bR61ATbMWq5Dvy8UV8RKI2PpKNdV+I3kTtkHF28dMpg1D81MDrZv3XG5hWsNoxuRIMXTl/ImHdb7OGt3E3Yjw==,iv:iBBDh4kuob1AHW+ztSPoMP/wgHECAUsb07GZjbbUYSY=,tag:7kOiSTYrK6hE7E3f+ZOynw==,type:comment] #ENC[AES256_GCM,data:4DaWj6Y1scTKoOZwkGcU9GmnXvhzxRJO3PyJvkfzlO0WkjpprRjYo5P95ZdlnZrk0M8gGHZ2zuxwm8MNxVlw8dKwdAFubTPbeTpasa/XoAFZciZgXBWmv5DLLyQ/yXP/e70mSWKYpmj8nQ7JkBoYSXwMR1mntbRSPQ==,iv:hBRikHT2RFxo488HO2WF5M8AiTHhQw/eTZoQqaFzH8U=,tag:RqwEf0QmbFfiXsMf9tZdiA==,type:comment]
ALLOWED_HOSTS=ENC[AES256_GCM,data:fA==,iv:P7zb2UFzhOSZfBbOdXmgZz6vMAYC2UzuGVawxsfoTcQ=,tag:fhHBI8gXTXrK1eLkbZNPbA==,type:str] #ENC[AES256_GCM,data:FjSYK3tDKa2BeY/FUBye5wcXUjEJaAxQj7Q=,iv:+rkQmUPVOte+9W1r0RzcZl3vwCva6ONUPGwl8HdwgSY=,tag:wox8uewK5jGxBSDT87NBzQ==,type:comment]
#ENC[AES256_GCM,data:iXUhDgm3Z7TOmuGpcoK67XRRQgwZ7gFkXR7gGQusa62pS3Q6qKkj6JzBikbgZG9d6cEpI7F00odoi2+leQoKAUCiuUkC2t9l2Bp194gJ/yf4t7HDnIpKrR+HamZh4cA6VE5q523KqVnIfSVwKzFI5KQ=,iv:QMKkjhQjA2tTOp0sdgPIcmuecHr/yQRudg14LBn9rOo=,tag:fJ95+YsKHYHWUhFPwGh1tA==,type:comment] #ENC[AES256_GCM,data:O/Utl77r6zCAyZpOwvXEsuNCvUN9/Uw/bz1OOHqYI23CHJxjU8bPUgnGq2F/1Y9eC+1NheMATcgEOsx8wZVNm6707SwylRXbBLWASAJY/U4oLgm2tKLcMLd8yU9Sulp65S2Iwu+LwK8f8PYMWFZRCAo=,iv:IoI9vA3PfT/GQRQn2GRpLF7WMSdFZ44z9Tci646jm0E=,tag:IVddJQwMQ8HQ0aiPEzQcZA==,type:comment]
DB_ENGINE=ENC[AES256_GCM,data:sAHT9ykTS/fRJoGll7zbtC0f0OdolH6KoKlV5ZM=,iv:7NjD60gemxVE1IGGiX2y3qrV+C7Q+oVw+3ihgfLIYQQ=,tag:T/SCdnvjoHRTujw84tUQFw==,type:str] DB_ENGINE=ENC[AES256_GCM,data:YCZKf7/riM43EVwI+OC7ZK3zhSB+o1KPsZjML6E=,iv:+MVjA3706QwHE60PrnlmV5TZauZ4oiMQ2szY7d4BH4c=,tag:uR3+At7DpSi5lXxL1jGAMw==,type:str]
POSTGRES_HOST=ENC[AES256_GCM,data:6bLRvIaWAsXuvA==,iv:M/FHf+b+RBM5s9FkuoHfbm92G/xd1nHX9ybFKgcU+r4=,tag:RdQ03UD018Sd6871IXHxbA==,type:str] POSTGRES_HOST=ENC[AES256_GCM,data:MEeYiNliMe0QPg==,iv:MGrySxMuVId7TUSHlMxTWfZCwQkWe/7Uzb05je+z9AY=,tag:R+neZ6AV1PmunX8SpEE+nw==,type:str]
POSTGRES_DB=ENC[AES256_GCM,data:+l5L7LFB5rI=,iv:5dOgXGEz0NhlGc7EoseT+vqGMP7qUMHVrZtZ04saYv0=,tag:O6H8JEcZLyyHzmuLZEj0JA==,type:str] POSTGRES_DB=ENC[AES256_GCM,data:Oj/x13nKqww=,iv:CRX+KCvdrtMBuyQoM6lYp2jPoX3ynpEQvNvG8vVDER0=,tag:hHTZs7nyRHYbKPcwkpkLbA==,type:str]
POSTGRES_PORT=ENC[AES256_GCM,data:moVL+Q==,iv:Up9P2BSQG0LRg7dpJmKcM9XVv8U0LwVmR1OT5IiRsjU=,tag:O+oVY2u0Z/nua3JPctqKRw==,type:str] POSTGRES_PORT=ENC[AES256_GCM,data:xG6OMA==,iv:RAaZMnIraUD21fz850vSrAAKr2Px8XDWT/w0j1I2KNk=,tag:SoOCZcumwJpp/OdmGnt2LQ==,type:str]
POSTGRES_USER=ENC[AES256_GCM,data:0pvImCp8YiGwHw==,iv:HeMNTkjvj7Cn0e97sMQQ6rD1chMCq4SJYEw8ey9NzrE=,tag:szRIG56Vw7xpC1xL63l7sA==,type:str] POSTGRES_USER=ENC[AES256_GCM,data:CNr2sdWsOW9Rjw==,iv:OyyxMOqSfY7VGgw8gvKetbKsz711rqsx7q2q2NCgzEk=,tag:wee12iH0niPk28HhKLmRxg==,type:str]
POSTGRES_PASSWORD=ENC[AES256_GCM,data:9eLbXMxp5fqmrID0bYMSzA==,iv:q6yJOYuivGX195TUItFFMHhDLOHC1tDR8tb47UqKsiU=,tag:09vvc9Hqjkj9O4dI95rcbQ==,type:str] POSTGRES_PASSWORD=ENC[AES256_GCM,data:mSUfMvGV/iInGeQmsu9TQg==,iv:XbV/XUHwKOm7khLibuTbz8P8KfnEz6YMHPWZndqzXs8=,tag:YDL1qbNq2b9WX1cmDyt88w==,type:str]
sops_lastmodified=2025-10-11T10:38:59Z sops_lastmodified=2025-09-23T20:49:33Z
sops_mac=ENC[AES256_GCM,data:1qRH5pTYnVQGt4jiqQH+bkiW24yRtWkZ2QNjNKtvNctaMEcR5J8yNOl1/aak4zswMsqUqWaXtbLJ2DR7I8FcehrxRUXnAfI4g0xekd7+tcZdsN1D0SKSBi3yk7J0rTTL3vRnZUzjdEEf1RSRf5LSjxGS4JbRqPVfhiUWRUVBKHQ=,iv:x6FqzR1EFUyLEumhAG1Yvz7c9RjlBkF30xjE5uBKyoQ=,tag:CzXuPzmZfn09A3m287JsRg==,type:str] sops_mac=ENC[AES256_GCM,data:mlwYhfyGIxuupvhRT5eGP+QcVoI99uw69s9ud/QYogCu8WstXsJAIsKjBZu1dlxfs1pvTN4ehX966yFfSkRNeT+UcIPHbN0UK9Gnv7CnO3AdF9IxJy4RJ607LAFeZVVobY0E7LjNyeD9Gt9UiAb1U+v5yF4XVm7A+2OTvSgBUos=,iv:Y7Vmy92yfahN0o+kNuAhGD79acY1adq859rU8hfYVMk=,tag:srfdmpfsDL7o+Su+F4zTSA==,type:str]
sops_pgp__list_0__map_created_at=2025-10-11T10:38:59Z sops_pgp__list_0__map_created_at=2025-09-23T20:49:33Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ//VJRc8ou8YvhhfoxG8vrJX20nWbPLSWsU60Soo3BBcQ33\n/NZVkYY8jtyFJxOeaARewJKK4umSKUQovHj3KgexMrTZZk+vG7wByhBD6yX0Yonh\nsm2Z9CdbOdNizg8FyBD0iryBpBRPLGp5Z2gJlM/DwAAwArOZzb2oc+fq04YrOZVO\n91/mSoDA4McVkUMH/RdBxJz8eKIVAuUtEkMHysoTs3d2HOCFkzi5cezXpNmnfzvc\ni3BPOa6o7ek1u8TIG3rXODm274atMqFaXnzPn8yWZDuqZLrcz96b/yIY89Yd6LN2\n6ZMUyeJop9FY0w6OSZ9qdLT5EuwRm/LnFRcEb2cBXXFgTHz2TpXoGQXdzJM+TFJ1\nFg2lnNxb/vxPzFrTG8cG6dtuZr/YQKRnpK/MHJ2ZlCc1hUuejmSqkMKJS05zXXOT\nS+6F/i1p9+XYTXt48ZVLDubDTqMXE6CyXX86Py3bueVvg8nysWfRPyy1ECC2+Anx\nd0YcVxpj7Wlm8Rql5pNJZJ/jj7EIuHW/cbTritWz5CAr8pYlJz/JsICi6uhMIOP7\n6Ocj6UCD5TEOc1iA45NT4f1BSioODh9n7U945npcwiPWeRpJKDTcVXlw2HJRvOE3\nHF7D+dxde3ZePkkUb0XhZWmWlvzRuuM2Ur9aztUZS8gXHEwb3V/zlH4HXvhl2tPS\nXAEh8gKTyF69pY4RKc7/p8zp5mGdybuCT4XChA63nndi9WyopJt4cul4x9oKPsE+\ngDXrllyrZsRmRAAtTcl7Gl41Il4YeBzop8u5/3qZoAjANrnFlJI3NOAL7SuP\n=7kXM\n-----END PGP MESSAGE----- sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ/9HEiC8UWx+wNWy6peC+BBSG1eXi4NPHgLSxTVn5s50s1w\nXrddeGGNLJ2RJxvCbKEk4B+Q3tBguTyip97Awex2Xwsl5deTuFmxJDO7fGFxAgzK\ntRIo3dJRisSAArcUj0ElAhgxZpAoFB5U6VY9cexIjE94PBbhHo3zlcd3dSgv39v9\nJOYYy62k6MzwjIHwdS3d/oKn3tDqx8D+WQXEMEPRlyM1ptrODnxqiFu3iAUCH4SS\n97GsHsVCmvKL6O61raYa+Kt5BoFgUem2rXKj603PW7iL8Q0wdIWCPC10v4XUB4N/\nfM30qi2tPmObGkbBMnA/8VRYv9M+gUi0PBKGstuxjs15/ypJTEm4p0aTsySmTF3J\nq6YKJmZAG0fxUkdIdV/CJKNRoTpgviPHfm8est9vZwB3hbs8N4TOY5AgHMHRygbD\nhUFR5vhhqAgI0qs0BKfCjVM2nHx5h5tzxqr2OPSn8zKKDJY8EozdFvmPz6PRzEzJ\n2899UvJ1rX34zKOCxOeKMurW0BNjpkIh1Quke/Ob8F0LygAekbZJPP1fbZIQgzgz\nWSxyA2RZEdI+Rv6Z24P0VJRzNzk6NkyHVe93E/dK2ICHhUz6xd+BMRfEi38LkQ8C\nhGb/iU+eLOhtVvmcSq1/R8ezWmAo1/VjeqYgknMdhO+H1SDcUhDLX2fcDrqNv2jS\nXAEM9LPeZI4k9moLKiNAEcJe3AH/nN4GaXbDVO2UExNT12C1xd9ODqv+9aIqdOiu\nqFRxpSUjPFVgLdGdLvsk6MzXsMbhBpNSrWwYKBPA895lzKgB5b/UwQk/rnmY\n=grEF\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2 sops_version=3.10.2
+18 -6
View File
@@ -9,20 +9,32 @@ services:
web_recipes: web_recipes:
restart: always restart: always
image: vabene1111/recipes:2.6.13 image: vabene1111/recipes:2.2.3
networks:
- default
- proxy
env_file: env_file:
- ./.env - ./.env
ports:
- 80
volumes: volumes:
- staticfiles:/opt/recipes/staticfiles - staticfiles:/opt/recipes/staticfiles
- nginx_config:/opt/recipes/nginx/conf.d - nginx_config:/opt/recipes/nginx/conf.d
- mediafiles:/opt/recipes/mediafiles - mediafiles:/opt/recipes/mediafiles
depends_on: depends_on:
- db_recipes - db_recipes
nginx_recipes:
image: nginx:1.29.1-alpine
restart: always
networks:
- default
- proxy
ports:
- 80
env_file:
- ./.env
depends_on:
- web_recipes
volumes:
- nginx_config:/etc/nginx/conf.d:ro
- staticfiles:/static:ro
- mediafiles:/media:ro
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.nginx_recipes.rule=Host(`tandoor.lan`)" - "traefik.http.routers.nginx_recipes.rule=Host(`tandoor.lan`)"
@@ -10,12 +10,12 @@ services:
ports: ports:
- 80 - 80
volumes: volumes:
- /etc/timezone:/etc/timezone:ro
- reservations:/app/reservations - reservations:/app/reservations
- selenium_data_02:/app/.chrome-selenium - selenium_data_02:/app/.chrome-selenium
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.alexscript.rule=Host(`alexscript.vhaudiquet.fr`)" - "traefik.http.routers.alexscript.rule=Host(`alexscript.vhaudiquet.fr`)"
- "traefik.http.services.alexscript.loadbalancer.server.port=80"
volumes: volumes:
reservations: reservations:
-18
View File
@@ -1,18 +0,0 @@
ME_CONFIG_MONGODB_ADMINUSERNAME=ENC[AES256_GCM,data:AHXIMA==,iv:trofFagJGNq5OyWDaN57vPpKwwG3SouiV5xLl5sJIBA=,tag:c1NUlmBouEb0Milri85QNw==,type:str]
ME_CONFIG_MONGODB_ADMINPASSWORD=ENC[AES256_GCM,data:8X6+SphUNus=,iv:zwofVw03pToXHR6weckniT/fymFYeHZw6lVmrGUsnLc=,tag:lEWtnnqpwamNsCnkStsRfQ==,type:str]
ME_CONFIG_MONGODB_URL=ENC[AES256_GCM,data:3xLFWhRYU/EfhRw+rOs9pOb+nzsbV9IvQydB4VGZGw/WLkQd,iv:T9T6ewB+05qzFDL7z2WESs6fIc9lTFdjVxy/71YzhXo=,tag:S3YsOokO4jzhJVWep/QTsQ==,type:str]
ME_CONFIG_BASICAUTH=ENC[AES256_GCM,data:FnUichsnpQ==,iv:Ayw1Vqg5rj6P79vtERX2hRCttnol/4aNUG5Y0OhFVTo=,tag:JkTxro0kyYJLr9gdkY8A1Q==,type:str]
MONGO_USER=ENC[AES256_GCM,data:2KFDcg==,iv:wdDxrQd07+hC5GEq1DS0DLVASiL9L4ds1V3TG1NA9EQ=,tag:gieiOLmOfLtUQjfjwZg6qQ==,type:str]
MONGO_PASS=ENC[AES256_GCM,data:W80YLzp8G50=,iv:eFts3fhrB9PGEfC69d8btt4ko3gcOGrFZUy95hx2rCE=,tag:+1JFEiclNnjei8+2I42j6w==,type:str]
MONGO_HOST=ENC[AES256_GCM,data:0RknYUM=,iv:8QyL4KHrSr9pv1kX+FD09N2ltVSZkEKqtFCS30ik1v0=,tag:bTXBMHqp5JU9VTD3soXEyQ==,type:str]
MONGO_INITDB_ROOT_USERNAME=ENC[AES256_GCM,data:G6wekw==,iv:AH5qqxXOeEBVI2mXXPPrC1X8X/Vq5MHZBWdfNRNeK1c=,tag:nMkWql/aVHi2FGnJ5NGFBQ==,type:str]
MONGO_INITDB_ROOT_PASSWORD=ENC[AES256_GCM,data:jzVSUjGSjOY=,iv:S/Ar0oYN2vSE7pK+/tfp9RyCThtDbk0gOUYDyzNYjVE=,tag:whWyBFHuXBcmF+WixjafOw==,type:str]
RIOT_API_KEY=ENC[AES256_GCM,data:EzqWk1Y73htAXaUJhzByV6Aru/hxUNjHGK90ac1NGaz92Cwk9YEdmrb9,iv:KorIppEflVX2aDC8K3ndRzK1q6scNjdQfl38p/8fLGM=,tag:Ei2zLoiGOlOX8ocrO2wNMw==,type:str]
CDRAGON_CACHE_DIR=ENC[AES256_GCM,data:uMogP1/K/pc=,iv:/0A8fs9HEuksSiKV1SZDoslHHGlJe+vFw0BQ5zQ9BBA=,tag:grwWPwMQarpmSAUIgKDZ5Q==,type:str]
sops_lastmodified=2026-04-30T18:20:37Z
sops_mac=ENC[AES256_GCM,data:7teYIGLLHBH8TJ/gr3lcbtfo4CVl0Gj2RWPSLgx4AyTvM+pZaSvUDaVUhWuprSCVqZcDWI2tNHUOHE4aYlJzyt9JfQrooKLPkKUq3WX3bucg3Rv5GpiP1tNHiPDE7UZCBp5bkHhYvwn+dPjhObEUdMUuwMBDA9JSpPlr3YQCg/E=,iv:6knBO6QNe33E2bJw5WZMzcDzeTW9mwgjQtftv0FZq8s=,tag:xuIKZl7szrUyX8/D9xxAmA==,type:str]
sops_pgp__list_0__map_created_at=2026-04-30T18:20:33Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiARAAufkTVdCq2ARwMFuec9+0N1BzTo7WgGQhzKIJehe+uQ5I\nuPS5bafo5vrvxlCuxVmhup45CS3gm3X46hgHh/d3htaYzDnbyh/awbVGIhU9sa9T\n74i4jZAabzWjWAU8lAvxS6dJ6hf5U3MHOc1zYoCUfCJjgw+QRzR5PxZKFhpVklQU\nQJycdfRAl5oAqF7N6B7oCNTs7w1hbx2CJXBVGM8YoJySkThpXEY3dECxZ5nTSPmp\nXo3hmidO09uYsjWzcqynJHnh9RkMd1VAe6ULzhVIOv5KLXQLQV/paNAPdsxA5UmY\nE1imIFrqS25BVU9xbsGaPj6AHX6+Ux8bpO8TOVbpULe56Aq2c5GOjIZXb3p20K7N\nEk5rJ/K+8FxvytK3jDkhJI49wiDs9UDim02DSZmsWirIy/c02Ojy2d/Cxors1Lw/\nBCc4S6/ESH9u/LGlWs8WDqcDQqhHgeCvGOLAvOXs9eOCXNW2ROtNdfW808APbu1A\nzgYJwPtdfBhUv4KhZcEVMldWgX1OiYhcWMWYgJUXcfOwaRbzntZ/MczPNJ/a+57T\nPvH9GuTiwCXn0fOgcETTp9RPvXflL+4LPgh9drCOo4zwMvlqZs2+0Os2m8GDdDcL\nD45VMTsnNUXWuO7YUdtYX47bON2W6Z7NwzvkSr5odogzq1xw38SgRN7g3Jbl6+fS\nXAH/Rw8jWjpYztZ5HgDXisTxLEXqn5UNYKZBjzsLV5tE9GQp8ppck21igBiDCqoT\nsziZwFyRy/nKq076lZlRgSFr0pm4168u7Vn5x1TLQBHl+i0eKficgUQpwCFx\n=XUsx\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
@@ -1,57 +0,0 @@
services:
mongo:
hostname: mongo
image: mongo:8.2.11
restart: always
user: root:root
command: mongod --wiredTigerCacheSizeGB 2
deploy:
resources:
limits:
memory: 6G
reservations:
memory: 3G
volumes:
- bpmongo_data:/data/db:Z
- bpmongo_config:/data/configdb:Z
env_file: .env
match_collector:
image: git.vhaudiquet.fr/vhaudiquet/lolstats-match_collector:d878af6d1a5cb633175515259e27a12c76c4609b
build: ./match_collector
volumes:
- bpcdragon_cache:/cdragon
restart: "no"
deploy:
restart_policy:
condition: any
delay: '0'
window: 20s
env_file: .env
frontend:
image: git.vhaudiquet.fr/vhaudiquet/lolstats-frontend:d878af6d1a5cb633175515259e27a12c76c4609b
build: ./frontend
restart: always
volumes:
- bpcdragon_cache:/cdragon
networks:
- default
- proxy
ports:
- "3000"
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`buildpath.win`)"
- "traefik.http.services.frontend.loadbalancer.server.port=3000"
env_file: .env
volumes:
bpmongo_data:
bpmongo_config:
bpcdragon_cache:
networks:
proxy:
external: true
name: proxy
@@ -0,0 +1,29 @@
services:
vhaudiquetfr:
container_name: vhaudiquetfr
image: git.vhaudiquet.fr/vhaudiquet/vhaudiquet.fr:latest
networks:
- default
- proxy
ports:
- 80
labels:
- "traefik.enable=true"
- "traefik.http.routers.vhaudiquetfr.rule=Host(`vhaudiquet.fr`)"
environment:
- NGINX_HOST=vhaudiquet.fr
- NGINX_PORT=80
volumes:
- public:/usr/share/nginx/html/public
networks:
proxy:
external: true
name: proxy
volumes:
public:
driver_opts:
type: 'nfs'
o: 'addr=truenas.local'
device: ':/mnt/main_storage/public'
+11
View File
@@ -0,0 +1,11 @@
POSTGRES_PASSWORD=ENC[AES256_GCM,data:naUGUVMbgkNSbblt,iv:ao/NeYM62PnViWtNfWlobLcgZrf/K2cQV3FXJR+TidQ=,tag:MGILTlnyfy8itf1cjHkfMA==,type:str]
POSTGRES_USER=ENC[AES256_GCM,data:kXeEALbz,iv:VgUHRsrMQoMxhPMTrbteNGbfSFSuKR0VZkdeWY7eqZM=,tag:t2Q4I0wIGsaYiHcQkZpnRA==,type:str]
CMD_DB_URL=ENC[AES256_GCM,data:Z4gMf/68p4vNL9zv5ygAUHENAhO51lJEnN5xhEsr1yv5nQQUCcrgNwE6swxV8EhMSKweuaiIt93ybgbu,iv:rOM6DJp+z31sEYapFPuhfOL5C+Ot7PDR2GnvQkIiTuY=,tag:lC5AkC/i8/a0Q3Ou/GcByw==,type:str]
CMD_SESSION_SECRET=ENC[AES256_GCM,data:2k+ctM/7j/JhXMzLaI+x4QMzyyHf6tJpjrQ7rLRn896h0g+5P3AB6DfUbcmdWbE0ab6AkSuUm7wKcEKFwZrDwg==,iv:JdLg/9yUstUaeoaMvPknTYInq+t+AjqhP36olCKVeXg=,tag:3dIGzKgNOJu8xX6vR4ruqw==,type:str]
sops_lastmodified=2025-09-16T19:22:00Z
sops_mac=ENC[AES256_GCM,data:TLX5aj8DkvlLcub8oLgYzpPM3/JkSejZzc96NVB/loOvPmbe+JWEHs4ZHWhxLW9diL8cP5a6hfRAlIsXknXG7I8TN/s11+z77h0wwVQjKk25WH5rZ5REJrz3UCa/QNkMCozFARM/rQH1WoNBHKqKqnj3z6OlntNdWC4y/E2PpDA=,iv:JZ6yVv+Rjda6KBh6Ubdggq+vmrGE4AOBMZPKPYqOwLY=,tag:bO5NgxkeSksqqiho27BoHg==,type:str]
sops_pgp__list_0__map_created_at=2025-09-16T19:22:00Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ/+MKdgjEQ9YAAK/6cvFuSSHwkLCiGhwhQyYuL/N4PEQ4hi\nanMMlvsAY5R691OMGi1hmSrmtm5DJuO5Ol9/Q3v4nPLuF4cvTApA6t0uhEmqPrWu\nKQc0vvakPUoxbi6RuiCiUujyh/kVaJbNpOjqGPiTAdpHxfqjTRwT7qGwOKFKLqcE\nwotXc9zCMu8tj1X2hpku5kIL2b3b6yt5tSNtrua/hjo05Q9SJmO1qOa3YRo8g5/R\nbwlqMDe5qzaASV5Tsu//P1uTpq0/MI8qhrJmYOdCY9swkYAOzpap6UGhvjbxLHwk\nd8g4YNEt+UcoIHVGn3rdLWvRo7UJS9ewTQq5UAU9ahCGzzbz9dqHSk7preO06cWG\nVsA9uCZ55UfkHqE8ucEqADPx6erduV5VPie4aakwbFUlYklwllvyc3s3NQJkorAn\nZpkI6vXBvCD3adF4JdiULUh9agRKIVfV/zDOcBdPv5bvhAr8EPmk2fU53al1ULkz\n9SMHVVl/97OJ8seMHbYbmPbsQLzChhtgFFqnhoBbPYgh1z5XSiCgxCzVUUWjub7S\nTAKxDbxOCfEn3n6h/ITdRU+LCFoc0zZi2k9dOqtXtZWQpO2RyL04pxPcS3QgMXqN\nKPtC6sY57ii6m118vBuaY9W0u+YADVJCfxSiCaQRHgVBhSV3hZUXlcMn1iGBrq/S\nXgFC4jpm+cZi7UsExMLwDUjmqlMGFUAD1IPoXymWrgZeBeeMrJ3BRpifNKYxS9Ps\no5q1Tuyslwot4XBPr/YRCcw+rEYosSUaRahYZav02FPWVuVZw1rdeKwjBiUfBFw=\n=QSUX\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
+55
View File
@@ -0,0 +1,55 @@
services:
hedgedoc-database:
image: postgres:11.6-alpine
env_file:
- .env
environment:
- POSTGRES_DB=codimd
volumes:
- "database-data:/var/lib/postgresql/data"
restart: always
hedgedoc:
image: quay.io/hedgedoc/hedgedoc:1.10.3
networks:
- default
- proxy
env_file:
- .env
environment:
- CMD_USECDN=false
- CMD_ALLOW_EMAIL_REGISTER=false
- CMD_ALLOW_ANONYMOUS=false
- CMD_DOMAIN=md.vhaudiquet.fr
- CMD_PROTOCOL_USESSL=true
depends_on:
- hedgedoc-database
ports:
- "3000"
volumes:
- upload-data:/home/hackmd/app/public/uploads
- upload-data:/hedgedoc/public/uploads
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.hedgedoc.rule=Host(`md.vhaudiquet.fr`)"
- "traefik.http.routers.hedgedoc.entrypoints=http"
volumes:
database-data:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/codimd/db'
upload-data:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/codimd/uploads'
networks:
proxy:
external: true
name: proxy
+20
View File
@@ -0,0 +1,20 @@
INSTANCE_NAME=ENC[AES256_GCM,data:GLnSjEj0NhKzccTJpjIN7o48LiSiIIg=,iv:ku2w/xVEhyYVsf6KQFypFK4y6154nLvgEt2XaqRcOOI=,tag:rzjxIxjyMNNfurUuD1zpMg==,type:str]
NOTESNOOK_API_SECRET=ENC[AES256_GCM,data:97xTiLFM9pL/bUM3,iv:gSlpqmsZyIzf7jpugc0ueGVmwCrauIuo+64gmlwzZaY=,tag:zVECG8LUGTVQJfH1tsXYTA==,type:str]
DISABLE_SIGNUPS=ENC[AES256_GCM,data:An/cGA==,iv:jQhnSXSxDaTZ847tDZ7nUeqhgNpdYu3I7Q2oqqjkO3U=,tag:l7cu2AUgUlqrckNgCIg9ng==,type:str]
SMTP_USERNAME=ENC[AES256_GCM,data:cke9ITC/naUhfoOr19FakMOmgkk=,iv:lgJOnpPwfYyPdEPn/8zhgPM++sKQHjM2lwnqj3/349k=,tag:TfWixgwuhvdvAfYkPT+anA==,type:str]
SMTP_PASSWORD=ENC[AES256_GCM,data:otmIJtB9wYOu5weVLgw=,iv:Cz8IgIjtQJtePNOYrIE8UE4Ey0kmLFIgql5M6co/D84=,tag:aDMvWzACfrOsqBqUQ+D2zA==,type:str]
SMTP_HOST=ENC[AES256_GCM,data:LYUUxNHABmeHbv7tFbOeZn4n,iv:PBPZhQNseoG0CXUZ3d3ECG04aWpw/QA2wA5sToMJ7EQ=,tag:m9VlE3eWnOtmyzTV0eBgOg==,type:str]
SMTP_PORT=ENC[AES256_GCM,data:qqQK,iv:99/i7zKxt6KAVCeIB/7TMvz2CqomwQZNIY+TeJqcgAY=,tag:/g9Kt49YkawKc8d0UBHPcA==,type:str]
NOTESNOOK_APP_PUBLIC_URL=ENC[AES256_GCM,data:KWK12glgITh0h8at2RuUzsrfY1DzusIDSg==,iv:Z/H3NbIWjz6T1/7sC2SuBYvMJn7ltQEHwBT5e2RGm3o=,tag:2t60j9gPPOY7bqM2QqsLNw==,type:str]
AUTH_SERVER_PUBLIC_URL=ENC[AES256_GCM,data:+bLyA0ucfycLLc4iGkWb9WisMr5wskAZK07QVCcM5oj2eTMmxfQ2Mw==,iv:Bp4JoLgxgRJMG98/QWRBTQnIpihgHp1+izCgOr1UoNI=,tag:uSPnZPEWU5QC0CTLeRCldw==,type:str]
NOTESNOOK_APP_PUBLIC_URL=ENC[AES256_GCM,data:u/8oFwLF1ZtuiIvM/bOM0XH3ibQYvyVPIA==,iv:p/ECEwrchuqaU2MRCUZdGJGTRE/mTkglPIX+nMZQ4J4=,tag:5cBC8D+MIya1vQa3kSXHtg==,type:str]
MONOGRAPH_PUBLIC_URL=ENC[AES256_GCM,data:uoiC69IAyraujhwVdpVQQEGM0b78tJh6VG2bLRtqoAUTBGp6bUGkABE=,iv:5UpUJKBjHaUzRFyUySI6Wyjich6E5JNmQqIVjsxOhkE=,tag:UP9NQzlX8CaB5oACMTqqtg==,type:str]
ATTACHMENTS_SERVER_PUBLIC_URL=ENC[AES256_GCM,data:i0nNFgcLVgJI2fU72x7z0JciE3Rld10GhOdEo3p5YlGvcA==,iv:JpXfO+VfruKjbP3pkMUYQMlX4xsfts6PQ0brUK3abzQ=,tag:Jd/laba8yfEbswP3bN/UJg==,type:str]
NOTESNOOK_CORS_ORIGINS=ENC[AES256_GCM,data:XF+aOoB9JjV1CaI0tdERfOO/TQNvaIVfZGEaRPgpzaWNjKNAaTDVN6ZffgVI+RD3pY5R03c2GBpWYYu7zwxyF7XF6fSmazGfI6bhKuk8+A==,iv:mR5v1V2npqwx7KMzps7RFy3u//SllTTxLWabG+b17ms=,tag:1myD72i/0zX79/TVOTWfGw==,type:str]
sops_lastmodified=2025-09-16T19:22:01Z
sops_mac=ENC[AES256_GCM,data:Nl320cxMzRHaZ0H0tfUaHb4jtZb8AadWOIEVJCFcmDA7YRofKnRkmt3xFc3cNKJj3FoDri6AflCFTSvG7FaY66FYjaQBUjz5566YHw/tng1ctHgxGjW4tyDS8NRFPEyugFm7d6QPiLAIeKSbJEGKbCfDVdQm57gptxpA2XNWc+Q=,iv:LuehCTAxGPCfnw6zg9BpqfzuJObKU6gB7MSNr51eNZI=,tag:hU0Nm1OD4V4w9nvTpQXtSA==,type:str]
sops_pgp__list_0__map_created_at=2025-09-16T19:22:00Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ//dbVRD62HBACKEDwmCYgfYyKQk9RGgxBhBodXGmyFP31k\nqDms2E8+9V3QHr13mw840XcTpE8g9XL0IqQYHU3+wrNafo/hDgGPrfpw+7AtVhtk\nBv5VCeULBxkPJjWEv9Tv/T/ZDP5qKAsllaqvdw0ZliuBug6viXdq1U3GOTsIprZf\nh5TyW7Y1I3zQ4w/CmzRJVJUF1Vp6eBRFzuKndGIrjOAQrlqwhd1SyCUxrJ6LW6N6\nEmpuoOvhFvGnbRnhfNwRzDU6m6yLG8VjJeKWOHxLmeQe3DcxY+/Q4tFbWtRGtrWJ\nqoqxDw5CuqdnvlDlf3TE2REbFIoZphJNibtsMVMGNZyDY93NUmfMRCg9WGmHym2o\na76jZfQhb5voRMVsdKSqdb+jNd5WfSl5u+30JWw7m5BfvXCWpL5hECFP9qn/piDl\n2bVQVRQ10VZJp6D3S8y5zHiEuCHbYtZtUZXektKjWCJBQVYTh0c+cME6Pm6oDp8E\nQIflT+QwVtrXPCulwFbl/IMMtR+/BXFFMzmyxHc7JQfItavcEu2xWYYqV8jrymqJ\nntAYlTdop9kSdn7PxGba9YxcWvcAMSox9aMeol4IJ+IAfJXCV+MCTajrmFQeyRDb\nI2draPx8VjSC5Mf0FeXDQmnRwmkcdBdZiwuHvte2xBQyIeQi2whdq/zNvOk5RFrS\nXgErWrMWM0lAZPVk/gnDCcUhdojMTn+Pz1uwLGS201D94fADXN0nhSXstqlDO5tN\naM/XJItjToWRrRc12JYXFemNIbCTvbP6kfBvt8z4pFc9OtnvNWxbSvL7mOvWUiw=\n=2MC3\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
+283
View File
@@ -0,0 +1,283 @@
x-server-discovery: &server-discovery
NOTESNOOK_SERVER_PORT: 5264
NOTESNOOK_SERVER_HOST: notesnook-server
IDENTITY_SERVER_PORT: 8264
IDENTITY_SERVER_HOST: identity-server
SSE_SERVER_PORT: 7264
SSE_SERVER_HOST: sse-server
SELF_HOSTED: 1
IDENTITY_SERVER_URL: ${AUTH_SERVER_PUBLIC_URL}
NOTESNOOK_APP_HOST: ${NOTESNOOK_APP_PUBLIC_URL}
x-env-files: &env-files
- .env
services:
validate:
image: vandot/alpine-bash
entrypoint: /bin/bash
env_file: *env-files
command:
- -c
- |
# List of required environment variables
required_vars=(
"INSTANCE_NAME"
"NOTESNOOK_API_SECRET"
"DISABLE_SIGNUPS"
"SMTP_USERNAME"
"SMTP_PASSWORD"
"SMTP_HOST"
"SMTP_PORT"
"AUTH_SERVER_PUBLIC_URL"
"NOTESNOOK_APP_PUBLIC_URL"
"MONOGRAPH_PUBLIC_URL"
"ATTACHMENTS_SERVER_PUBLIC_URL"
)
# Check each required environment variable
for var in "$${required_vars[@]}"; do
if [ -z "$${!var}" ]; then
echo "Error: Required environment variable $$var is not set."
exit 1
fi
done
echo "All required environment variables are set."
# Ensure the validate service runs first
restart: "no"
notesnook-db:
image: mongo:8.0.10
hostname: notesnookdb
volumes:
- dbdata:/data/db
- dbdata:/data/configdb
networks:
- notesnook
command: --replSet rs0 --bind_ip_all
depends_on:
validate:
condition: service_completed_successfully
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongosh mongodb://localhost:27017 --quiet
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
# the notesnook sync server requires transactions which only work
# with a MongoDB replica set.
# This job just runs `rs.initiate()` on our mongodb instance
# upgrading it to a replica set. This is only required once but we running
# it multiple times is no issue.
initiate-rs0:
image: mongo:8.0.10
networks:
- notesnook
depends_on:
- notesnook-db
entrypoint: /bin/sh
command:
- -c
- |
mongosh mongodb://notesnookdb:27017 <<EOF
rs.initiate();
rs.status();
EOF
notesnook-s3:
image: minio/minio:RELEASE.2024-07-29T22-14-52Z
# ports:
# - 9000:9000
networks:
- notesnook
- proxy
volumes:
- s3data:/data/s3
environment:
MINIO_BROWSER: "on"
depends_on:
validate:
condition: service_completed_successfully
env_file: *env-files
command: server /data/s3 --console-address :9090
healthcheck:
test: timeout 5s bash -c ':> /dev/tcp/127.0.0.1/9000' || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
labels:
- "traefik.enable=true"
- "traefik.http.routers.notesnook-s3.rule=Host(`notesnook.vhaudiquet.fr`) && PathPrefix(`/s3`)"
- "traefik.http.routers.notesnook-s3.middlewares=notesnook-s3"
- "traefik.http.middlewares.notesnook-s3.stripprefix.prefixes=/s3"
- "traefik.docker.network=proxy"
- "traefik.http.routers.notesnook-s3.entrypoints=http"
# There's no way to specify a default bucket in Minio so we have to
# set it up ourselves.
setup-s3:
image: minio/mc:RELEASE.2024-07-26T13-08-44Z
depends_on:
- notesnook-s3
networks:
- notesnook
entrypoint: /bin/bash
env_file: *env-files
command:
- -c
- |
until mc alias set minio http://notesnook-s3:9000 ${MINIO_ROOT_USER:-minioadmin} ${MINIO_ROOT_PASSWORD:-minioadmin}; do
sleep 1;
done;
mc mb minio/attachments -p
identity-server:
image: streetwriters/identity:latest
ports:
- 8264
networks:
- notesnook
- proxy
env_file: *env-files
depends_on:
- notesnook-db
healthcheck:
test: wget --tries=1 -nv -q http://localhost:8264/health -O- || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
environment:
<<: *server-discovery
MONGODB_CONNECTION_STRING: mongodb://notesnookdb:27017/identity?replSet=rs0
MONGODB_DATABASE_NAME: identity
labels:
- "traefik.enable=true"
- "traefik.http.routers.identity-server.rule=Host(`notesnook.vhaudiquet.fr`) && PathPrefix(`/identity`)"
- "traefik.http.routers.identity-server.middlewares=identity-server,notesnook-server-cors"
- "traefik.http.middlewares.identity-server.stripprefix.prefixes=/identity"
- "traefik.docker.network=proxy"
- "traefik.http.routers.identity-server.entrypoints=http"
- "traefik.http.services.identity-server.loadbalancer.server.port=8264"
notesnook-server:
image: streetwriters/notesnook-sync:latest
ports:
- 5264
networks:
- notesnook
- proxy
env_file: *env-files
depends_on:
- notesnook-s3
- setup-s3
- identity-server
healthcheck:
test: wget --tries=1 -nv -q http://localhost:5264/health -O- || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
environment:
<<: *server-discovery
MONGODB_CONNECTION_STRING: mongodb://notesnookdb:27017/?replSet=rs0
MONGODB_DATABASE_NAME: notesnook
S3_INTERNAL_SERVICE_URL: "http://notesnook-s3:9000"
S3_INTERNAL_BUCKET_NAME: "attachments"
S3_ACCESS_KEY_ID: "${MINIO_ROOT_USER:-minioadmin}"
S3_ACCESS_KEY: "${MINIO_ROOT_PASSWORD:-minioadmin}"
S3_SERVICE_URL: "${ATTACHMENTS_SERVER_PUBLIC_URL}"
S3_REGION: "us-east-1"
S3_BUCKET_NAME: "attachments"
labels:
- "traefik.enable=true"
- "traefik.http.routers.notesnook-server.rule=Host(`notesnook.vhaudiquet.fr`)"
- "traefik.docker.network=proxy"
- "traefik.http.routers.notesnook-server.entrypoints=http"
- "traefik.http.routers.notesnook-server.middlewares=notesnook-server-cors"
- "traefik.http.middlewares.notesnook-server-cors.headers.accesscontrolalloworiginlist=https://app.notesnook.com,http://localhost:3000,https://notesnook.vhaudiquet.fr"
- "traefik.http.middlewares.notesnook-server-cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
- "traefik.http.middlewares.notesnook-server-cors.headers.accesscontrolallowheaders=Authorization,*"
- "traefik.http.middlewares.notesnook-server-cors.headers.accesscontrolallowcredentials=true"
sse-server:
image: streetwriters/sse:latest
ports:
- 7264
env_file: *env-files
depends_on:
- identity-server
- notesnook-server
networks:
- notesnook
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.sse-server.rule=Host(`notesnook.vhaudiquet.fr`) && PathPrefix(`/sse`)"
- "traefik.http.routers.sse-server.middlewares=sse-server,notesnook-server-cors"
- "traefik.http.middlewares.sse-server.stripprefix.prefixes=/sse"
- "traefik.docker.network=proxy"
- "traefik.http.routers.sse-server.entrypoints=http"
healthcheck:
test: wget --tries=1 -nv -q http://localhost:7264/health -O- || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
environment:
<<: *server-discovery
monograph-server:
image: streetwriters/monograph:latest
# ports:
# - 6264:3000
env_file: *env-files
depends_on:
- notesnook-server
networks:
- notesnook
- proxy
healthcheck:
test: wget --tries=1 -nv -q http://localhost:3000/api/health -O- || exit 1
interval: 40s
timeout: 30s
retries: 3
start_period: 60s
environment:
<<: *server-discovery
API_HOST: http://notesnook-server:5264
PUBLIC_URL: ${MONOGRAPH_PUBLIC_URL}
labels:
- "traefik.enable=true"
- "traefik.http.routers.monograph-server.rule=Host(`notesnook.vhaudiquet.fr`) && PathPrefix(`/monograph`)"
- "traefik.http.routers.monograph-server.middlewares=monograph-server,notesnook-server-cors"
- "traefik.http.middlewares.monograph-server.stripprefix.prefixes=/monograph"
- "traefik.docker.network=proxy"
- "traefik.http.routers.monograph-server.entrypoints=http"
- "traefik.http.services.monograph-server.loadbalancer.server.port=3000"
autoheal:
image: willfarrell/autoheal:latest
tty: true
restart: always
environment:
- AUTOHEAL_INTERVAL=60
- AUTOHEAL_START_PERIOD=300
- AUTOHEAL_DEFAULT_STOP_TIMEOUT=10
depends_on:
validate:
condition: service_completed_successfully
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
notesnook:
proxy:
name: proxy
external: true
volumes:
dbdata:
s3data:
-9
View File
@@ -1,9 +0,0 @@
COUCHDB_USER=ENC[AES256_GCM,data:wMQJhlZFW30=,iv:OG3S+hZppJdP/PjDINGEEQZD8Qf4520mfzsyw+/QAx4=,tag:i1og4xc0N4Hf4UE0GKPtbg==,type:str]
COUCHDB_PASSWORD=ENC[AES256_GCM,data:eud7WTnlZEzzBGciiwM=,iv:g8RCLIcO1ZxUn/SROHV/stl+whdzICMSX0jVLKXbTns=,tag:6gReHLd+97dqUoAlYL780Q==,type:str]
sops_lastmodified=2025-11-21T23:00:14Z
sops_mac=ENC[AES256_GCM,data:O+jtG9ojK8Md6NSaqfyykVdVG84Kafz3zoKb5hbj2alzvJgaLuzVu3ihM75ZU3/meu/nPl9wCc+J4RKepE7VTp5Il3HK09MVHYRHQKVlbyiZ5cTbU74JJuSL3PF1GiU7p/U5Ht9+Z9c8sDrqSN2IPSIfDr8zCdTwKZF71nYOqew=,iv:n33XCpiwVOGnrJyH3Q967u5uMknRfAwx9esJuOLl+9g=,tag:aKMwsOKXPRUaa+9/ZmnpfQ==,type:str]
sops_pgp__list_0__map_created_at=2025-11-21T23:00:14Z
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQIMA7uy4qQr71wiAQ/+Mt0/uXHnndDK7FLEM8rhWmX0NpJWtgBY3BBXMX7I2Ilg\n6hNZJxISOqcoJCPqb8gZ9pUulcGC5F8owoo/wUILyI/mK3kAzGCP+lfp6Dk03k+P\nwB6BcQTC8NJsApoygdm50h/jtnlK2KUCICFKXUxf527KLWdo8g0wnMIOBe8mBvVC\n8bI/1BOcJZeB4IhmFVrgED+Ct1dTTiuyLscJirCqHD0VTD4eavd6DVpN89m/mtY/\nhTRVT3omuV8JITLeWPdVVWyQznrq3/x8OGAs8L2c24gad5AsTLCr2WS20CvXP1uL\nUoLH9EH0IDvo36DbiMO+p3LdyEvlRe1PW+0dvOpO64CLNoH4szYDJ/dG+UUa3xWo\nRpOIT1F0puXRz3UHZv/IkAFah4Zzi8TxdZDD7Riz5pzMWqzWwdQHQUS1ZWibm1ve\nfC7strrMNybh+QUfMTXhTaW4OoRkY+rGo3d2x3eUjZpaqlKOBWaScZ0c1I7DY/CP\no4QoCoga1RNePXp/WWvWAbQf0w+hAxrsb6U3/ECKtcd4gYGE3shvH0MS6T4oAaIx\nB9ldqRbKIcEUYU7MWq3Wqt8c1k/MtJZh1q3YuZwy8C3U8cHiS5iqDWzAnjIkUwbC\nJpYVaIOvI0qOjE7v6Fc06ZnTBoh/DoTX4XfdIY39GMo3ZageBV0r7Fi0HUzbFxvS\nXAHnsiZZXFB/TJAVEZKDO0Yic3DhlYLL/glOJF0kNgUOoYGvTFaSuNhwhv4tqOrw\nSv7FLH+79LSrM/bPug3Zq9Ec7p/TSnsJ4amu6p7VSmSHRBGV0uZDxt5wkYnG\n=yY4C\n-----END PGP MESSAGE-----
sops_pgp__list_0__map_fp=DC6910268E657FF70BA7EC289974494E76938DDC
sops_unencrypted_suffix=_unencrypted
sops_version=3.10.2
@@ -1,44 +0,0 @@
services:
couchdb:
image: couchdb:3.5.2
container_name: couchdb
env_file: .env
volumes:
- couchdb-data:/opt/couchdb/data
- couchdb-etc:/opt/couchdb/etc/local.d
networks:
- default
- proxy
ports:
- 5984
labels:
- "traefik.enable=true"
- "traefik.http.routers.couchdb.rule=Host(`obsidian-livesync.lan`)"
- "traefik.http.services.couchdb.loadbalancer.server.port=5984"
- "traefik.http.routers.obsidian-livesync.middlewares=obsidiancors"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowmethods=GET,PUT,POST,HEAD,DELETE"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowheaders=accept,authorization,content-type,origin,referer"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolalloworiginlist=app://obsidian.md,capacitor://localhost,http://localhost"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolmaxage=3600"
- "traefik.http.middlewares.obsidiancors.headers.addvaryheader=true"
- "traefik.http.middlewares.obsidiancors.headers.accessControlAllowCredentials=true"
restart: unless-stopped
networks:
proxy:
external: true
name: proxy
volumes:
couchdb-data:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/obsidian-livesync/data'
couchdb-etc:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/app/obsidian-livesync/etc'
-1
View File
@@ -52,7 +52,6 @@ find kubernetes -name 'release.yaml' -print0 \
if ! [ -f .github/dependabot.yml ] || ! cmp -s "$tmpfile" .github/dependabot.yml; then if ! [ -f .github/dependabot.yml ] || ! cmp -s "$tmpfile" .github/dependabot.yml; then
mv "$tmpfile" .github/dependabot.yml mv "$tmpfile" .github/dependabot.yml
echo "Updated .github/dependabot.yml!" echo "Updated .github/dependabot.yml!"
git add ".github/dependabot.yml"
else else
echo "No changes to .github/dependabot.yml." echo "No changes to .github/dependabot.yml."
fi fi
-1
View File
@@ -33,7 +33,6 @@ find docker -name 'docker-compose.yml' -print0 \
if ! [ -f .swarmcd/stacks.yaml ] || ! cmp -s "$tmpfile" .swarmcd/stacks.yaml; then if ! [ -f .swarmcd/stacks.yaml ] || ! cmp -s "$tmpfile" .swarmcd/stacks.yaml; then
mv "$tmpfile" .swarmcd/stacks.yaml mv "$tmpfile" .swarmcd/stacks.yaml
echo "Updated .swarmcd/stacks.yaml!" echo "Updated .swarmcd/stacks.yaml!"
git add ".swarmcd/stacks.yaml"
else else
echo "No changes to .swarmcd/stacks.yaml." echo "No changes to .swarmcd/stacks.yaml."
fi fi
-195
View File
@@ -1,195 +0,0 @@
# Talos node for the P330 — joins the r740 "kube" cluster.
terraform {
required_providers {
talos = {
source = "siderolabs/talos"
version = "0.9.0"
}
null = {
source = "hashicorp/null"
version = "3.2.3"
}
}
}
# Read the r740 kube module state to reuse the cluster secrets & endpoint.
# The r740 module exposes: client_configuration, machine_secrets, cluster_name,
# cluster_endpoint, kube_host.
data "terraform_remote_state" "r740_kube" {
backend = var.r740_backend
config = var.r740_backend == "local" ? {
path = "${var.r740_state_path}/terraform.tfstate"
} : var.r740_backend_config
}
locals {
cluster_name = data.terraform_remote_state.r740_kube.outputs.cluster_name
cluster_endpoint = data.terraform_remote_state.r740_kube.outputs.cluster_endpoint
machine_secrets = data.terraform_remote_state.r740_kube.outputs.machine_secrets
client_config = data.terraform_remote_state.r740_kube.outputs.client_configuration
# kubeconfig produced by the r740 kube module — used to wait for the node and
# apply labels/taints. There is no in-tree kubernetes provider here on
# purpose: managing a `kubernetes_node` resource conflicts with the node
# object that kubelet itself creates, so we use a null_resource with kubectl
# to wait + label + taint idempotently.
kubeconfig_path = "${var.r740_state_path}/kubeconfig"
# Network config: static if node_subnet is provided, otherwise Talos DHCPs.
static_network = var.node_subnet == null ? {} : {
interfaces = [{
interface = var.network_interface
addresses = [var.node_subnet]
routes = var.node_gateway == null ? [] : [{ gateway = var.node_gateway }]
}]
}
network_patch = {
nameservers = var.nameservers
}
network_patch_merged = merge(local.network_patch, local.static_network)
machine_patch = {
install = {
image = var.installer_image
disk = var.install_disk
}
network = merge(local.network_patch_merged, {
# Pin the Kubernetes node name. Talos otherwise auto-generates a hostname
# (e.g. "talos-8ec-vd1"), so the node registers with that random name
# instead of var.p330_node_name — and our label/taint null_resource waits
# for the wrong node. Setting machine.network.hostname fixes the node name.
hostname = var.p330_node_name
})
# Kernel modules required by Longhorn (iSCSI + ext4) — must match the
# control-plane nodes so Longhorn can schedule replicas on the failover node.
kernel = {
modules = [
{ name = "iscsi_tcp" },
{ name = "libiscsi" },
{ name = "scsi_transport_iscsi" },
{ name = "ext4" },
]
}
sysctls = {
"fs.inotify.max_user_instances" = "1024"
"fs.inotify.max_user_watches" = "1048576"
}
kubelet = {
# Keep the failover node from accumulating non-essential DaemonSet pods
# via the regular scheduler; the taint does the heavy lifting, this is
# belt-and-braces.
extraArgs = {
"register-with-taints" = "${var.failover_taint_key}=${var.failover_taint_value}:${var.failover_taint_effect}"
}
}
}
}
# Control-plane machine configuration. machine_type = "controlplane" makes
# Talos generate a join config that runs the apiserver/controller-manager/
# scheduler AND joins the existing etcd cluster as a new member (the cluster
# was already bootstrapped by the r740 module's talos_machine_bootstrap).
data "talos_machine_configuration" "p330" {
cluster_name = local.cluster_name
machine_type = "controlplane"
cluster_endpoint = local.cluster_endpoint
machine_secrets = local.machine_secrets
config_patches = [
yamlencode({
machine = local.machine_patch
})
]
}
# Rendered config is written to disk so it can also be applied manually with
# `talosctl apply-config --nodes <p330_host> --file p330.yaml` if needed.
resource "local_file" "p330_machine_config" {
filename = "${path.module}/p330.yaml"
content = data.talos_machine_configuration.p330.machine_configuration
}
# Apply the machine config to the running (maintenance-mode) node over the
# Talos API. Because the config patch contains a `machine.install` block, when
# Talos receives this config on a node booted from the USB (maintenance) image
# it installs itself to install.disk and reboots into the installed system.
# For a controlplane node it then joins the existing etcd cluster as a new
# member and runs the control-plane components; for a worker it just registers
# via kubelet.
resource "talos_machine_configuration_apply" "p330" {
client_configuration = local.client_config
machine_configuration_input = data.talos_machine_configuration.p330.machine_configuration
node = var.p330_host
depends_on = [local_file.p330_machine_config]
}
# Emit a talosconfig scoped to this node for ad-hoc `talosctl` use.
data "talos_client_configuration" "p330" {
cluster_name = local.cluster_name
client_configuration = local.client_config
nodes = [var.p330_host]
}
resource "local_file" "talosconfig" {
content = data.talos_client_configuration.p330.talos_config
filename = "${path.module}/talosconfig"
depends_on = [data.talos_client_configuration.p330]
}
# Wait for the node to register with Kubernetes (kubelet creates the Node
# object after Talos installs and reboots), then label it and (re)apply the
# failover taint. This is idempotent: kubectl exits 0 if the label/taint already
# exists. The taint is also set via kubelet `register-with-taints`, so this
# null_resource is a safety net for manual edits / drift.
resource "null_resource" "p330_node_label_and_taint" {
triggers = {
node = var.p330_node_name
key = var.failover_taint_key
value = var.failover_taint_value
effect = var.failover_taint_effect
kubeconfig = local.kubeconfig_path
}
provisioner "local-exec" {
# Wait for the node to show up, then label + taint. The wait loop is bounded
# by kubectl --timeout; tune it via TF_LOG / re-run if the node is slow to
# join (a controlplane node must first complete the etcd join handshake).
command = <<-EOT
set -euo pipefail
KUBECONFIG="${local.kubeconfig_path}"
export KUBECONFIG
NODE="${var.p330_node_name}"
echo "Waiting for node $NODE to be registered (kubelet creates the Node object once Talos has installed, rebooted and joined etcd)..."
# kubectl wait --for=condition=Ready fails instantly with NotFound if the
# node object doesn't exist yet, so poll for existence first.
# /bin/sh (dash) has no $SECONDS, so count iterations with a bounded loop.
tries=240 # 240 * 5s = 20 minutes max
until kubectl get node "$NODE" >/dev/null 2>&1; do
tries=$((tries - 1))
if [ "$tries" -le 0 ]; then
echo "Timed out waiting for node $NODE to register." >&2
exit 1
fi
sleep 5
done
echo "Node $NODE registered. Waiting for it to become Ready..."
# Now wait for Ready (a controlplane node needs etcd joined + apiserver up).
kubectl wait --for=condition=Ready "node/$NODE" --timeout=20m || \
kubectl wait --for=jsonpath='{.status.conditions[?(@.reason=="KubeletReady")].status}'=True "node/$NODE" --timeout=20m
# Failover marker + taint (applied to both controlplane and worker nodes).
kubectl label --overwrite node "$NODE" homeprod.io/failover=true
# Apply the taint idempotently (kubectl taint --overwrite is a no-op if it exists).
kubectl taint --overwrite node "$NODE" \
"${var.failover_taint_key}=${var.failover_taint_value}:${var.failover_taint_effect}"
echo "Node $NODE ready, labeled and tainted for failover-only scheduling."
EOT
}
depends_on = [talos_machine_configuration_apply.p330]
}
-118
View File
@@ -1,118 +0,0 @@
# Variables for the P330 Talos worker node that joins the r740 cluster.
variable "p330_host" {
description = "Reachable IP/hostname of the P330 Talos node (for Talos API access)."
type = string
}
variable "p330_node_name" {
description = "Kubernetes/Talos node name for the P330 (e.g. p330)."
type = string
default = "p330"
}
variable "r740_state_path" {
description = <<EOT
Path to the Terraform state of the r740 kube module, used by terraform_remote_state
to read the cluster secrets and endpoint so this node can join the existing cluster.
Path is resolved by terraform_remote_state relative to the working directory where
terraform runs (this module dir). The default points two levels up to the repo
root and back down to the r740 kube module.
EOT
type = string
default = "../../r740/kube"
}
variable "r740_backend" {
description = <<EOT
Terraform backend type used by the r740 kube module.
Set to "local" (default) when r740 uses a local tfstate file in its own directory,
or the matching remote backend name ("s3", "remote", ...) if the r740 module uses
a configured backend.
EOT
type = string
default = "local"
}
variable "r740_backend_config" {
description = <<EOT
Backend configuration map passed to terraform_remote_state when r740_backend is
not "local". For a local backend this is ignored.
EOT
type = map(string)
default = {}
}
variable "installer_image" {
description = <<EOT
Talos installer image to use on the P330 (bare metal).
Must be a **metal** Image Factory build that includes ixgbe.allow_unsupported_sfp=1
in the kernel command line (sd-boot/UKI ignores machine.install.extraKernelArgs, so
the param must be baked into the image). The default is a custom factory build
(a18165114...).
EOT
type = string
default = "factory.talos.dev/installer/a18165114f80c28601d05bc4ff1f6ea6d6b214882c5b9af7928aaf4d09741beb:v1.13.6"
}
variable "install_disk" {
description = "Block device path to install Talos on (e.g. /dev/sda, /dev/nvme0n1)."
type = string
default = "/dev/nvme0n1"
}
variable "node_subnet" {
description = <<EOT
Static IPv4 address in CIDR notation for the P330 node (e.g. 10.1.2.132/24).
Set to null to use DHCP. A static address is recommended for a failover node so
DNS/affinity rules stay stable.
EOT
type = string
default = "10.1.2.132/24"
}
variable "node_gateway" {
description = "IPv4 gateway for the P330 node. Ignored when node_subnet is null."
type = string
default = "10.1.2.1"
}
variable "network_interface" {
description = <<EOT
Primary network interface name on the P330. Defaults to enp3s0f1 (the 10G Intel
X520 NIC), which must be on the same L2/subnet as the r740 control plane so etcd
peer traffic (TLS-verified against the r740's etcd cert SANs) doesn't cross a
router. eno1 (1G) is left unconfigured.
EOT
type = string
default = "enp3s0f1"
}
variable "nameservers" {
description = "DNS nameservers configured on the node (must work independently of kube)."
type = list(string)
default = ["10.1.2.148", "1.1.1.1"]
}
variable "failover_taint_key" {
description = "Taint key applied to the node to reserve it for failover workloads."
type = string
default = "dedicated"
}
variable "failover_taint_value" {
description = "Taint value applied to the node."
type = string
default = "failover"
}
variable "failover_taint_effect" {
description = "Taint effect applied to the node (NoSchedule / NoExecute)."
type = string
default = "NoSchedule"
validation {
condition = contains(["NoSchedule", "PreferNoSchedule", "NoExecute"], var.failover_taint_effect)
error_message = "failover_taint_effect must be NoSchedule, PreferNoSchedule or NoExecute."
}
}
@@ -1,15 +1,19 @@
/*
* Docker machine terraform file
*/
resource "proxmox_virtual_environment_download_file" "debian-latest-cloudimg" { resource "proxmox_virtual_environment_download_file" "debian-latest-cloudimg" {
content_type = "iso" content_type = "iso"
datastore_id = "local" datastore_id = "local"
file_name = "debian-13-generic-amd64.qcow2.img" file_name = "debian-12-generic-amd64.qcow2.img"
node_name = var.proxmox_node_name node_name = "pve"
url = "https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2" url = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
} }
resource "proxmox_virtual_environment_file" "docker-machine-cloud-config" { resource "proxmox_virtual_environment_file" "docker-machine-cloud-config" {
content_type = "snippets" content_type = "snippets"
datastore_id = "local" datastore_id = "local"
node_name = var.proxmox_node_name node_name = "pve"
source_raw { source_raw {
data = <<-EOF data = <<-EOF
@@ -24,7 +28,6 @@ resource "proxmox_virtual_environment_file" "docker-machine-cloud-config" {
- qemu-guest-agent - qemu-guest-agent
- nfs-common - nfs-common
runcmd: runcmd:
- systemctl mask tmp.mount
- systemctl enable --now qemu-guest-agent - systemctl enable --now qemu-guest-agent
- install -m 0755 -d /etc/apt/keyrings - install -m 0755 -d /etc/apt/keyrings
- curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc - curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
@@ -37,14 +40,15 @@ resource "proxmox_virtual_environment_file" "docker-machine-cloud-config" {
- mkdir /app - mkdir /app
- echo "truenas.lan:/mnt/fast_app_data/docker-homeprod /app nfs defaults,_netdev 0 0" >>/etc/fstab - echo "truenas.lan:/mnt/fast_app_data/docker-homeprod /app nfs defaults,_netdev 0 0" >>/etc/fstab
- mount -t nfs truenas.lan:/mnt/fast_app_data/docker-homeprod /app - mount -t nfs truenas.lan:/mnt/fast_app_data/docker-homeprod /app
- echo "${var.sops_private_key}" | gpg --import
EOF EOF
file_name = "docker-machine-cloud-config.yaml" file_name = "docker-machine-cloud-config.yaml"
} }
} }
resource "proxmox_virtual_environment_vm" "docker-machine" { resource "proxmox_virtual_environment_vm" "docker-machine" {
name = "docker-${var.proxmox_node_name}" name = "docker-machine"
node_name = var.proxmox_node_name node_name = "pve"
on_boot = true on_boot = true
agent { agent {
@@ -55,14 +59,13 @@ resource "proxmox_virtual_environment_vm" "docker-machine" {
cpu { cpu {
type = "host" type = "host"
cores = 20 cores = 4
sockets = 1 sockets = 1
flags = [] flags = []
} }
memory { memory {
floating = 32000 dedicated = 16192
dedicated = 38768
} }
network_device { network_device {
@@ -108,7 +111,7 @@ resource "proxmox_virtual_environment_vm" "docker-machine" {
ip_config { ip_config {
ipv4 { ipv4 {
address = "10.1.2.212/24" address = "10.1.2.175/24"
gateway = "10.1.2.1" gateway = "10.1.2.1"
} }
} }
@@ -9,14 +9,11 @@ terraform {
# Docker configuration # Docker configuration
provider "docker" { provider "docker" {
host = "ssh://root@${var.docker_host}" host = "ssh://root@docker-machine.lan"
} }
resource "docker_image" "swarm-cd" { resource "docker_image" "swarm-cd" {
name = "swarm-cd:latest" name = "ghcr.io/m-adawi/swarm-cd:latest"
# For now, custom-built image based on custom development branch
# Once this reaches upstream, back to upstream tag, like:
# ghcr.io/m-adawi/swarm-cd:1.9.0
} }
resource "docker_container" "swarm-cd" { resource "docker_container" "swarm-cd" {
@@ -37,13 +34,6 @@ resource "docker_container" "swarm-cd" {
container_path = "/app/stacks.yaml" container_path = "/app/stacks.yaml"
read_only = true read_only = true
} }
volumes {
host_path = "/app/swarm-cd/data"
container_path = "/data"
}
env = [
"SOPS_GPG_PRIVATE_KEY=${var.sops_private_key}"
]
depends_on = [ docker_image.swarm-cd ] depends_on = [ docker_image.swarm-cd ]
} }
+116 -100
View File
@@ -1,93 +1,130 @@
terraform { /*
required_providers { * Kubernetes cluster terraform file
talos = { */
source = "siderolabs/talos"
version = "0.9.0" resource "proxmox_virtual_environment_download_file" "talos-cloudimg" {
} content_type = "iso"
kubernetes = { datastore_id = "local"
source = "hashicorp/kubernetes" file_name = "talos-v1.11.1-nocloud-amd64.iso"
version = "2.36.0" node_name = "pve"
} url = "https://factory.talos.dev/image/ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515/v1.11.1/nocloud-amd64.iso"
helm = {
source = "hashicorp/helm"
version = "2.17.0"
}
}
} }
# Talos configuration resource "proxmox_virtual_environment_vm" "kube" {
provider "talos" {} name = "kube-talos"
description = "Kubernetes Talos Linux"
tags = ["kubernetes", "talos", "terraform"]
# Kubernetes configuration node_name = "pve"
provider "kubernetes" { vm_id = 703
config_path = "${path.module}/kubeconfig" machine = "q35"
} keyboard_layout = "fr"
# Helm configuration
provider "helm" { agent {
kubernetes { enabled = true
config_path = "${path.module}/kubeconfig"
} }
stop_on_destroy = true
cpu {
cores = 4
type = "x86-64-v3"
}
memory {
dedicated = 16192
floating = 16192
}
boot_order = ["scsi0", "ide0"]
scsi_hardware = "virtio-scsi-single"
cdrom {
file_id = proxmox_virtual_environment_download_file.talos-cloudimg.id
interface = "ide0"
}
disk {
interface = "scsi0"
iothread = true
datastore_id = "local-lvm"
size = 128
discard = "ignore"
file_format = "raw"
}
vga {
type = "serial0"
}
initialization {
datastore_id = "local-lvm"
interface = "ide2"
ip_config {
ipv4 {
address = "10.1.2.187/24"
gateway = "10.1.2.1"
}
}
user_account {
keys = [trimspace(var.ssh_public_key)]
password = var.machine_root_password
username = "root"
}
}
lifecycle {
ignore_changes = [
ipv4_addresses, ipv6_addresses, network_interface_names
]
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = 2
}
operating_system {
type = "l26"
}
tpm_state {
version = "v2.0"
}
serial_device {}
} }
resource "talos_machine_secrets" "kube" {} resource "talos_machine_secrets" "kube" {}
data "talos_machine_configuration" "kube" { data "talos_machine_configuration" "kube" {
cluster_name = "kube-${var.physical_hostname}" cluster_name = "kube"
machine_type = "controlplane" machine_type = "controlplane"
cluster_endpoint = "https://${var.kube_host}:6443" cluster_endpoint = "https://kube-talos.lan:6443"
machine_secrets = talos_machine_secrets.kube.machine_secrets machine_secrets = talos_machine_secrets.kube.machine_secrets
config_patches = [ config_patches = [
yamlencode({ yamlencode({
machine = { machine = {
install = { install = {
# Image Factory image with iSCSI extension for Longhorn. image = "factory.talos.dev/installer/ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515:v1.11.1"
# Generated at https://factory.talos.dev siderolabs/iscsi-tools + qemu-guest-agent
image = "factory.talos.dev/installer/dc7b152cb3ea99b821fcb7340ce7168313ce393d663740b791c36f6e95fc8586:v1.13.6"
} }
network = { network = {
nameservers = [ nameservers = [
# We need a set of nameservers that can work independently of kube "10.1.2.3"
# to bootstrap.
"10.1.2.148",
"1.1.1.1"
] ]
} }
certSANs = [
"${var.kube_host}", "${var.kube_hostname}"
]
# Kernel modules required by Longhorn (iSCSI + ext4)
kernel = {
modules = [
{
name = "iscsi_tcp"
},
{
name = "libiscsi"
},
{
name = "scsi_transport_iscsi"
},
{
name = "ext4"
},
]
}
# Sysctls for Longhorn
sysctls = {
"fs.inotify.max_user_instances" = "1024"
"fs.inotify.max_user_watches" = "1048576"
}
} }
cluster = { cluster = {
clusterName = "kube-${var.physical_hostname}"
allowSchedulingOnControlPlanes = true allowSchedulingOnControlPlanes = true
apiServer = { apiServer = {
certSANs = [ certSANs = [
"${var.kube_host}", "${var.kube_hostname}" "kube-talos.lan"
] ]
} }
network = { network = {
dnsDomain = "cluster.local" dnsDomain = "kube-talos.lan"
cni = { cni = {
name: "none" name: "none"
} }
@@ -101,26 +138,32 @@ data "talos_machine_configuration" "kube" {
} }
data "talos_client_configuration" "kube" { data "talos_client_configuration" "kube" {
cluster_name = "kube-${var.physical_hostname}" cluster_name = "kube"
client_configuration = talos_machine_secrets.kube.client_configuration client_configuration = talos_machine_secrets.kube.client_configuration
nodes = ["${var.kube_host}"] nodes = ["kube-talos"]
} }
resource "talos_machine_configuration_apply" "kube" { resource "talos_machine_configuration_apply" "kube" {
client_configuration = talos_machine_secrets.kube.client_configuration client_configuration = talos_machine_secrets.kube.client_configuration
machine_configuration_input = data.talos_machine_configuration.kube.machine_configuration machine_configuration_input = data.talos_machine_configuration.kube.machine_configuration
node = var.kube_host node = "10.1.2.187" #proxmox_virtual_environment_vm.kube.ipv4_addresses[7][0] # lo + 6 talos-created interfaces before eth0
depends_on = [ talos_machine_secrets.kube ] depends_on = [ proxmox_virtual_environment_vm.kube ]
lifecycle {
replace_triggered_by = [ proxmox_virtual_environment_vm.kube ]
}
} }
resource "talos_machine_bootstrap" "kube" { resource "talos_machine_bootstrap" "kube" {
node = var.kube_host node = "10.1.2.187" #proxmox_virtual_environment_vm.kube.ipv4_addresses[7][0] # lo + 6 talos-created interfaces before eth0
client_configuration = talos_machine_secrets.kube.client_configuration client_configuration = talos_machine_secrets.kube.client_configuration
depends_on = [ talos_machine_configuration_apply.kube, talos_machine_secrets.kube ] depends_on = [ talos_machine_configuration_apply.kube ]
lifecycle {
replace_triggered_by = [ proxmox_virtual_environment_vm.kube ]
}
} }
resource "talos_cluster_kubeconfig" "kube" { resource "talos_cluster_kubeconfig" "kube" {
node = var.kube_host node = proxmox_virtual_environment_vm.kube.ipv4_addresses[7][0] # lo + 6 talos-created interfaces before eth0
depends_on = [ talos_machine_bootstrap.kube ] depends_on = [ talos_machine_bootstrap.kube ]
client_configuration = talos_machine_secrets.kube.client_configuration client_configuration = talos_machine_secrets.kube.client_configuration
} }
@@ -130,33 +173,6 @@ output "kubeconfig" {
value = talos_cluster_kubeconfig.kube.kubeconfig_raw value = talos_cluster_kubeconfig.kube.kubeconfig_raw
} }
output "client_configuration" {
description = "Talos client configuration (sensitive) used to manage nodes."
sensitive = true
value = talos_machine_secrets.kube.client_configuration
}
output "machine_secrets" {
description = "Talos machine secrets (sensitive) used to generate node configs."
sensitive = true
value = talos_machine_secrets.kube.machine_secrets
}
output "cluster_name" {
description = "Name of the Talos cluster the worker joins."
value = "kube-${var.physical_hostname}"
}
output "cluster_endpoint" {
description = "Endpoint (host:port) of the Talos/Kubernetes API on the cluster."
value = "https://${var.kube_host}:6443"
}
output "kube_host" {
description = "Reachable IP/hostname of the control-plane node."
value = var.kube_host
}
resource "local_file" "kubeconfig" { resource "local_file" "kubeconfig" {
content = "${talos_cluster_kubeconfig.kube.kubeconfig_raw}" content = "${talos_cluster_kubeconfig.kube.kubeconfig_raw}"
filename = "${path.module}/kubeconfig" filename = "${path.module}/kubeconfig"
@@ -164,9 +180,9 @@ resource "local_file" "kubeconfig" {
} }
data "talos_client_configuration" "talosconfig" { data "talos_client_configuration" "talosconfig" {
cluster_name = "kube-${var.physical_hostname}" cluster_name = "homeprod"
client_configuration = talos_machine_secrets.kube.client_configuration client_configuration = talos_machine_secrets.kube.client_configuration
nodes = [var.kube_host] nodes = [proxmox_virtual_environment_vm.kube.ipv4_addresses[7][0]]
} }
resource "local_file" "talosconfig" { resource "local_file" "talosconfig" {
@@ -182,7 +198,7 @@ resource "helm_release" "cilium" {
repository = "https://helm.cilium.io/" repository = "https://helm.cilium.io/"
chart = "cilium" chart = "cilium"
wait = false wait = false
depends_on = [ local_file.kubeconfig, talos_cluster_kubeconfig.kube ] depends_on = [ local_file.kubeconfig ]
set { set {
name = "ipam.mode" name = "ipam.mode"
@@ -218,7 +234,7 @@ resource "helm_release" "cilium" {
} }
set { set {
name = "etcd.clusterDomain" name = "etcd.clusterDomain"
value = "cluster.local" value = "kube-talos.lan"
} }
set { set {
name = "hubble.relay.enabled" name = "hubble.relay.enabled"
+46
View File
@@ -0,0 +1,46 @@
# Terraform providers configuration
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.83.2"
}
talos = {
source = "siderolabs/talos"
version = "0.9.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.38.0"
}
helm = {
source = "hashicorp/helm"
version = "2.17.0"
}
}
}
# Proxmox configuration
provider "proxmox" {
endpoint = "https://pve.lan:8006/"
api_token = var.api_token
insecure = true
ssh {
agent = true
username = "root"
}
}
# Talos configuration
provider "talos" {}
# Kubernetes configuration
provider "kubernetes" {
config_path = "${path.module}/kubeconfig"
}
# Helm configuration
provider "helm" {
kubernetes {
config_path = "${path.module}/kubeconfig"
}
}
@@ -10,7 +10,7 @@ instance:
type: kubernetes type: kubernetes
multitenant: false multitenant: false
networkPolicy: true networkPolicy: true
domain: "cluster.local" domain: "kube-talos.lan"
kustomize: kustomize:
patches: patches:
- target: - target:
+19
View File
@@ -0,0 +1,19 @@
variable "api_token" {
description = "Token to connect Proxmox API"
type = string
}
variable "machine_root_password" {
description = "Root password for VMs and containers"
type = string
}
variable "ssh_public_key" {
description = "Public SSH key authorized access for VMs and containers"
type = string
}
variable "sops_private_key" {
description = "Private SOPS GPG key for flux/kubernetes to decrypt secrets"
type = string
}
-8
View File
@@ -1,8 +0,0 @@
variable "sops_private_key" {
description = "Private SOPS GPG key for SwarmCD to decrypt secrets"
type = string
}
variable "docker_host" {
description = "Docker machine hostname"
type = string
}
-16
View File
@@ -1,16 +0,0 @@
variable "sops_private_key" {
description = "Private SOPS GPG key for flux/kubernetes to decrypt secrets"
type = string
}
variable "kube_hostname" {
description = "Kubernetes cluster hostname"
type = string
}
variable "kube_host" {
description = "Kubernetes cluster host"
type = string
}
variable "physical_hostname" {
description = "Host name of the physical host for the kubernetes VM"
type = string
}
-139
View File
@@ -1,139 +0,0 @@
resource "proxmox_virtual_environment_download_file" "ubuntu-latest-cloudimg" {
content_type = "iso"
datastore_id = "local"
file_name = "noble-server-cloudimg-amd64.img"
node_name = var.proxmox_node_name
url = "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
}
resource "proxmox_virtual_environment_file" "ai-cloud-config" {
content_type = "snippets"
datastore_id = "local"
node_name = var.proxmox_node_name
source_raw {
data = <<-EOF
#cloud-config
package_update: true
packages:
- git
- ca-certificates
- wget
- curl
- gnupg2
- qemu-guest-agent
runcmd:
- systemctl enable --now qemu-guest-agent
- install -m 0755 -d /etc/apt/keyrings
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
- chmod a+r /etc/apt/keyrings/docker.asc
- echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- apt-get update
- apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- apt install ubuntu-drivers-common
- ubuntu-drivers install --gpgpu
- curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
- curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
- apt-get update
- export NVIDIA_CONTAINER_TOOLKIT_VERSION=1.17.8-1
- apt-get install -y nvidia-container-toolkit=$NVIDIA_CONTAINER_TOOLKIT_VERSION nvidia-container-toolkit-base=$NVIDIA_CONTAINER_TOOLKIT_VERSION libnvidia-container-tools=$NVIDIA_CONTAINER_TOOLKIT_VERSION libnvidia-container1=$NVIDIA_CONTAINER_TOOLKIT_VERSION
- nvidia-ctk runtime configure --runtime=docker
- systemctl restart docker
EOF
file_name = "ai-cloud-config.yaml"
}
}
resource "proxmox_virtual_environment_vm" "ai" {
name = "ai-${var.proxmox_node_name}"
node_name = var.proxmox_node_name
on_boot = false
started = false
agent {
enabled = true
}
tags = ["ubuntu", "ubuntu-latest", "docker", "terraform", "gpu", "ai"]
cpu {
type = "host"
cores = 20
sockets = 1
flags = []
}
memory {
dedicated = 64536
floating = 16192
}
network_device {
bridge = "vmbr0"
model = "virtio"
# mac_address = "BC:24:11:E2:F5:5B"
vlan_id = 2
}
lifecycle {
ignore_changes = [
network_interface_names,
mac_addresses,
ipv4_addresses,
ipv6_addresses,
id,
disk,
initialization,
vga,
hostpci
]
}
boot_order = ["scsi0"]
scsi_hardware = "virtio-scsi-single"
vga {
type = "serial0"
}
disk {
interface = "scsi0"
iothread = true
datastore_id = "local-lvm"
size = 330
discard = "ignore"
file_id = proxmox_virtual_environment_download_file.ubuntu-latest-cloudimg.id
}
vm_id = 101
initialization {
datastore_id = "local-lvm"
interface = "ide2"
ip_config {
ipv4 {
address = "dhcp"
}
}
user_account {
keys = [trimspace(var.ssh_public_key)]
password = var.machine_root_password
username = "root"
}
vendor_data_file_id = proxmox_virtual_environment_file.ai-cloud-config.id
}
operating_system {
type = "l26"
}
tpm_state {
version = "v2.0"
}
serial_device {}
}
-133
View File
@@ -1,133 +0,0 @@
resource "proxmox_virtual_environment_download_file" "ubuntu-questing-cloudimg" {
content_type = "iso"
datastore_id = "local"
file_name = "questing-server-cloudimg-amd64.img"
node_name = var.proxmox_node_name
url = "https://cloud-images.ubuntu.com/questing/current/questing-server-cloudimg-amd64.img"
}
resource "proxmox_virtual_environment_file" "build-latest-cloud-config" {
content_type = "snippets"
datastore_id = "local"
node_name = var.proxmox_node_name
source_raw {
data = <<-EOF
#cloud-config
package_update: true
packages:
- git
- ca-certificates
- wget
- curl
- gnupg2
- qemu-guest-agent
- build-essential
- sbuild
- mmdebstrap
- qemu-user-binfmt
- ubuntu-dev-tools
- micro
runcmd:
- systemctl enable --now qemu-guest-agent
- snap install lxd
- lxd init --auto
- snap install snapcraft --classic
- usermod --add-subuids 100000-165535 --add-subgids 100000-165535 root
- mkdir -p /root/.config/sbuild/
- mkdir -p /root/.cache/sbuild/
- echo -e "\$chroot_mode = 'unshare';\n\$unshare_mmdebstrap_keep_tarball = 1;\n1;\n" >/root/.config/sbuild/config.pl
EOF
file_name = "build-latest-cloud-config.yaml"
}
}
resource "proxmox_virtual_environment_vm" "build-latest" {
name = "bw-${var.proxmox_node_name}"
node_name = var.proxmox_node_name
on_boot = true
agent {
enabled = true
}
tags = ["ubuntu", "ubuntu-questing", "docker", "terraform", "build"]
cpu {
type = "host"
cores = 20
sockets = 1
flags = []
}
memory {
dedicated = 64536
floating = 16192
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = 2
}
lifecycle {
ignore_changes = [
network_interface_names,
mac_addresses,
ipv4_addresses,
ipv6_addresses,
id,
disk,
initialization,
vga
]
}
boot_order = ["scsi0"]
scsi_hardware = "virtio-scsi-single"
vga {
type = "serial0"
}
disk {
interface = "scsi0"
iothread = true
datastore_id = "local-lvm"
size = 330
discard = "ignore"
file_id = proxmox_virtual_environment_download_file.ubuntu-questing-cloudimg.id
}
vm_id = 201
initialization {
datastore_id = "local-lvm"
interface = "ide2"
ip_config {
ipv4 {
address = "dhcp"
}
}
user_account {
keys = [trimspace(var.ssh_public_key), trimspace(var.ssh_secondary_key)]
password = var.machine_root_password
username = "root"
}
vendor_data_file_id = proxmox_virtual_environment_file.build-latest-cloud-config.id
}
operating_system {
type = "l26"
}
tpm_state {
version = "v2.0"
}
serial_device {}
}
-113
View File
@@ -1,113 +0,0 @@
resource "proxmox_virtual_environment_download_file" "talos-cloudimg" {
content_type = "iso"
datastore_id = "local"
file_name = "talos-v1.13.6-nocloud-amd64.iso"
node_name = var.proxmox_node_name
url = "https://factory.talos.dev/image/5a697fd6e91537a2c9c45929d004d82af180bb5d4e989dd8494e25fedca005bd/v1.13.6/nocloud-amd64.iso"
}
resource "proxmox_virtual_environment_vm" "kube" {
name = "kube-${var.proxmox_node_name}"
description = "Kubernetes Talos Linux"
tags = ["kubernetes", "talos", "terraform"]
node_name = var.proxmox_node_name
vm_id = 702
machine = "q35"
keyboard_layout = "fr"
agent {
enabled = true
}
stop_on_destroy = true
cpu {
cores = 20
sockets = 1
type = "host"
}
memory {
dedicated = 32768
floating = 22222
}
boot_order = ["scsi0", "ide0"]
scsi_hardware = "virtio-scsi-single"
cdrom {
file_id = proxmox_virtual_environment_download_file.talos-cloudimg.id
interface = "ide0"
}
disk {
interface = "scsi0"
iothread = true
datastore_id = "local-lvm"
size = 128
discard = "ignore"
file_format = "raw"
}
vga {
type = "serial0"
}
initialization {
datastore_id = "local-lvm"
interface = "ide2"
ip_config {
ipv4 {
address = "dhcp"
}
}
user_account {
keys = [trimspace(var.ssh_public_key)]
password = var.machine_root_password
username = "root"
}
}
lifecycle {
ignore_changes = [
ipv4_addresses, ipv6_addresses, network_interface_names
]
}
network_device {
bridge = "vmbr0"
model = "virtio"
# mac_address = "BC:24:11:F6:E1:C9"
vlan_id = 2
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = 2
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = 2
}
network_device {
bridge = "vmbr0"
model = "virtio"
vlan_id = 2
}
operating_system {
type = "l26"
}
tpm_state {
version = "v2.0"
}
serial_device {}
}
-18
View File
@@ -1,18 +0,0 @@
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.81.0"
}
}
}
provider "proxmox" {
endpoint = "https://${var.proxmox_host}:8006/"
api_token = var.proxmox_api_token
insecure = true
ssh {
agent = true
username = "root"
}
}
-29
View File
@@ -1,29 +0,0 @@
variable "proxmox_host" {
description = "Hostname of Proxmox server"
type = string
}
variable "proxmox_node_name" {
description = "Name of Proxmox node to use"
type = string
}
variable "proxmox_api_token" {
description = "Token to connect Proxmox API"
type = string
}
variable "machine_root_password" {
description = "Root password for VMs and containers"
type = string
}
variable "ssh_public_key" {
description = "Public SSH key authorized access for VMs and containers"
type = string
}
variable "ssh_secondary_key" {
description = "Secondary SSH key for authorized access to specific VMs and containers"
type = string
}
-1
View File
@@ -12,7 +12,6 @@ spec:
name: gitea name: gitea
namespace: gitea namespace: gitea
chart: gitea chart: gitea
version: '12.6.0'
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
+26 -126
View File
@@ -1,5 +1,5 @@
image: image:
tag: 1.26.2 tag: 1.24.3
ingress: ingress:
enabled: true enabled: true
hosts: hosts:
@@ -10,89 +10,19 @@ ingress:
# Disable HA, we are on a 1-node cluster # Disable HA, we are on a 1-node cluster
redis-cluster: redis-cluster:
enabled: false enabled: false
# Valkey cluster is the new default in chart 12.x - must be explicitly disabled redis:
valkey-cluster:
enabled: false
# Use standalone Valkey (replaces 'redis' in chart 12.x)
valkey:
enabled: true enabled: true
master:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
tolerations:
- key: ENC[AES256_GCM,data:o/sXxge7tAi4,iv:4at3gD2SjyjA1r1eVYE3bi0xEzFkwxKgJRJGagfzDjA=,tag:OxOcClpHU/Z3sSiMHikOsA==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:5FY3Hmqh8Uw=,iv:8LGdTpFovI9lsfAaf65dHdJnNsm17ahm2/x+97LiTgA=,tag:b07oTtzzfU4FFjm9W+iz9A==,type:str]
effect: NoSchedule
- key: ENC[AES256_GCM,data:FPkNzrFpfqQI7h1D346c72Og0B2y5w+z5m25trSt4kIEjxJ4RA==,iv:Xjl+xrXs5m28siBqNXTTmtLKEiTxnLZAzvFXEXH8ZcM=,tag:VQoot4mURGhCmy+MSjr4BA==,type:str]
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: ENC[AES256_GCM,data:O4Wtr+1YuNGmYknT35XPONTeqUk=,iv:VqTkPwG4bxvRgXDGrmpwVeT2zLQzOLrwKlhqYCv/GiA=,tag:2pntJGKlUF8cBKgKpyySHQ==,type:str]
operator: NotIn
values:
- "true"
postgresql: postgresql:
enabled: true enabled: true
global: global:
postgresql: postgresql:
auth: auth:
postgressPassword: ENC[AES256_GCM,data:/vgY7Q154znmpg==,iv:GqwNyccbeCSm/b+7PufHcoSrsrrIR3FVgRAI0WxrHow=,tag:o/kkueEMtJUVLeARdy5zpQ==,type:str] postgressPassword: ENC[AES256_GCM,data:VUX2PSBXjfVXAQ==,iv:EokbkSVOl89e6mtIt2F2EnPTcdbSlxMccJ+AYkwz4CA=,tag:N0qeu/PKO5kdyiXIQufkMQ==,type:str]
password: ENC[AES256_GCM,data:gc4Ev4kn9KaSqw==,iv:Bd/qGIaobKewB/rtJf426pzS4qPe/WAMi2AB7T7HtCE=,tag:XlDtRF1tWv+9YmTo1H/Lvw==,type:str] password: ENC[AES256_GCM,data:QU81CjR0T2EJuw==,iv:GV+2aLlO9q0f+6ydXgW8DEWjYs/MbYl3C/pslCHUfZM=,tag:IrC50vQyUc3KZhM6+A89wg==,type:str]
database: gitea database: gitea
username: ENC[AES256_GCM,data:6mlFP+E=,iv:+QEgLA6reecmpvvtmdOnwkpqOa7fOV06ZS8VTDQo7MY=,tag:dREH7uvHk8ZS6HcA7Vo0zw==,type:str] username: ENC[AES256_GCM,data:EhkRSB8=,iv:4bQZYn0WwOTfL0mA5hzENSzq49GBFMbYeYyx5ofcoVM=,tag:0pb3hrwfuWV8JSlM26tiSA==,type:str]
volumePermissions: volumePermissions:
enabled: true enabled: true
primary:
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
tolerations:
- key: ENC[AES256_GCM,data:xd4ugBSV+lcC,iv:3dUqomveQf0/rMwOrlNnTk1mJoF5sW2RQ+UrPLlczkI=,tag:16IzYY0mqB8LlwRGXxUy8w==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:rK9ACxsGlEk=,iv:afDm0KWC0HAHw4AJnlpPw5oGcfEe3oG+RgiRCTpjb7g=,tag:sDOIWCiqxi04YYxalZ6DbQ==,type:str]
effect: NoSchedule
- key: ENC[AES256_GCM,data:83c8V9jJ+d5zpFFFhbo//O/opfgAKNpoqcsRw8W9oGbTu9pBMg==,iv:uw+6IhfkixBxBo7Gs2VSvW+q+JpW35rE9REkb6SQDTc=,tag:donRKnK6NbgBKhDgEOR0Eg==,type:str]
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: ENC[AES256_GCM,data:UKDLBJ1yfJ2gcyu/Ms3jVnBTfDE=,iv:fK73/46Jh3nfPMnWmMHr+SK3k3l16IsT9Ah45+yCz0w=,tag:A+PvsR9YpWwHrVpHOYXMGQ==,type:str]
operator: NotIn
values:
- "true"
livenessProbe:
enabled: true
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
successThreshold: 1
failureThreshold: 10
readinessProbe:
enabled: true
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 10
successThreshold: 1
failureThreshold: 6
postgresql-ha: postgresql-ha:
enabled: false enabled: false
persistence: persistence:
@@ -102,17 +32,17 @@ extraVolumes:
- name: git - name: git
nfs: nfs:
server: truenas.lan server: truenas.lan
path: /mnt/fast_app_data/git path: /mnt/main_storage/git
extraContainerVolumeMounts: extraContainerVolumeMounts:
- name: git - name: git
mountPath: /git mountPath: /git
clusterDomain: cluster.local clusterDomain: kube-talos.lan
gitea: gitea:
oauth: oauth:
- name: Authentik - name: Authentik
provider: openidConnect provider: openidConnect
key: ENC[AES256_GCM,data:ctukTzFfQAZSAIaXonIu6nVsTHnTNAlqObVhGkKt/aLa9o3KxDHdBw==,iv:QoudL4RRdwpPfz6h6MWoaBOztALRa8PEi5fRFkjFzQ8=,tag:+TgP8KrYQNCBmTaqscOn8Q==,type:str] key: ENC[AES256_GCM,data:izCBYkFigzgaZaERrTulvtxTRhGlvmglOOp6myaFg+4YKZIUls141Q==,iv:MOu0KNyCYqzwK4aghIJLfxpp6YNjhrfN/MTvlWj+dfQ=,tag:bLe9P1og6xuxLqA6d4fSfg==,type:str]
secret: ENC[AES256_GCM,data:mxNRVXfX0X777xh5bB7PwMEeaxRPszmvmpoQt2lMtvkTSIQMJOllzY27PAShJ/y6JBPRslg6us9TpKd3zt5KcVY4Jne3hkpkQCKqE8HN3XnjHDHDzAm4ugYib5J97BeLw9pvdurLxw5iXAp3XFxMytzU4xCrYPsS61FWJRTLFRg=,iv:NCGMyWJT575CGnnFM4mcLDxsoMkggsxiNkXNp/aU0es=,tag:5uudyC1IIxorgepR7HnPMA==,type:str] secret: ENC[AES256_GCM,data:DG6WH1asGPcK87IjyqoGau/JRL6A1Uu2Q+xq9XxMa0betH4yTiT68IW3f95TxPQo7NL9bEpiOKgX4qfHFu80+Qah65l5YC67OC+bnnUy4KVZ46drFWrDZMZbKPlDuSiZEav+ABszH9cc6HAoDg8LKmwtpM7TfWNbfpmYyv6iPCs=,iv:gPlM4Ol7KFVU1snuanuA7iib4AQH2+nKT2sX2h9JXlI=,tag:sddwFIZjVik+ojl2BI5o7g==,type:str]
autoDiscoverUrl: https://authentik.vhaudiquet.fr/application/o/gitea/.well-known/openid-configuration autoDiscoverUrl: https://authentik.vhaudiquet.fr/application/o/gitea/.well-known/openid-configuration
config: config:
APP_NAME: Gitea APP_NAME: Gitea
@@ -138,58 +68,28 @@ gitea:
indexer: indexer:
ISSUE_INDEXER_TYPE: bleve ISSUE_INDEXER_TYPE: bleve
REPO_INDEXER_ENABLED: true REPO_INDEXER_ENABLED: true
# Resource limits for Gitea container
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
# Increase replica count is not useful for 1-node cluster
replicaCount: 1
# Failover tolerations + affinity — allow scheduling on p330 during r740 outage
tolerations:
- key: ENC[AES256_GCM,data:RBMIdZLIV79D,iv:TTa1CovTGm91r/lYCKOKjnhM+i9hoLVsmDi2kmki9c4=,tag:zuhnRKxy3dtkYJr3TuLilw==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:LLOg34s1mrw=,iv:rjOyHPWBGrpNl1YGi2cYN6JRm7m28HiRibQoK0JZ3CE=,tag:oSyz0nISr3plqdXQ5UJxzw==,type:str]
effect: NoSchedule
- key: ENC[AES256_GCM,data:jVh0MTlCs7rVPSYvulsw8bIGwYPw5soaOzMlzVzVbFy13qqKLA==,iv:JfZ+JWxHBiTD/rG8xHYKogkyryNQIUIXyf9chxpwlEo=,tag:hwlZ+k1L0uPe+UGBOeMlYg==,type:str]
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: ENC[AES256_GCM,data:Sn7FuYqGMbTjx/EpqRIDx5GofR8=,iv:Wkyz+RmyTGswohAZmyeQ1lWT8hTaYw7qAVmXTnSIT7c=,tag:WAiU90Wo8Av0TsdMtyPF9w==,type:str]
operator: NotIn
values:
- "true"
# (postgresql and valkey tolerations are set in their respective blocks above)
sops: sops:
lastmodified: "2026-07-25T12:44:33Z" lastmodified: "2025-09-15T21:48:05Z"
mac: ENC[AES256_GCM,data:V9ZOpVvIi9PzScyasqQJb0yZDrqQ0RSXGyAY1+WaHCIa4/YRKn9d9V4wy+CwWaeEiIO7+fkp2ROInl7eVmETm5JppQ899G33GTmHCZLcBvVR2M4xEkx8eXy3saKCbC2DN4bHRuSCvvqw2XR+QIdemLL7ETuRo2cepUMhz/93peY=,iv:3wm/iCVfAYUUa7VfBXsx200LypYYWgJYCEm5X5Wwsnk=,tag:OzGw1PQUuVRVtQ5slH3E0Q==,type:str] mac: ENC[AES256_GCM,data:T5Ub0m8vGt+5AbJ8UiQlYLr7nLLodiPUlvdiCM9AD19YdKwiTiKmZVMTEW9rompVbPoHLArzb/reqmQ2D2D5CMNs8SgOfWiLD4/Y3qmnnxjwJi/0c6RNGmkTipYYwYu7gLVoL6GgQoNZmpr29MwNTEzCPN781XqMnxhxKtp18+A=,iv:6/t/i7a4Qr6/JDiNz9IPzaKSYZBWT8mxPB3Nnd/w9CI=,tag:l7NS89WXa8h33siY7UNTvw==,type:str]
pgp: pgp:
- created_at: "2026-07-25T12:44:32Z" - created_at: "2025-09-15T21:48:05Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//RIr73tcloQQg2OqSLn7W1DI6T1dYCh+ntTP3Y8KeB1WC hQIMA7uy4qQr71wiAQ//ZYp2oZsd950lEsQEYF8twms5kD+IwszzVFi71sGrdvTB
hZy2JOdTwHLkd9MiDimgjH0E1036+Pta9xhmoi9lnY3cvwOH/1oHxjd6ixhPxYzV 3Hi3bzDDc57PcP6lzxs0wA4LaIkAVkK290nYofhxNk6r4sbX7Imqni6ECYhw1Tik
Xt38fQ3BkFvf3fHbhcbzpMIFL8tfvuVDAxRV1fHHOdCGgXqeC5GP0KtDGmnddHui XkxfR8KIlZrVNNYRvFiwcYRfcqfoiwW5fNVfw09p1replIwyqcucg4c0MgGgxj2G
w+ms/1bS/EiwS4C7IW0yYSD3nGIF3GyLwMPOnbmJSz+ealEWjuBi8R0S1gX40QFU n8h95hiQPKr4Iq4qf7tsp+9EsYD3PBZAQWngbihlU67FwRinHUYn9sWO/o5qe1Rs
EV0MBrVrtFtnA2R8UZGCjU/xpgoQFE1U8dArNt0DPqNsOeL17WQZrZ58DurmnmiE UVqdejDYssQjcebCu8pZvx0wSSBTZYov149fGpWCzrkHyNVkEUKaLbs8Js2AMN/1
DNjndlR8Est1y0gSO9ujPtGXbbuhAOIXuEsYMfnBgQ5Y+dShs2G1EHC0OexYB83W TgIym0AQ+U/RN0vkBujghwtiC8H9VkaFQ6UE9eSfSqP+yUY9UtAvQhGuAv+2KYqN
FSHxM69hjQkvRLL0/lX+5NH5h+IJqZEUsLd0/J4h2Iz/EsDRxO6pKt0HzZbJd/y8 DTtL7+IeIg19V51PUTLvvPo6I+jhKtTQhnvdKzzktZ+h3ff1y9r4OF/f5mgWpxz8
qY0Y2K5cGUzG0y0TWuUznJyxmTSCgrZAE8sgBhU607+UnXU678cqbkRgSuHTNdMe FF1aO+oxufAvP4HdOWAn9B7KAwOdd1vLuxUHhI/DQqxmSoeJ51F6K+JJl5GYFBuy
yNxQas/PA0ltezOe3dBG34Cwf0oQZ/NCt2TfSFciFEgf6ze+fu+T+gCFfftWPiy6 HlgToIbCMeoBj5Yt/1g49nGLfSwN84MG90NNob+wmCtbrX1hEHW0Gv4fz8gGo5fi
pQ/3Fl6yAaVguu6UCR27wRMhXETZ+YZ8rw32XPbLE6BOvQ1LcGg9E7wJlw5eeir8 hkQtd0OfvsRZHZgrK+HXdQfAZ3v7F5onod28ZSaJHj8HsJ7d5Bl7UNG/NmZ/jqwq
0aWvKyUu/ClK6+/s7Ytxv1RoL72gn6WuOgK5q6Sf3mqmltuvJxtDVAnqCHNRfHXS lEnA70BoD7wQLuEojP5TnF2lEdNAbRAounXPpT7JLdbFjdVfA47xchLD9aUY1dfS
XgFH8gPqy47Gqg9qggCHjDIUbQeAu1IAznJAQ368WXkTqqnq887sSSgcs6JVduJf XgFwyvyBo0ocLKAHkCoBgfVdCjUnoCH5Bi0aONiEROumTTyv+NQBRoP2UiniQYPw
2YV5NQFOcoI6OF66FXXmY+sTpJaHcgVfKt3EHAqXxHCFZUSBHMwDJm9ulRBuYsc= ZL0OnDYOXviLwbsmMKB8J8KatKRuvOojT4kF+xGA2fUtsachPFYWPWvtRGNZ88Q=
=raBM =6Lnz
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$ encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
@@ -1,13 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: home-assistant
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: home-assistant-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -1,6 +0,0 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: home-assistant
@@ -1,18 +0,0 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: home-assistant
namespace: home-assistant
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: home-assistant
namespace: home-assistant
chart: home-assistant
interval: 1m
valuesFrom:
- kind: Secret
name: home-assistant-values
@@ -1,8 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: home-assistant
namespace: home-assistant
spec:
interval: 1m
url: http://pajikos.github.io/home-assistant-helm-chart/
@@ -1,61 +0,0 @@
persistence:
enabled: true
ingress:
enabled: true
external: false
hosts:
- host: homeassistant.lan
paths:
- path: /
pathType: Prefix
configurations:
trusted_proxies:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8
# Failover tolerations + affinity — allow scheduling on p330 during r740 outage
tolerations:
- key: ENC[AES256_GCM,data:SMOTaAtzpNtv,iv:rsMiAMaugnRKQjtp67nU0pW+MWXgolluiE5qoIWJkRA=,tag:RLUTotQG3XUQfDiA7CE7vA==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:DhbXHMsUJ7E=,iv:lQQTpWpDGi7JEQV24jdICHMnC8yV0EsNQ/nauBsqk/8=,tag:RKripNRdBwqnt1sCY72eYA==,type:str]
effect: NoSchedule
- key: ENC[AES256_GCM,data:YApCSh00O5YoRqzHUNSoPbYWOsNVwFKOlln0C2+mYpDfKqLU5g==,iv:eOv/Yri400RHpm6Bnxqw4IYp2IiYAKXTd06sduW3Ku0=,tag:9GR1Q8lWHG7Uplevd1hbYg==,type:str]
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: ENC[AES256_GCM,data:0rESi0B+l5uEwmPQPuFzMylc6JE=,iv:dGx39YEojvQ/J2y6SlP54I5L7Zr+yecwJwNQQ53RV9k=,tag:icAw2r/q4+UcHzYClfOBSg==,type:str]
operator: NotIn
values:
- "true"
sops:
lastmodified: "2026-07-25T12:44:32Z"
mac: ENC[AES256_GCM,data:cNqULRYPz0Es3az9v9HWlEf1pvPFWfZ67OofRWaDgFx3KVKVj6VUY6HQgN589xbbCoBKLSKXUoag2zOku1P3yBkb39WrdUtfSJw2t7BvZIo0l9VG0bRAYZgJYgnQA1NrjxixzgZZ7AHst1ljB+ZC6qq5DgEJcuCiue9zkfySTMY=,iv:rNDmiWS1U01xgRHty/sp/RJ5iz78sOdBGP0mdjUX7TA=,tag:BVKsb/HQchTaLo+2Tlrn+A==,type:str]
pgp:
- created_at: "2026-07-25T12:44:32Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiARAAgxstgt71NySIfZBgF0Nb78qkkFV7xOEfv+VWO3EaSp7Q
8jhARPxkAVMwl1MQIdCxB6UuUeQi8fOrLwjYzTN1tWG/VV1P3KV3klm6jNcZ4Zxv
OdYt6kRLNfI4J7KWFhZg8A7/FfXSOtZEWLjD60hb4ie02ALEC9o2rUcdxWH2ZdHU
69GhP3VU9uiChOxEk6eLyQr22IF9IfQ7BVUckVzU13neZ2PEYXCV3QaHMBrvutMz
IFUGpi+drrXxXq9KmJQ4Yr4L0+mHwXYrFVi5rHK/ibgRDNT7T9nK56WCsgRd0MiK
7+1vK/q73p5ZdozmalYB2lKuehRapf/xdXbn1SrWGXbsHubdrE2AQgRxBHVy3k8I
spN2ZTPzl29mUsVIWKE/CdF1GsUGYrKwKL7S6aHZBtRXncbKBEFLbrloAjs+j83+
aU5ybyQWnZxh7f4+nQyDerSJXZJ17eEJRjqMDhJ6VmA8iOBWxgudM57d4Umt53cf
s4vOikRSO0cd+/OMvQQBW1IPMkwRSi4/jD8BZTXisWVUQ3/98NQPXQE5EYk2w7aM
5T1orWWWMz5EdQNptqz5GL6qPoH4UpVSGCNuCf/oyLR6MCt24JDR9KobOgXKUrfM
Qig6/+4WbvxBJ9zevi14FL+K00MeWd3pQT2Bsg8l3fWPIRe+p9lSB6yrsf6xHu/S
XgFWycRMj+U+y7B1kyXT5W6WshFHHTOlyAVgk9lnB+kKEVno4pAQBNuNlW4gwOvr
iuc9EaiuHat+CW+WdxLdH3i/jcNmvXfXRXdE3449aXv+haNBjxz93nRo1vbAFuw=
=O+AO
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
version: 3.10.2
@@ -1,13 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: zigbee2mqtt
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: zigbee2mqtt-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -1,6 +0,0 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: zigbee2mqtt
-18
View File
@@ -1,18 +0,0 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: zigbee2mqtt
namespace: zigbee2mqtt
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: zigbee2mqtt
namespace: zigbee2mqtt
chart: zigbee2mqtt
interval: 1m
valuesFrom:
- kind: Secret
name: zigbee2mqtt-values
@@ -1,8 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: zigbee2mqtt
namespace: zigbee2mqtt
spec:
interval: 1m
url: https://charts.zigbee2mqtt.io/
-71
View File
@@ -1,71 +0,0 @@
ingress:
enabled: true
ingressClassName: traefik
hosts:
- host: z2m.lan
paths:
- path: /
pathType: Prefix
service:
type: ClusterIP
statefulset:
securityContext:
privileged: false
capabilities:
add: []
zigbee2mqtt:
homeassistant:
enabled: true
discovery_topic: homeassistant
status_topic: hass/status
legacy_entity_attributes: true
legacy_triggers: false
permit_join: false
blocklist: []
availability:
active:
# -- Time after which an active device will be marked as offline in
# minutes (default = 10 minutes)
timeout: 10
passive:
# -- Time after which a passive device will be marked as offline in
# minutes (default = 1500 minutes aka 25 hours)
timeout: 1500
timezone: Europe/Paris
external_converters: []
mqtt:
server: mqtt://mqtt.lan:1883
user: ENC[AES256_GCM,data:8chGUA==,iv:SOAuBYShpWbza3idtyqFoVIFstZFM34OPDN4uhAer0Y=,tag:WPoH80VcUGLy5Uq/z8EtaQ==,type:str]
password: ENC[AES256_GCM,data:XVcTzQ3pDvPKbw==,iv:TK5qHq2yMTWgzcOPvj0GO7tOOD4PHvKMWfd3p4T8LuM=,tag:GJpKQWpVhwrewX4+9NITfQ==,type:str]
base_topic: z2m
serial:
port: tcp://10.1.1.159:6638
baudrate: 115200
rtscts: false
adapter: ember
sops:
lastmodified: "2026-05-02T10:26:20Z"
mac: ENC[AES256_GCM,data:32zZ0bYrgn+zTz8DEOU1N8MgDrihzWyMsV9q2m5RhFHRvXFuq3Z2GTORlUTeuK5qZIUrZt22VskigGAQiKC2CdzsJTcO3cGPshu5E6gWGBRNob02bXXsMu3TfCKxic/Ek7jE2p9R++a5AKczFZY8SxL7Sv1BZDxozkginDdYR4Q=,iv:VcDKwoPgYxZc8KXYv9oEH2GBqDRAJJxphj6MFLLI8ok=,tag:vPWqcEHoBVvfCoKoN5UiLA==,type:str]
pgp:
- created_at: "2026-05-02T10:26:20Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//fl1m3T6TnQvQ+yG0plOZaRXIGRI/YHiyP9KsK6I6l4c9
Y7lUjVcgADbjZYAMv08LFOEyN0/dtTFx2kV1vC5sF4CjxXKfddazKrQFjZQygc56
Yn3wiYX2ZMTsc3AnOoUF/evXyDHYMu0l8FwZEupi0cjmgKjVZZsLYScMjLi6h9oO
agDUxqZX8d3ikj3LPF1dk/XGP75fHBg7Jfim1RMMrOcpAbRi0H3XU82cr2s9fTS8
UtylTk1x3F253YTC0JdvU0UskvzCvVl0Sf8TlkVb2tTJgwf/XnXMTmMeCvbhIj5u
bgqIs0y6F0xm8NjhPGV2CtsQuQtLMLb5SxVFj7P4ad/Ekf9TizAJlcPt2u1/25zu
x9v/kFnI5XMDIr3eWBJlFUwtImQJ+bO3GTauqwpULIHSa+y3Ux2XMNarKfN1jH3Y
RG86rLQSioSA+HdZuZdEvo2ACc5DotC835cnMGMeIuO1Ad/RjvUaptN/p5hvTFMf
5t6SoE8gLXH7FZF7IomY0Xs/feztPOvPK76zpKV1Tqqgb7i0GaTFcKKBUxMPklZw
XwqOQl36HWz1BSvtYtYYX6/HyuknH4T6tk//J6MrNttnTQ/ZqjrBvl4FEVxTgf1h
pFc8fTzNak+VB4MSdALg6Eo5xR57eGHhKgdUMgDAv1JMEP9ikk4/p8/1WHKhpTvS
XAG3QSahHWoc9L5A73xFmD66TRUhm8CVKRCAQebB7rXjsxaqgEOl70taQpucrckD
624SYxJwG9Uuk4odCQJ6g7T2KCKxsS/NKy6jOqgprkerR6pCfuXg8LDxBkHP
=cZ3t
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
version: 3.10.2
+23 -82
View File
@@ -1,60 +1,22 @@
authentik: authentik:
secret_key: ENC[AES256_GCM,data:P5e7cSOa0Uw0NEmWuDzIv1QxIkbvLE9vjzULmS8yS8b62fS5jHuFWUF/8VkW+pXiJo51mZ9b3QWDBdD732hpSrR7hUpK19WdZvFfXMKsqVc=,iv:AuuvJtXdlQ2SzeiFdxv96cEVyeMTNW/fG8bPS4ItFtY=,tag:AJC/T+eXGwOdQ/U7rebIdQ==,type:str] secret_key: ENC[AES256_GCM,data:o7yrtJ93jbwGEbF9noIn1kifWTRj9oTZ1W10vaXGkqn2a98SE5+1KHWATFNkLq68TPSyKlGDrvXKEXX7jdAPgDkDBFv9XXTfWAPX22Jymhk=,iv:iyCygmcW5jR4QfzUfOfX4uIERmef/rZ6/vddJ5SMu7Q=,tag:CV78h8WCvyZ4piMvOElm6g==,type:str]
postgresql: postgresql:
password: ENC[AES256_GCM,data:wmidNe0ODeH8FQ==,iv:zh38F/lIKdFBBIQufjLORtfusPWwDnsDIh61b6ltbQE=,tag:SSMCicRKoPBXwPLFoh+uoQ==,type:str] password: ENC[AES256_GCM,data:BnUPCDLW/cA1hw==,iv:odEP+d3nx2Q0X9/MXimujGx7ZFnwhNCzTs1F+Vdhm48=,tag:Z2l7EhHM3qxAGY6Adue7FA==,type:str]
email: email:
from: webbot@vhaudiquet.fr from: webbot@vhaudiquet.fr
host: mail.vhaudiquet.fr host: mail.vhaudiquet.fr
port: 587 port: 587
username: ENC[AES256_GCM,data:VV9x5UWZ2F/p/l4pOVdDB3ZeK98=,iv:H7YXijpo2oJEO96LJOERL4lyQtV7QJq86H33wDpKObU=,tag:q+KiivjpV3kXY0AYGKhzFQ==,type:str] username: ENC[AES256_GCM,data:aPUSXDiYvDF/E/Gd8yJdIuuoHsE=,iv:+K2CeYD8CFg9ncpPsyQQKf1YzCAc1qj2b3m7hbS7Q1I=,tag:4KLvqKvhe2bqi65h5zRslg==,type:str]
use_tls: true use_tls: true
password: ENC[AES256_GCM,data:pco+hLWairs2UFNFTSY=,iv:OMrxrzKDo91UIMgEhPdN4dTpRxl5A1LKHYk5h4eFD/A=,tag:ecjAP9lv6FPxPppyurJ5cA==,type:str] password: ENC[AES256_GCM,data:0RP14fdOUDlqPLam0jo=,iv:jZpdUzBIyqSS16t6kHvpa3YEoAPc1Z4vnWfo2zMWUXw=,tag:AHNgHPvZvdyo2UJcuUHL8g==,type:str]
postgresql: postgresql:
enabled: true enabled: true
volumePermissions: volumePermissions:
enabled: true enabled: true
image:
repository: bitnamilegacy/os-shell
tag: 12-debian-12-r51
auth: auth:
password: ENC[AES256_GCM,data:cRaZ23HWjZ41ig==,iv:HABmXhmHvMhjUJ989xJOFPWW+EnLTCot1is80vMTBUE=,tag:r+/iRkQIlXvALv/JQbGFRg==,type:str] password: ENC[AES256_GCM,data:+3x5Tyegl7AXDw==,iv:7wYEX57Cqr7CH57FwHi9mulZa34l0pCOyh13nWRPD+k=,tag:x0k/Yjr9DrZLbZUfz+LmTw==,type:str]
image: image:
repository: bitnamilegacy/postgresql tag: 15.9-bookworm
tag: 15.9.0
primary:
args: []
tolerations:
- key: ENC[AES256_GCM,data:M14eAjMj2w2+,iv:5vIosyFtwVgqs07CT2UcL1KL2hqg+rvKS5PWRvWRlPQ=,tag:OJ4RwlLAhGDN4JGPX8gypw==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:KKZ1Kd5yRa8=,iv:adSUcfmjnDAc9QZ14NDfFz4oATpcBhtn8iHTF2xXpcw=,tag:G//QEbSKXiGP7nD5oAfNSA==,type:str]
effect: NoSchedule
- key: ENC[AES256_GCM,data:KtJS0g+/3y6VZb9VNKv1IWMwIi8FBURPGT6W6qvBAV1CHW4UMg==,iv:1I8o3SNljujN4FqByFC9uHpImJhHjj4Us0QEpHpDHZ4=,tag:FIpRW9I4OSVFVx4ejmau5w==,type:str]
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: ENC[AES256_GCM,data:IkWdKkS/XlGw0u7I+Q2wYhXL+CU=,iv:2k9d0Jo4Vw5gA4tGeIq1Dw0IiZKQykfV8YAt2lYk7GE=,tag:Xnz58VP61Ew/J8hvIClOVg==,type:str]
operator: NotIn
values:
- "true"
livenessProbe:
enabled: true
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 10
successThreshold: 1
failureThreshold: 10
readinessProbe:
enabled: true
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 10
successThreshold: 1
failureThreshold: 6
redis: redis:
enabled: true enabled: true
server: server:
@@ -62,49 +24,28 @@ server:
enabled: true enabled: true
hosts: hosts:
- authentik.vhaudiquet.fr - authentik.vhaudiquet.fr
# Failover tolerations + affinity — allow scheduling on p330 during r740 outage.
# The authentik chart reads global.tolerations (applied to server + worker)
# and global.affinity.nodeAffinity (preset system with type + matchExpressions).
global:
tolerations:
- key: ENC[AES256_GCM,data:yy3LVikckQ4y,iv:PlWRKZVoR6g/RtQdGBoIKbnwjX887xZY7ZhciTa0nps=,tag:yRMuJW3yjBV2C3LDWVdEHg==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:IqKHhgroaK0=,iv:bvg7kLaVQEsH31xHH1rCW29dWlWDlDsAMAmR1cX2nS4=,tag:B77eeEjVnRwk/feuPyi2Kw==,type:str]
effect: NoSchedule
- key: ENC[AES256_GCM,data:QYGmJBgxhqC2L3UvGYyJKKWDfzSFq91w1ifwNn9rofPnBqL0Ug==,iv:+tI3xw51LqinZnEOi7Lgao9liOD8KT8rOGNtn10qkFg=,tag:fJhk0PifHEyFlX4j75Sklg==,type:str]
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
type: soft
matchExpressions:
- key: ENC[AES256_GCM,data:qRInCqtomABFKcUFHzDQe2qmzJY=,iv:9cMrKqqpIMtNCUqkIWaCr5YGNoK6zsID3xAKp34q1kM=,tag:Zf1ZjGwCgnaOqTq8Hr++Fg==,type:str]
operator: NotIn
values:
- "true"
# (postgresql tolerations are set in the postgresql block above)
sops: sops:
lastmodified: "2026-07-25T12:48:03Z" lastmodified: "2025-08-24T08:01:35Z"
mac: ENC[AES256_GCM,data:noPba/BIxyoUo3sFfwXuMaZwwSMNADgWcwGaIoQchdzu3KodtWRHk5xJ9wy4VGelOuy3gS79j9ErDnsn8I1v05Bqqlrig99Sch5Jlu1UQpeUQtUjq9S7d5BQ0f3QdeU4iP2v28JovI3gBNHEIlZiueV6xYUrpeoKzS9ukrBtJsM=,iv:XRmbI5hX0OCh4I+7MmnI9LyBLJhf2CsfHgvsNaEUWgc=,tag:Ym5JeVRqTWHWl8qSQAFh0w==,type:str] mac: ENC[AES256_GCM,data:R9FBswMSQKehwWNQ2oKhsRkbIPkPeuTMnPCxrMZZouWZgkAq7OLYSAdj1dOYZ0PJn6gyoiyFRzx/9GOklwqthCKRES4Kg1u1jTrv7GmUxI7H8lTPfMg37i1BXYIc4Lkr87/qWT8b4NGIZY83ufauVhryY/heXtLBXovzRXg5vEw=,iv:e2ZkquHUAFG2yjj+J2X1cte3u1s4HvqKQhKk9wZpTAg=,tag:HHZ1DV7SbIGhICAJ2uLZoQ==,type:str]
pgp: pgp:
- created_at: "2026-07-25T12:48:03Z" - created_at: "2025-08-24T08:01:35Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//Sa5nJk6vXXFdf4C5XwsCeRmkSYKSdxJZ2auRzRi+2znv hQIMA7uy4qQr71wiAQ//XLw8WkiLxJjC0PDTflh9Yn/ruDENUznyl/z342jizaWA
IqicZh0YENwEX++2NQNtt/jaPFCqWUMEVfncvYceutHzZxDZihkbIL/jKs0h/Hjr 49o0jrmnlktRtnPVR2BZAC27CaZX2waR+nhlrSwSNRyOwyhxIcw+MpCthc0uPcd2
gL/JNRPQbVD4HXLTQ5dOuAfixJXcN9DfYQGyBg1vOtvpKxR4cD4JirA3KyYjtSWf 8w/MCCNPxf2UcdmXn7djl5rQV8cOlomFweDga9nUna7PGv7SWewQOmCDGOzplnik
cYw5fMSalPJ0D3B5pObFZoVJhu8emO3FegSu/tqnZseJuT4mqZqdhpuej17FtkQB MxpBRhFyOZxuheQIqq5u5it3e+gUfwHC9My8m3OJKBqFaEAhf3clnDy0nrq+xrgZ
il0tNwBdy9pDFXMxiZoGFtVb5Bii7ZU19MPleBBTFO9nNLXE8rCZ/1tJBtR+XUXE Dgc5DvEwCHbjXE/C9pgv/vmLUHEpXoEsmIurIO9ruxxzm2D6CaOXSL1WN6zwwQ1q
acglYoZHt3aHAqe1+8iLWAOmE1KkElUMU6/G5yZCpLNNwwgx1jXqGsvITMQQVptJ 3/UvrCAJx4JSNbmiXFfwYHTw3Xu3kAqpBssIyHP7qeiU+hIX11psDRFDnJHpRxnI
RMMKfdNGZSC4mcVXT+Ux/uwvw09DO9Mrbf0tjiTTjLProNxUmY4pPMShwCmGsfTa a6Sc5hGICirKFLQPGJAIYFce/nuAVpHZ4dfaCKhlZF1sqHoO8MZtOw/MG6pnYu3j
si/bZbCui/Jryy02dYWuzA4bpReY+ySMwUGZ9C/0Gn/SBEAdeGQKDhJwgmE6BM1n rpyw0db1ehnGaWVjBTUrtV4wPVQ1jN0UPJ2OTRJrxAIEu/AY9gNqLGcv8tGtjnZr
hMZOh9YPcGSc0n4a9q/CzFqcQ7T8m1uHgqciFG/zW8A+l8bC1H5uxsUwcYPALLxY /SpWn7Uvu11lpayXy7vFsXz5JsnBv/6cN6M8Ze3VcRDBKF15/S7K/YX8JyD6/oOF
adAZ6XMPZAZ1L/zp3NO/SpdHp7hQVqx+TZOWvmlZ4XiDrICp4AVK8oZAXKw/nrAu MosvgFeOZ7Hxw22M7Q+pKXoNvBj17+iBkqiZaJOVFVUG8GlxeF8hkSUBWkdWCGq8
k4ZYVsrBKrkLBIMNmM1mxuhi248ELB7V+kN9zDxQZh87J+F2WXk8D4dMwBfRfYzS 7URVftX1uNAvYjKptzSREDvCSu6fXfE+znSYUzGZT6u55lOWerdtGraRUPBr94TS
XAGiurXdFcCH3i8O5mmE8QY+ZgdKzyAj7hVw8BvXlOIne8pPe3YuZsp68zwdz8MQ XgF1ukkgRyYqbf/eyiN02LvVDBl0IfxYiedRCkMeX6L8NCVU9vxZZZattGDf6U3O
Gr5oDPaZWhEwFEg+4H+ub5xSIZewY7Ib7FM8bzzfd23vODtZ+0sBoRH+Tq4R lIT5wZTKLLAu3qeLQMOc/CkIJLePNhfzZVwcGLtQ12bLMnuTSjeS3S3EmajcFnI=
=m933 =yqSe
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$ encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
@@ -1,24 +0,0 @@
# TLS certificate for the Stalwart mail listeners (SMTP/IMAP/POP3 STARTTLS + implicit TLS)
# and the management WebUI hostname.
#
# Issued by cert-manager via the letsencrypt-production ClusterIssuer (Cloudflare DNS-01).
# The resulting Secret (mail-vhaudiquet-fr-tls) is consumed in two places:
# 1. The Stalwart HelmRelease mailTls block -> mounted into the pod + pushed to
# Stalwart by the tls-sync sidecar (JMAP) so SMTP/IMAP/POP3 present this cert.
# 2. The chart ingress (TLS termination is handled by Caddy in this cluster, so the
# ingress is TLS-less and only routes HTTP to the mgmt port).
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: mail-vhaudiquet-fr
namespace: stalwart
spec:
secretName: mail-vhaudiquet-fr-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: mail.vhaudiquet.fr
dnsNames:
- mail.vhaudiquet.fr
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
@@ -1,15 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: stalwart
resources:
- namespace.yaml
- repository.yaml
- certificate.yaml
- recovery-admin-secret.yaml
- release.yaml
secretGenerator:
- name: stalwart-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -1,6 +0,0 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: stalwart
@@ -1,47 +0,0 @@
# Recovery / bootstrap administrator credential for Stalwart.
#
# This Secret is referenced by:
# - recoveryAdmin.existingSecret in the HelmRelease, which injects it into the
# Stalwart pod (and the tls-sync sidecar) so the cert-manager certificate can
# be pushed to Stalwart via JMAP. Keep it present for the lifetime of the
# deployment; the tls-sync sidecar needs it on every cert renewal.
#
# The username/password here are ONLY the recovery account.
apiVersion: v1
kind: Secret
metadata:
name: stalwart-recovery-admin
namespace: stalwart
labels:
app.kubernetes.io/name: stalwart
app.kubernetes.io/component: recovery-admin
type: Opaque
stringData:
username: ENC[AES256_GCM,data:CYm0+Kw=,iv:UdgReqdb8GdoOfv1ZEW/7BAvY3vV88httj3W976eV0Y=,tag:PPrDQY/mo0RcJiz/cmxFSA==,type:str]
password: ENC[AES256_GCM,data:r0mPJ4qKIhAWDw==,iv:L5+OKTznQgDUgqttHwdW0X66vz+JPTqWdwYPGklCuj0=,tag:WNOj7ZjC6Lx76UlPsgSDhg==,type:str]
sops:
lastmodified: "2026-07-02T20:57:39Z"
mac: ENC[AES256_GCM,data:lIVOaMsFV9F1/yLvykA3LH5ukn9PIba6N8cE9RGdcFepM56tBYlY6fbkcKTtojyAkoYov6OCjgTsOkMtUzRdGES4Zti6zHB3cTPal8bJCf5cAfYnGFRcQaASIkVjNZkQSJ2pDRP4rZqioCHuj2/a6uJZ4hhtSpxrECYbpzD2Gk8=,iv:31fXHsWH1ZP00Od5DSxgYPuw87NqQNfWl4vFtoouIHk=,tag:u5cJn231VT2ZTmlcdpBz0g==,type:str]
pgp:
- created_at: "2026-07-02T20:57:39Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//fYBIypexVfQJn5BxVCRgZKRBcYw78XSoPjFYWFyk5F7I
UFRQKtdZOVVhgNHtFJOVyBvl1sAmmzAt3xq3L+Z5bvtrUfZ33tTp7ty+MmSmuutS
wquSh4NOHUYENGvo5pWsgVwQDj5bI2qUq4L92aedpB2XJycb7/Df7BWFKNMNgWdt
l+Hj9HEJWxmFjrz1MQJEL2r5WOx9/hK7uatbDTXVFPqyyW1aCM5XOkKErTuc3Avn
8tNNlvP1aqhI/2dHfOSZ1l0/PHhdi3RBmGa3BfAZUXEseBEesIK/EaJZXMjQYhF2
5tAPQ1irqg8LLv9mhrUD2mWaUigcuZ1EeyfZFvNtY/noF8fyZny1jra0sDe4CmQP
7uyP6CNRWPCikutUw45oxtw+/Us5Ld8xzJxhDEm0e+8FFiAK/SFSOx57JbjNzoCj
dqHU3UIzyp9VVZohqW7xdHOW64fgDI41BDKBsEiKraLnZUoXL2Lx0lnjxayJqVsD
2pX9D5YXzmtwFvUU5ZpcCzUWFu9MVxSfp6HdKvocGdtpSz7J23PQvHtkv20GxJYd
J45RYGgekuJ2EXc9kPaCuSex/0BKtYybOk5ANRv2yGeUZlc6EoW8/GZ4sHXPY6um
tt1DdIsMNMjAU68EgRkhmQnFAkZixJVdDR3u4MNXFUr0WdVIqzjFBavyrkcK6HjS
XAGhFNWdk5DNZ1ChGrMKEnYCZEB6XNkofa7S2xAomEoxyuCq7X2vbfBfqDQ/Rtcf
kSx0TpIOSHxefSFMduPz90rDqdZgUW0D3GND0PD5XRFFiJxxdrRYPux9MDMd
=Ef8e
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*.key|.*.crt)$
version: 3.10.2
@@ -1,21 +0,0 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: stalwart
namespace: stalwart
annotations:
homeprod.io/essential: "true"
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: stalwart-helm
namespace: stalwart
chart: stalwart
version: "0.7.5"
interval: 1m
valuesFrom:
- kind: Secret
name: stalwart-values
@@ -1,8 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: stalwart-helm
namespace: stalwart
spec:
interval: 1m
url: https://kgrubb.github.io/stalwart-helm-chart
@@ -1,147 +0,0 @@
# Stalwart Mail Server - Helm values
#
# TLS for the mail listeners is sourced from cert-manager: the
# mail-vhaudiquet-fr-tls Secret (see certificate.yaml) is mounted into the pod
# and pushed to Stalwart by the chart's tls-sync sidecar over JMAP, which also
# calls ReloadTlsCertificates on every cert-manager renewal.
# Container image
image:
repository: stalwartlabs/stalwart
tag: v0.16.11
pullPolicy: IfNotPresent
# Single-node RocksDB deployment.
replicaCount: 1
role: ""
pushShard: ""
# Recovery / bootstrap administrator.
# The Secret (stalwart-recovery-admin) is required for the lifetime of the
# deployment because the tls-sync sidecar authenticates to Stalwart's JMAP API
# with these credentials on every cert-manager renewal.
recoveryAdmin:
enabled: true
username: ENC[AES256_GCM,data:kpf88Vc=,iv:k2kGcGlH0jQkLmb35V4+IIrBpDM93PaG6atcO/SLDB4=,tag:qZIR2LZlv1g0XBkEh0y8qA==,type:str]
password: ""
existingSecret: ENC[AES256_GCM,data:DnjFoj8VNeqHmwM/KVebjOOHvYHPgZQ=,iv:JWBs6OeZzsa+8uJt/FjptI6t+tf+CRQDKA7149rBg1o=,tag:M4CXA2k8M65mbSUF0mnGvQ==,type:str]
usernameKey: username
passwordKey: password
# Recovery mode suspends mail services and exposes only the management listener.
# Ship production values with this OFF.
recoveryMode:
enabled: false
port: 8080
logLevel: info
extraEnv: {}
extraSecretEnv: {}
# The bootstrap hook Job provisions a *fresh* domain/accounts/OIDC directory.
bootstrap:
enabled: false
# cert-manager TLS integration for the mail (SMTP/IMAP/POP3 STARTTLS + implicit
# TLS) listeners. The Secret below is produced by the Certificate in
# certificate.yaml (letsencrypt-production, Cloudflare DNS-01).
mailTls:
enabled: true
existingSecret: ENC[AES256_GCM,data:e8rzv2mvlpoZR/vMfd5sgNuYLDvptQ==,iv:qIQfpHxAOameSdDzOHh89n+RIOd9CcJcl0oRumSHAQQ=,tag:xwbQR5Jabvz+lEju5zuW2g==,type:str]
certKey: tls.crt
privateKeyKey: tls.key
mountPath: /etc/stalwart/tls/ingress
hostname: mail.vhaudiquet.fr
domain: vhaudiquet.fr
# How often the sidecar re-checks the mounted cert for changes.
reloadIntervalSeconds: 300
# config.json contents - ONLY the DataStore object. All other settings
# (listeners, storage backends, domains, accounts, certs) live in the database
# and are managed via JMAP/WebUI.
config:
'@type': RocksDb
path: /var/lib/stalwart
# Main Service: ClusterIP. Used by the Ingress for the management WebUI (mgmt)
# and for in-cluster access. Mail L4 ports are exposed separately via mailService.
service:
type: ClusterIP
ports:
smtp: 25
smtps: 465
submission: 587
imap: 143
imaps: 993
pop3: 110
pop3s: 995
sieve: 4190
http: 80
https: 443
mgmt: 8080
# Dedicated LoadBalancer for SMTP/IMAP/POP3/Sieve (L4). HTTP/HTTPS/mgmt are NOT
# exposed here - the WebUI is reached via the Ingress (Traefik) below.
# The WAN router NAT for 25/465/587/993/995/4190 must be repointed to this IP.
mailService:
enabled: true
name: stalwart-mail
type: LoadBalancer
loadBalancerIP: 10.1.2.143
annotations: {}
# WebUI ingress. TLS is terminated by Caddy at the edge (wildcard cert), so the
# path is: public -> Caddy (TLS) -> Traefik (HTTP) -> this Ingress -> mgmt:8080.
# No TLS block here.
ingress:
enabled: true
annotations: {}
hosts:
- host: mail.vhaudiquet.fr
paths:
- path: /
pathType: Prefix
portName: mgmt
tls: []
# Persistent volume for the RocksDB data directory.
persistence:
enabled: true
accessMode: ReadWriteOnce
storageClass: longhorn
size: 50Gi
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
# Override chart defaults to add fsGroupChangePolicy: OnRootMismatch.
# Without this, kubelet recursively chowns every file in the NFS-backed PVC
# on every pod start (15k+ RocksDB files), causing multi-minute delays.
# OnRootMismatch skips the recursive chown if the volume root already
# has the correct owner (UID 2000).
podSecurityContext:
fsGroup: 2000
fsGroupChangePolicy: OnRootMismatch
runAsUser: 2000
runAsGroup: 2000
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containerSecurityContext: {}
sops:
lastmodified: "2026-07-18T14:22:17Z"
mac: ENC[AES256_GCM,data:JjN4ziOnd65U8AzI9ZnMiPUBiYFGqjGjM3HJ7XoSJuJ+fgYjOH+WX/U2IAfSeqEIMkzvP435BxKGoylrwEVM1k5v07slul5zEclPZglphDjiX+md403lVDtYEXdCSo0+3nqv1DFEQDkKItEEEz882sZBbhMotBHhgcd41RSA1aY=,iv:MaSmisJoj3aobpMw1HGgEOktegX2LtOaXLh3601xgvc=,tag:acWtTiu4ub7GDNp8nM/yVA==,type:str]
pgp:
- created_at: "2026-07-18T14:22:17Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/9G7UtHO7Ux0YNAPlnkVmU5BI+crzwbWPhdaUZFf5dmCkg
r67EAi/DjqFHR9Ew1Dhpn0InTA/Ld+mGZAAbWeP7xhIEQ+AqACmm/Oxgf3IkHKzE
P7dvco6lQO50W/m3fiU0Pv4A7w3Oq+AdFHcPr3UBi8YGYLgkCbzLs2r9JNviCJsl
uuvz438g92aXfa5JcyUjzxtxKFjzHrZ8seDx38X4fveS/mROpRqiw+G8aQ0BlXDM
9wfiQtiM9CcuahPUWopv4RCOjuqrSc14sxv9xRGsYt1YZFxZ/4Q7rqM+HXBsFp4u
8r4MgE+EflrhKp1aWPGnSn2kalDy3o+yFuk7IhWsrSKsNIU4j1J5xCfhliey+kNJ
387cVf7Bjw+iqoy+qiV7Q7XGip6NgF8WwSudZhznv/pS6LL5H5yHaKxjz5rny/TQ
0upK///2YGuiE66sBb8h2sqzIgr6hZecvb2VdY7BQX4FCo2uAmxTEh+h1fHlervc
i/03B9kNSjP5fSufhE9lsLl0oZgaFIKSpkzLlPdy6z0X5vDEXJGSL+qFudo9RKtf
aaEwaQ+I+snmhWyBeeywxpdyRE5g3xhRwuwaxp7zzVt5ykCnyrZIPvzaSxu/QjaF
jCUmvPp0ZLzAB2xY9AMwOHIrym9lPmcBEEqCiHywCauOQzsGJE3vLF8x3/nzZnvS
XgEE9z1NxK8o0ntL+JZO3+GYvm28Hyw0eXgDJbjJ+tlBYeWH8lfBUOsk2V485OJZ
4SDNvxzxpyF/4RJY4P4KR7HgwDC8gOCsDgqcyn1s4KzECXyQlqmrXxOrL8cFRhY=
=aeJw
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
version: 3.10.2
-36
View File
@@ -1,36 +0,0 @@
# Root Kustomization for Flux
# Explicitly lists all components to exclude:
# - cert-manager: managed by separate Flux Kustomization (CRD dependency)
# - cert-manager-issuer: managed by separate Flux Kustomization (depends on cert-manager)
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
# System components
- system/cilium # cilium IP pool is managed here
- system/blocky
- system/caddy
- system/coredns
- system/csi-driver-nfs
- system/longhorn
- system/external-dns
- system/flux
- system/traefik
# Code
- code/gitea
- code/harbor
# Home
- home/home-assistant
- home/zigbee2mqtt
# Infrastructure
- infrastructure/authentik
- infrastructure/mail/stalwart
# Personal
- personal/linkwarden
- personal/notesnook
- personal/photoprism
# Production
- production/umami
- production/vhaudiquet-fr
# Tools
- tools/dashy
- tools/glance
+23 -23
View File
@@ -18,46 +18,46 @@ configuration:
disableNewSSOUsers: false disableNewSSOUsers: false
PublicCredentialsEnabled: false PublicCredentialsEnabled: false
authURL: http://linkwarden.lan/api/v1/auth authURL: http://linkwarden.lan/api/v1/auth
authSecret: ENC[AES256_GCM,data:Qaxb9o3xtrDo9rsxHFpm6tkRd7OWPDyjiIyoPvc1SiIQIthOwXyHQ0b7YAW8rGg1vKBg2fDCIUK4Kgoyr26qUw==,iv:KFt4KqTUwB830flAmxfw7tQrLktacTtWmYDjBAiugk4=,tag:IAi0x3AlCdCTXz7MBryg8A==,type:str] authSecret: ENC[AES256_GCM,data:UUZagqAY6+9AM4gMv9WFsWFSzjLxAALUz2iGg3dBIrpP+JCdJWVbXIRpZ8bZPJxvwnTcZSPOsLHlqzeqJRHubA==,iv:xgPnCNp2dpy8UG/fjEHPUxdXYXEQzFn3K/EX9lfjpWo=,tag:1uFZDdgGUvMvyKHj93z4yw==,type:str]
sso: sso:
enabled: true enabled: true
authentik: authentik:
enabled: true enabled: true
clientId: ENC[AES256_GCM,data:1u8Xe9ZMosAJWwPGZCloAFEQE6n0eTtBzaw149zsuL/yrVoiU8s7Pg==,iv:uxfiXfpocKbiFIu0dPq0So6Kdfr3iMFUM4hRJm3eQPQ=,tag:BxgV/Wl2ZE80+08uaDnsDw==,type:str] clientId: ENC[AES256_GCM,data:6XqAMjwywGgZK23ywm1GKWpIhIrXNa28Z52+0J1yhocBxLXoJAiocw==,iv:DiIpcD0H6wnIkXCMPmhLEHTzE6qKQrotGZ7q7Lv2iME=,tag:Kx80RoPf7BFMWEO1lZ4wCQ==,type:str]
clientSecret: ENC[AES256_GCM,data:LBIh0Jc2MtS5pvOhmFbWSrQaOMiM05e2i5aeMbDJJGNArQ7PGK+okbltWnZHonIwGU/sriFm/x4BMz+snrd+NgTUR2aPPXnomK6f9dEmSXNjLxgnVFUmgcT2P7zqlKUBjMT+SKjZLELfYGzysKTRkXHOCrOoGX8ZobEgOXGflpQ=,iv:iADfUCL30NrwPPof7r/ppO3Rt7ap4RoOkKpBuzyoO8A=,tag:lrt50iqFsZcEdBx25BY0PA==,type:str] clientSecret: ENC[AES256_GCM,data:OO8vjjWVxzUNuY/Jhk348RykWnVRQ/xthunOyI4XVzCmT0WXAH/uWSupljfWQW8aj4WzUUHMpJOvFpd3iYTExFn6QqyBisOgVzS9jy4sP4qdhnSpu9jXzEUNmKyjQncl3QTQCcPZMjlGGf0oJzZgHivVWl6rFbnYQOJHDlu3r48=,iv:H2OvOpH2yxUivH8RTvSnM9k86i9jUJKcUmNPpSSos6g=,tag:XXTyOC+Hj7BvgZJ7qxEZyA==,type:str]
customName: Authentik customName: Authentik
issuer: https://authentik.vhaudiquet.fr/application/o/linkwarden issuer: https://authentik.vhaudiquet.fr/application/o/linkwarden
persistence: persistence:
enabled: true enabled: true
storageClass: longhorn storageClass: nfs-csi
postgres: postgres:
enabled: true enabled: true
host: linkwarden-postgresql.linkwarden.svc.kube-talos.lan host: linkwarden-postgresql.linkwarden.svc.kube-talos.lan
username: ENC[AES256_GCM,data:eUTE15OnJZ4dBQ==,iv:bN7y9EwD9rzzH3pm6JJvFkSHmdXkCunui2tyerb3z98=,tag:apU0hdiJbp5fgKjesLfdrw==,type:str] username: ENC[AES256_GCM,data:N+ozpU6TgAZSLA==,iv:XJT1fUe2XqSxpuuPfmzbyrJUUInUEhLyNddOX0jogZQ=,tag:z9rCjOKISMT+wpfwUzFd1Q==,type:str]
password: ENC[AES256_GCM,data:qA/FQZdMQG3vdQ==,iv:S0fBAfNiNUi1t7coaKFLloaXolv7l//tUVnSui0Tmo0=,tag:SbW/QBMoNqUSENkSCR83AQ==,type:str] password: ENC[AES256_GCM,data:G7dF3Oo+1wzL9g==,iv:yAjh22rwaBhKtHgYAmQEjFSMFspOpG2hThwwjAo2KJk=,tag:DdXlyNk+TfR0IuSpQG3+Zg==,type:str]
database: linkwarden database: linkwarden
sops: sops:
lastmodified: "2026-07-18T14:22:17Z" lastmodified: "2025-09-15T21:48:06Z"
mac: ENC[AES256_GCM,data:DoHEvtWEetZGb/lCzQalLAMUlAZ7OVG66bDSaGY7s0i8mhDzRxrkvPq7FL07rnDQoLSW+SFSq6h7LB1PV1HodW35b4rmDzpCCHQ/S7Gj8WW/sX0t6dFpF1GlYeseqAMtNMPeMf095Q9LIHmQlILmjPAKbAuOg6shQ9oIesBzSDw=,iv:3D+wZjBHp0gZRDOvmVHaTIyZlC9IzMupvXfbvYYZVm4=,tag:ui9jt5/F/9NJ08P7MD+7AQ==,type:str] mac: ENC[AES256_GCM,data:i9Mg17Z72cBJOSvmOlHkl0x0/FqhpCqS8iTGTYKlXacXi9E0nYYZr/y74qVjhubEaI1y6cRYXgaePI47lkyfvTzB3VGEpEs/y5fiL+PfiuV8Z18J9244+TyoasYR/a2sdRuJcY5jm6PSTKoGiwGnyZEthVwt1T38yr5msW3D79A=,iv:yj7uCySaoZcnO+7XsgB1EMfZOMwHSA0mtJXUq66MUgQ=,tag:YRvUG0/hj8Bjp+pMdJvePQ==,type:str]
pgp: pgp:
- created_at: "2026-07-18T14:22:16Z" - created_at: "2025-09-15T21:48:06Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+LxkvBdTDic8D31VBAtMiKJJ4nHAIpxja6gHsyVCmS+LP hQIMA7uy4qQr71wiAQ//dICUFaREdeVKhKkK7iPji73IRFZEnwoZwEnR0vtCBL3d
VOqnEvvEBxf3ifXqwlYh/rY7ywjMyuQAW03zIlNq+9Ufv5QV9Py+UTiQV1mfmRoa HXFfdXUMOVcXOvkkuF9zG52flUZBpVgilQz2W8Y7xI3tU8xX6wxmuz8LjegidCHk
73kINswzbUGvH+HXVkcRGjusS/StPMWKC6jwyrov09gtTF1rJUfcfenqy2waHZOk R2xKAJ5iCEWZTIouFwg4fM399Mm9xhiIPuM4+25DAZnSJJAc7fQ2NaNaA8vjbJQ7
JhwcxhrPUnHGOsv4f1+91CCjKHux3/FVagpxJcEvxckMJweuZWm59z77dbwF1lQ3 YUnqkmE+QPGbyeykudlTFfl/zZzrgKbQqWuUmD/vq1XckUaPxM5cdeFDsg87AZCs
ws4VMLKzt2wiYSULCDr5KM2YlYWkvzheqhwnOVKXk11ewM+6n8RHIvsE03nvkfRf o51lQ39b+CpWmdbDbJDF5nMWUrCzIz9okptoNfHM/5E0Jg53JBsXBvsqwWTOI5vo
tJduJYmXnz249SM4hq3GvyMq+j3qShIMvvKRMv6+aYMZ3SFzAIxtV0dA3lCoA9oy djilDfsyu5nQj7UDstaax839T7P5gm5ass2/YtIjgrJUczyRt6vS97zuXLsbEGpH
mGWvImrA7JX4GsG44tEzu0ECvoFV8lEb39QKBXBf8fN6UExasF4pSm276ZGG4Eom 6hXHan7OormqbmISnFrL68Q4w6JUZev43bdzqtX0EnYHNZVLXH3qAxD5EnuL/i20
IpfpuaB9oYL4TOEH0/56IEc2BRlvAm62ibra5jNCVLnLB0pzE3KdN7ZYMQyXooZi oY/oMEteFh86Smw/LXwtWjVfPKYzNQ6GTkTCzM3hVcfMOzdFVPgYDM+5EXF+/oAB
dOa56z4KidI4N5oDTc63Hkg0tApdV0x+Rtm7qgdhEp/1i4zqciQqb8//yN6CAb7I +BGqZvWW4G3G9sbPTRSJ1k+toWuC/erY41r+g3+KHbW73YdqIVwBsTDAFhPPNbe5
DkyPilrvNkZw95iGqpKVLrAp57BaFHLYNr0O7+WS9urCIUQl3Q37Nz2HyNLJt0Ej hnr1JFLQ75GHdDRnKRl3nZSPc2j9JMUtMhX+rKwLb/0DoVjNz0lFut/Tj+6xiG/1
i3VgiJUIoy5NcAIBIFvuAJDsXB+FQxzg+7XUZL44xxsSvA248Shz1CYH9CgwbszS SqHTpROU1tkip+rP0shzdu218+hjrzj+cDKkawoqmpD9gOm83P7YEqrIwcBj+TPS
XgHdJTIcrq3ReybtFVDPtqMkLyItA1fbJzpCr4Fwk922hmEpqBeMHx1Upy81MZJj XgE3UHtwHdJM38kfPm1fkTuCejlAQ3Hsz6W4PSbXJfY8w1gO241dEzy+b0At9Rv2
T+4v8xBo7KR/6sx3U9kO/TjV7AhdTJPRlgG0WfnfLMncCkrvg4cQWxEIkySShFo= 6IklhRBAs4ioH/hD653yz0mkCYRpOLYDJU2iMWZdv61YLXb4rsnAwr6xLbDHDXM=
=XPzS =69Pc
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$ encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
@@ -1,13 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: notesnook
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: notesnook-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -1,6 +0,0 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: notesnook
@@ -1,19 +0,0 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: notesnook
namespace: notesnook
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: notesnook
namespace: notesnook
chart: notesnook
version: '1.0.5'
interval: 1m
valuesFrom:
- kind: Secret
name: notesnook-values
@@ -1,8 +0,0 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: notesnook
namespace: notesnook
spec:
interval: 1m
url: https://gitlab.ibaraki.app/api/v4/projects/130/packages/helm/stable

Some files were not shown because too many files have changed in this diff Show More