Compare commits

..
Author SHA1 Message Date
renovate[bot] d8d71c35ba chore(deps): update terraform proxmox to v0.119.0 2026-10-31 05:01:37 +00:00
vhaudiquet f44a4e7d76 Revert "revert: restore caddy values to the last working state (s3 mount pending rework)"
This reverts commit bdfc374f08.
2026-10-16 09:20:37 +02:00
vhaudiquet bdfc374f08 revert: restore caddy values to the last working state (s3 mount pending rework) 2026-10-16 09:09:28 +02:00
vhaudiquet bd3143065c feat(caddy): mount the s3.rhema.rs certificate 2026-10-16 09:06:11 +02:00
vhaudiquet e33b82671a revert: restore the caddy values gutted by a bad s3 volume edit 2026-10-16 09:04:31 +02:00
vhaudiquet 844c8f8abe fix(caddy): the s3 certificate volume references its secret 2026-10-16 09:03:55 +02:00
vhaudiquet 93054f962a feat(caddy): mount the s3.rhema.rs certificate 2026-10-16 09:01:46 +02:00
vhaudiquet 9aeecee770 feat(get-rhema): expose the S3 API publicly for release uploads
The release runners cannot resolve the in-cluster Service name, so the
binary uploads died on DNS. s3.rhema.rs fronts the same Garage through
Caddy and Traefik, with its own certificate, matching the web face's
shape (Caddy terminates, Traefik routes, bucket by path).
2026-10-16 08:56:34 +02:00
vhaudiquet 9d53dd0fc6 rhema(kube): deploy rhema.rs and get.rhema.rs 2026-10-15 22:32:14 +02:00
vhaudiquet 5058982605 dns: manage rhema.rs via cloudflare 2026-10-15 22:28:50 +02:00
vhaudiquet bb443f3311 kyverno-policies(kube): exclude longhorn instance-manager pods from cpu stripping
The longhorn instance-manager and engine-image pods carry
longhorn.io/component labels, not app, so the exclusions never matched.
Kyverno stripped their cpu requests at admission, longhorn-manager saw a
spec mismatch and deleted the pod in a loop, and after any node reboot
all longhorn volumes stayed detached with every workload stuck in
ContainerCreating. Match the real labels instead.
2026-10-14 17:43:14 +02:00
renovate[bot]andvhaudiquet 7ac3b46b3c chore(kube): bump caddy Docker tag to v2.11.7 2026-10-11 00:03:43 +02:00
renovate[bot]andvhaudiquet bc905c78bc chore(kube): bump chart Helm release cert-manager-webhook-ovh to v0.9.18 2026-10-11 00:03:34 +02:00
renovate[bot]andvhaudiquet d97180783a chore(kube): bump chart Helm release radicale to v2.1.4 2026-10-11 00:03:23 +02:00
renovate[bot]andvhaudiquet 60759d4e4a chore(kube): bump stalwartlabs/stalwart Docker tag to v0.16.25 2026-10-11 00:03:05 +02:00
vhaudiquet a1ce8d3880 rhema-claw(kube): deploy 2026-10-10 13:49:22 +02:00
vhaudiquet 8c7a905d39 saggar(kube): weekly full syncs on the embedded garages
Garage's hourly full-sync cycles were the InvalidAccessKeyId source:
while a key-table sync runs, auth lookups transiently fail, and the
edge job's prune step kept landing inside the window (one sync ran
87 minutes). Both embedded stores get a weekly interval.
2026-10-06 06:20:19 +02:00
renovate[bot]andvhaudiquet d72a76e416 chore(kube): bump chart Helm release radicale to v2.1.2 2026-10-04 23:39:30 +02:00
renovate[bot]andvhaudiquet 992415e4f1 chore(kube): bump caddy Docker tag to v2.11.6 2026-10-04 23:39:17 +02:00
renovate[bot]andvhaudiquet d21f92eb4b chore(kube): bump chart Helm release stalwart to v0.7.21 2026-10-04 23:39:03 +02:00
renovate[bot]andvhaudiquet a8ff5d1b10 chore(kube): bump stalwartlabs/stalwart Docker tag to v0.16.24 2026-10-04 23:38:53 +02:00
vhaudiquet 9629597703 get-saggar(kube): deploy
The saggar-dist chart: a single-node Garage hosting the distribution
bucket — public read-only website on get.saggar.dev (the host label
is what Garage's vhost routing resolves the bucket from), S3 write
surface staying cluster-internal for the publish workflow. Same edge
path as the other saggar hosts: dns A record, cert-manager
certificate, caddy route. Chart repo and packages auth carry over
from the saggar release.
2026-10-04 23:14:09 +02:00
42 changed files with 749 additions and 70 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
creation_rules: creation_rules:
- path_regex: .*values.yaml$ - path_regex: .*values.yaml$
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml)$ encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml|token)$
mac_only_encrypted: true mac_only_encrypted: true
pgp: DC6910268E657FF70BA7EC289974494E76938DDC pgp: DC6910268E657FF70BA7EC289974494E76938DDC
- path_regex: .*.yaml - path_regex: .*.yaml
+5
View File
@@ -23,6 +23,11 @@ zones:
- config - config
targets: targets:
- cloudflare - cloudflare
rhema.rs.:
sources:
- config
targets:
- cloudflare
saggar.dev.: saggar.dev.:
sources: sources:
- config - config
+33
View File
@@ -0,0 +1,33 @@
---
? ''
: octodns:
cloudflare:
auto-ttl: true
proxied: false
ttl: 300
type: A
value: 82.64.154.58
get:
octodns:
cloudflare:
auto-ttl: true
proxied: false
ttl: 300
type: A
value: 82.64.154.58
s3:
octodns:
cloudflare:
auto-ttl: true
proxied: false
ttl: 300
type: A
value: 82.64.154.58
www:
octodns:
cloudflare:
auto-ttl: true
proxied: false
ttl: 300
type: A
value: 82.64.154.58
+4
View File
@@ -11,3 +11,7 @@ docs:
ttl: 600 ttl: 600
type: A type: A
value: 82.64.154.58 value: 82.64.154.58
get:
ttl: 600
type: A
value: 82.64.154.58
@@ -1,7 +1,7 @@
services: services:
wizarr: wizarr:
container_name: wizarr container_name: wizarr
image: ghcr.io/wizarrrr/wizarr:v2026.9.1 image: ghcr.io/wizarrrr/wizarr:v2026.7.1
networks: networks:
- default - default
- proxy - proxy
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers { required_providers {
proxmox = { proxmox = {
source = "bpg/proxmox" source = "bpg/proxmox"
version = "0.81.0" version = "0.119.0"
} }
} }
} }
@@ -127,3 +127,83 @@ spec:
- docs.saggar.dev - docs.saggar.dev
duration: 2160h # 90 days duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: get-saggar-dev
namespace: caddy
spec:
secretName: get-saggar-dev-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: get.saggar.dev
dnsNames:
- get.saggar.dev
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: rhema-rs
namespace: caddy
spec:
secretName: rhema-rs-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: rhema.rs
dnsNames:
- rhema.rs
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: s3-rhema-rs
namespace: caddy
spec:
secretName: s3-rhema-rs-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: s3.rhema.rs
dnsNames:
- s3.rhema.rs
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: www-rhema-rs
namespace: caddy
spec:
secretName: www-rhema-rs-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: www.rhema.rs
dnsNames:
- www.rhema.rs
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: get-rhema-rs
namespace: caddy
spec:
secretName: get-rhema-rs-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: get.rhema.rs
dnsNames:
- get.rhema.rs
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
@@ -122,3 +122,28 @@ data:
tls /etc/caddy/certs/docs-saggar-dev/tls.crt /etc/caddy/certs/docs-saggar-dev/tls.key tls /etc/caddy/certs/docs-saggar-dev/tls.crt /etc/caddy/certs/docs-saggar-dev/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80 reverse_proxy traefik.traefik.svc.cluster.local.:80
} }
get.saggar.dev {
tls /etc/caddy/certs/get-saggar-dev/tls.crt /etc/caddy/certs/get-saggar-dev/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
rhema.rs {
tls /etc/caddy/certs/rhema-rs/tls.crt /etc/caddy/certs/rhema-rs/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
www.rhema.rs {
tls /etc/caddy/certs/www-rhema-rs/tls.crt /etc/caddy/certs/www-rhema-rs/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
get.rhema.rs {
tls /etc/caddy/certs/get-rhema-rs/tls.crt /etc/caddy/certs/get-rhema-rs/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
s3.rhema.rs {
tls /etc/caddy/certs/s3-rhema-rs/tls.crt /etc/caddy/certs/s3-rhema-rs/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
+76 -40
View File
@@ -10,7 +10,7 @@ image:
repository: caddy repository: caddy
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
tagSuffix: "" tagSuffix: ""
tag: 2.11.4 tag: 2.11.7
service: service:
type: LoadBalancer type: LoadBalancer
# Cluster (not Local) so any node can forward to pods on any other node. # Cluster (not Local) so any node can forward to pods on any other node.
@@ -36,39 +36,61 @@ health:
volumes: volumes:
- name: vhaudiquet-fr-tls - name: vhaudiquet-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:0Gno0HzWCXBsKXu7HrFFpuk=,iv:Ygz3WDWijXzF6U1OEqGu3F7fkBsa7Q77dyURlgpww98=,tag:R1TH/CfTQXrC8INNWPTEBQ==,type:str] secretName: vhaudiquet-fr-tls
optional: ENC[AES256_GCM,data:lKaUaQ==,iv:ZD07ALdJ9QvLJZJvEANiHS+W9iusenyWsK4vO41fVqg=,tag:+5zgK51gMTwyCf+NuvdGOg==,type:bool] optional: true
- name: wildcard-vhaudiquet-fr-tls - name: wildcard-vhaudiquet-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:OgYNRxtElsKPLTxcHPAc8q1F8WsN+tdeo8A=,iv:3iflBURWgaOqa0fHp3J/ouxEyJD2AleHvANpumRSUFs=,tag:+WCVNo6P079P5WNmLRIsDQ==,type:str] secretName: wildcard-vhaudiquet-fr-tls
optional: ENC[AES256_GCM,data:uMCq9Q==,iv:rgEKryNgTq6m3VYYfImzQex7Fs5R+WIrMMX7+6zRJTo=,tag:ZtK824N7JkyQECslAsELUw==,type:bool] optional: true
# semery.fr certs from cert-manager (OVH DNS-01) # semery.fr certs from cert-manager (OVH DNS-01)
- name: semery-fr-tls - name: semery-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:BpYXgcOGKCfCkyWOPg==,iv:xEjs7L+74fCv2Lqh3gHL8Q5m64d9XkrO7QQjn1eNAdQ=,tag:M5TI2aFCl5Q+IFJv3fkczA==,type:str] secretName: semery-fr-tls
optional: ENC[AES256_GCM,data:6fbebg==,iv:aht7EEppRwKTYBnO4L/4VAlN2euvAVLPLuq7ekKWm0s=,tag:lHsPWL26QWbzAc32u9FYvw==,type:bool] optional: true
- name: wildcard-semery-fr-tls - name: wildcard-semery-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:UGyQYSXVWGw0F2XOynpuKfcgTdFIeg==,iv:8uzadBqa8qdQYImy81Z49ef4hUoIAXEN1lcpF/zLzKE=,tag:UfN9BzxGabZfoIIctowVjw==,type:str] secretName: wildcard-semery-fr-tls
optional: ENC[AES256_GCM,data:PxyWIg==,iv:0TxiU0ItTdtU7HQNbNhGjC2n1ECNQU9xB1EkDxDwwJY=,tag:XoiW8gIU9J3JGJ/bU68l+w==,type:bool] optional: true
- name: buildpath-win-tls - name: buildpath-win-tls
secret: secret:
secretName: ENC[AES256_GCM,data:9hnCOPClLIGgPNnNPaJbNXw=,iv:px4ZrrTlmXyqGI0dsWFzXndUGVqlV83Kv4aDdG0S4Jo=,tag:wiK4rTqyQN8+fWQhZB1chQ==,type:str] secretName: buildpath-win-tls
optional: ENC[AES256_GCM,data:vC8okg==,iv:Pl81vGJ6Lt7jvFuOZAoDl2iV/F0IgOfKoeVUCOdNPC4=,tag:tUo1/Y1ZXqpM6hsu52l+ZQ==,type:bool] optional: true
# saggar.dev cert from cert-manager (Porkbun DNS-01) # saggar.dev cert from cert-manager (Porkbun DNS-01)
- name: saggar-dev-tls - name: saggar-dev-tls
secret: secret:
secretName: ENC[AES256_GCM,data:dL9l5pMrG/mYNQrqLYU=,iv:iuObGUhAFxovuZNglvbkf2Tm6Ska6TOKucnbB6sDhKo=,tag:SmCPAODV/Sy/dNuUQJ48Zw==,type:str] secretName: saggar-dev-tls
optional: ENC[AES256_GCM,data:Ulw09Q==,iv:TKMN40lRkp+xmsAPDBVrVIe+h+6z5NlNZrpf7VvIah0=,tag:Cq3itFokCituCEJtrANeAA==,type:bool] optional: true
- name: api-saggar-dev-tls - name: api-saggar-dev-tls
secret: secret:
secretName: ENC[AES256_GCM,data:FQm3BLurAD2EMCgsg/kMgWIH,iv:f6bv6YFL2ExmHS1QmdAyOcI/nnCIHL7xEX0/kZQ9rts=,tag:KQRXKValNB0oWYCCqZ8xdg==,type:str] secretName: api-saggar-dev-tls
optional: ENC[AES256_GCM,data:+dUIjw==,iv:ztZ+5x76lpd2FqbZkgedeD2yneBKGicbW1MGTg4mUbo=,tag:ty4QRjVhbrB9WoOTenXcew==,type:bool] optional: true
# docs.saggar.dev cert — the saggar book (static nginx) # docs.saggar.dev cert — the saggar book (static nginx)
- name: docs-saggar-dev-tls - name: docs-saggar-dev-tls
secret: secret:
secretName: ENC[AES256_GCM,data:B/wTyuOSik2qea3FuCT2LpVqhA==,iv:Y8N5aQw4Yf2mPk1sEoeaxQEb3N1VVyyfiQy1cW1qdTI=,tag:Pn4k9TuMCJ5iAlWIVejb9Q==,type:str] secretName: docs-saggar-dev-tls
optional: ENC[AES256_GCM,data:Zt+j3g==,iv:AlxMaVpZMLKXDwP/xR9AiZS5p3Zm0/Kk0RXh7+s3/HA=,tag:6raJ2r1dw08NmP9GGbSysg==,type:bool] optional: true
# get.saggar.dev cert — the saggar distribution host (garage web)
- name: get-saggar-dev-tls
secret:
secretName: get-saggar-dev-tls
optional: true
# rhema.rs certs from cert-manager (Cloudflare DNS-01)
- name: rhema-rs-tls
secret:
secretName: rhema-rs-tls
optional: true
- name: www-rhema-rs-tls
secret:
secretName: www-rhema-rs-tls
optional: true
- name: get-rhema-rs-tls
secret:
secretName: get-rhema-rs-tls
optional: true
- name: s3-rhema-rs-tls
secret:
secretName: s3-rhema-rs-tls
optional: true
- name: routes - name: routes
configMap: configMap:
name: caddy-routes name: caddy-routes
@@ -98,6 +120,21 @@ volumeMounts:
- name: docs-saggar-dev-tls - name: docs-saggar-dev-tls
mountPath: /etc/caddy/certs/docs-saggar-dev mountPath: /etc/caddy/certs/docs-saggar-dev
readOnly: true readOnly: true
- name: get-saggar-dev-tls
mountPath: /etc/caddy/certs/get-saggar-dev
readOnly: true
- name: rhema-rs-tls
mountPath: /etc/caddy/certs/rhema-rs
readOnly: true
- name: www-rhema-rs-tls
mountPath: /etc/caddy/certs/www-rhema-rs
readOnly: true
- name: get-rhema-rs-tls
mountPath: /etc/caddy/certs/get-rhema-rs
readOnly: true
- name: s3-rhema-rs-tls
mountPath: /etc/caddy/certs/s3-rhema-rs
readOnly: true
- name: routes - name: routes
mountPath: /etc/caddy/routes mountPath: /etc/caddy/routes
readOnly: true readOnly: true
@@ -122,7 +159,7 @@ affinity:
- weight: 100 - weight: 100
preference: preference:
matchExpressions: matchExpressions:
- key: ENC[AES256_GCM,data:icR94wmhgXZjrKlEJhGCuCqwxfI=,iv:s4zhWsRFXy2rZnETpkhixCoFHykEt7z2cRjW3lXJZP0=,tag:ejJW4EqCxEyDCrvRtdg82Q==,type:str] - key: ENC[AES256_GCM,data:AsOdq9OGQbAGV42W4d22EGVMi5E=,iv:U3sLu8pI7fqOPbvpfpVz21cUfwovKRFi8jY6laTyStY=,tag:EQVSFAzTYw2En2xdGTCF3Q==,type:str]
operator: NotIn operator: NotIn
values: values:
- "true" - "true"
@@ -136,37 +173,36 @@ affinity:
topologyKey: kubernetes.io/hostname topologyKey: kubernetes.io/hostname
tolerations: tolerations:
# Tolerate the failover taint so caddy CAN schedule on p330 (small-node-1). # Tolerate the failover taint so caddy CAN schedule on p330 (small-node-1).
- key: ENC[AES256_GCM,data:Nw/vagZB7oUw,iv:HcfljVdo6FMPkAduv4hug8AVoe+/VniXMBKrJ8VT/QM=,tag:fr3Fl3fdmez/83pnZ9cFLQ==,type:str] - key: ENC[AES256_GCM,data:s3X0PmRJCCVh,iv:UYZl3EsmdSTdF9NoYsL+zbxLlkfO2GU80Sy3CpSXMBY=,tag:35UtC37ldCItR9fAtSXVVw==,type:str]
operator: Equal operator: Equal
value: ENC[AES256_GCM,data:647LykKfZZk=,iv:0Dz446WOcetIdS5x6ffugLgLJ7bqGk5DflIOajNxeJI=,tag:aGRWSC9aN8Jo0R8B96cYjw==,type:str] value: failover
effect: NoSchedule effect: NoSchedule
- key: ENC[AES256_GCM,data:i29MKq5p+vyIcWAKjOzfwLXJQ84MniWDAUbK9a+DyavBHi7v7Q==,iv:SaTj2YkCO40MT7l2VsH89/zi9y4COte3c1wnNcp1NRU=,tag:8VOtUPeDlg62Mbjg1/J5BQ==,type:str] - key: ENC[AES256_GCM,data:NYCyZsj7wMxKUjaDu+rUOQYxDKvvEwSWuDAxQkSGTczXyApCbw==,iv:3AcvLXryeZ6dfmqanFpGOgEf1nGuEVbvUmZzruxzL98=,tag:Daa9AgXQZkkr7RIzljWOeQ==,type:str]
operator: Exists operator: Exists
effect: NoSchedule effect: NoSchedule
sops: sops:
lastmodified: "2026-10-01T17:39:26Z" lastmodified: "2026-10-16T07:06:11Z"
mac: ENC[AES256_GCM,data:SCcbYDaj1ERDedV1LqbeBQ3uDJjkmyWkU2PXfmZ5BO5FC8b1ZkJJ9Ckcb8IvzSj2/f839RRHWGk7isUpwUrJ6QwifzYC53VAobr/S40sKx7281sYC+OX20zxa0hAf0fts1PsWWaWQ8IEVd08481MxyZFUFpFqGyGuyUeuIJtWf4=,iv:/U7yj5ONy57kFGqZNUOuCagw5N7mKgxv7s7QlR+nZNE=,tag:qBYkZmR3n/YrnfT7T/VwXw==,type:str] mac: ENC[AES256_GCM,data:kMIxep2WVIr8/uAiw12T1JXMbtpyijo1c1MOOUKuok2Z1zSrnFZovgIup3u8/2BhqJ2UUDm5hFJi41Tsq45ba5ELs4PX1whi6EXlHQJxNo7ScfepEi10es/wa+p+3w9V8Yv9cklIWk14zh0UABs8jRzOJXhn5XI3O644CJSULQA=,iv:3ssxqRNRvXbmn0HiQFdwoGVbsnzvtQxfpHPIUpplMK8=,tag:5VRyB/Hh4tZUWp6KCPNSQg==,type:str]
pgp: pgp:
- created_at: "2026-10-01T17:39:26Z" - created_at: "2026-10-16T07:06:11Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//W/WNIqPCl5afTCLEJOUnvBj80zjZ0+cDI7W/dvipnAqx hQIMA7uy4qQr71wiARAAuN5nBauJiH5bFx80iF2W2XJDwMCFG+SPlqv2ErxVaYkD
LQZr9zPfG3zURJBzGRpUDvqUWt2tymikQPx5rSNGgHeLYRru3SwaD3M5AEgkjAmC kSt8pA0o4Bzqr6gP6cEgEhzQHAVVvsvTZJTY5lX6KWNRxhz/RXDhxAi9xdBHQ81f
Y02hH6fIsJ+k5NhOS0wAlkgXze3EXq+0JOE8ZYQnF0ggYfsK6vTD+q+fI7zxddfx dDWn7pgD8sv8cODM39yeukhGlHxZuk7FiUJ4fBnouojWUCxf2Ib5m5TEaWwmmv5n
0KLi8Gec5GXjgO93Roi0GwVguvQ9IDxe/xkGxQQ+CdZ7X6w2vfzBz/of6QJAGvRr EBBjjcbGZzyWBzCkLbEY/ML1FIx5j/jyZjpjMp2En1309ljIBckjLk5s9Kntp6oJ
8XKWmuUDBOdvWNFqfmsLMZ03ssD/h/WmxwTUMCHcynXSyprL+QRNH+lMMSVCFwyo /TkW/BhU96y8fyGM6u3FV54wORNlCT3P5cDT4rsQd+KgG0DDchAdUSb7hmBEn+iC
yiagQVxDPx9zmp/fwnSYt99sN9Q+Ky75r0UdFJYzpk9ZfqHveEVIh7JUigwAawF+ W/eUsp7nhObkZZBjTKYeS502Q+3RUEXoLnVLWougDxMSA1rJNS3nkgzK1cmKs97/
oX8amZoyG5Qm24ZwTA6pkuzw8yc9KNPEGi5UjGFW+Q2fDPjq3Zt0NrSyfGD48dzJ Ghnb5TUGPmoQMUltQzxInDq1mgeGfuFUffprYprYKGeVC/oQ6uPHE4jVZImlWRjv
NnlmwkMkWGxTeVwmzdxgg9sd5QvG+8/pwJE76epJdXRQLd8ylJGoUNgbO0tZGEdW w6YPHv/2XhWMN5vH/ybsrqxcFb5+1z8u8J58GAJ37hDXzkL8ENJUouonM3sywaBc
99pFqcbTN1UfZ6CtuPKTtU3GHylprTB1qw0wM1Hl/y8UEo82iuJmDdZ1HWEA+9AS VbXHzJwYEuLhRfNpay6ovwPkhU25gV3atBiXloIWc0PivPjOAJqqs0vkMgRiA+3R
rCaYe0ZnWmTQHpWHXMBVK0OPqamOGiMZX4c6AUEdU5kyBymGmN5tjov6d+vA+4ai yUagVKdyavVUhqou2LOxSGSv77uFPWZwhqUILtqzTeSE6GHUxVqKQPa91klRRNI7
0OQjcH2QKzNshGrxo+iLIDP70AeZCg0BoKyo41X8Af4cRi6ub6l1lIWMmTYTY/7S YWNtM7ZqSeANK99h5vgphhPZpuKkIzXHSLEXdplxvaRERfWMU3UGCDZOMVcDMlbS
XgHrANxBUj67L7Qt8spnz5FsQQ7ikTSEb1sXPM6RQ/hzFXdOHQTzJjwlr0NUXDgy XgGovkHZ9+NKVgZVpsRyQQutbSJqvHVZJx162gu3UKC1IgnDnhslOGKVWw/oKNb5
dwC2khracGn6F9cXSrD7SN1elORAKr+HFWqBrnDLrYSkhkVI3kmCoueP7cwNFR0= KyPf0CLk9BCAlSngr5D5pw4GJ9eq7RNFOqC32LPwXgNSD1AfLFHYGWh3RZM+81w=
=jpmk =eA3w
-----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|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml)$ encrypted_regex: ^(data|stringData|.*key|.*crt)$
mac_only_encrypted: true
version: 3.10.2 version: 3.10.2
@@ -22,6 +22,7 @@ spec:
dnsZones: dnsZones:
- vhaudiquet.fr - vhaudiquet.fr
- buildpath.win - buildpath.win
- rhema.rs
# OVH solver for semery.fr (via cert-manager-webhook-ovh) # OVH solver for semery.fr (via cert-manager-webhook-ovh)
- dns01: - dns01:
webhook: webhook:
@@ -12,7 +12,7 @@ spec:
name: cert-manager-webhook-ovh name: cert-manager-webhook-ovh
namespace: cert-manager namespace: cert-manager
chart: cert-manager-webhook-ovh chart: cert-manager-webhook-ovh
version: "0.9.17" version: "0.9.18"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -14,7 +14,7 @@ spec:
name: stalwart-helm name: stalwart-helm
namespace: stalwart namespace: stalwart
chart: stalwart chart: stalwart
version: "0.7.19" version: "0.7.21"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -7,7 +7,7 @@
# Container image # Container image
image: image:
repository: stalwartlabs/stalwart repository: stalwartlabs/stalwart
tag: v0.16.23 tag: v0.16.25
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
# Single-node RocksDB deployment. # Single-node RocksDB deployment.
replicaCount: 1 replicaCount: 1
+4
View File
@@ -36,6 +36,7 @@ resources:
# Personal (apps storing my own content, grouped by content type) # Personal (apps storing my own content, grouped by content type)
- personal/paperless - personal/paperless
- personal/radicale - personal/radicale
- personal/rhema-claw
- personal/syncthing - personal/syncthing
- personal/media/photoprism - personal/media/photoprism
- personal/notes/notesnook - personal/notes/notesnook
@@ -47,6 +48,9 @@ resources:
# Production (public-facing websites/apps) # Production (public-facing websites/apps)
- production/buildpath - production/buildpath
- production/saggar - production/saggar
- production/get-saggar
- production/get-rhema
- production/rhema-site
- production/semery-fr - production/semery-fr
- production/umami - production/umami
- production/vhaudiquet-fr - production/vhaudiquet-fr
+1 -1
View File
@@ -12,7 +12,7 @@ spec:
name: derwitt name: derwitt
namespace: radicale namespace: radicale
chart: radicale chart: radicale
version: "2.1.1" version: "2.1.4"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: rhema-claw
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: rhema-claw-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -0,0 +1,6 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -0,0 +1,7 @@
apiVersion: v1
kind: Namespace
metadata:
name: rhema-claw
labels:
app.kubernetes.io/name: rhema-claw
app.kubernetes.io/component: ai-agent
@@ -0,0 +1,24 @@
# Tracks the rhema-claw chart as CI publishes it on main: the timestamp
# pre-releases (0.1.0-YYYYMMDD-HHMMSS) all sort above 0.1.0-0, and the
# chart's appVersion carries the commit SHA the image was tagged with —
# values.image.tag stays empty to ride it. Same rolling scheme as the
# saggar release.
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: rhema-claw
namespace: rhema-claw
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: vhaudiquet
namespace: rhema-claw
chart: rhema-claw
version: ">=0.1.0-0"
interval: 1m
valuesFrom:
- kind: Secret
name: rhema-claw-values
@@ -0,0 +1,11 @@
# The vhaudiquet package repository on the home Gitea — where the rhema
# CI publishes the rhema-claw chart on every main push (base version +
# timestamp, ordered by SemVer pre-release rules). Public: no auth.
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: vhaudiquet
namespace: rhema-claw
spec:
interval: 1m
url: https://git.vhaudiquet.fr/api/packages/vhaudiquet/helm
@@ -0,0 +1,69 @@
# The rhema claw — the resident agent daemon from ../rhema.
# Single-node by design (one SQLite store, one dispatcher): the chart
# fails the render past one replica.
image:
repository: git.vhaudiquet.fr/vhaudiquet/rhema-claw
# Empty: follows the chart's appVersion — the commit SHA CI stamped on
# the pushed images.
tag: ""
# Bearer token for the /v1 routes (/healthz stays open). The daemon
# shells out through the coding agent, so the surface must not sit open
# on the LAN. Encrypted at rest: the .sops.yaml creation rule scoped to
# this file adds `token` to the values encrypted_regex.
token: ENC[AES256_GCM,data:fZKJzLy8FjN+0ONrHn40Tgb1/uTtYdAWTJwY7BfFltsGCPnuMx1F8KIPfQbzliyH,iv:yzaHrdDrSBbnT01aJmv8537D1lVe4kwIDINiuOgXPKU=,tag:dT7Z5v3CUhJg/+BqcjAWIA==,type:str]
# No provider, model, or credentials: the backend is selected
# dynamically (nothing injected, nothing pinned) — when a dispatch or a
# chat turn needs a key, the daemon resolves it through the rhema
# config seam, not through this release. The nulls erase the chart's
# built-in anthropic/claude defaults from the rendered claw.yaml.
config:
provider: null
model: null
watches: null
# The chart's own ingress, rendered from these values. Plain HTTP on
# purpose: kosmos.lan is LAN-internal and token-auth-only, like every
# other .lan surface here (no TLS story for .lan hosts).
ingress:
enabled: true
host: kosmos.lan
className: traefik
annotations:
external-dns.alpha.kubernetes.io/enabled: "true"
persistence:
enabled: true
storageClass: longhorn
size: 5Gi
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
sops:
lastmodified: "2026-10-10T11:49:22Z"
mac: ENC[AES256_GCM,data:vz3cATCAOEoyXOJCz0u+GfIq06lV5sV3mUoOKa4lUOWnShGOnxxE+v60AslV4KYBfmSCVliTalM0Vm8isuqJSAd9ZdPaI0CZ9F0gkxza22eaESkapIcIYrAhJYcZnRBSyAXjdVHyIzlvVwyTEqWYvEW7F5MJUgc4igHFD1/gMIA=,iv:VxsYzAWGhOiLXCt68Mpu8N9xgjsXXgc2LnInv2BExV8=,tag:rICLpdj4D37QZtTNV91uWA==,type:str]
pgp:
- created_at: "2026-10-10T11:49:22Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//WeO+shUgWwJAu2IdxVteea0IpFCyo93hWqxLWMytqF7+
3h2s7zXXsNvNCvqndHzNSrZt+OuSQDWSBVIzfxlztw7ga6BdI92OhpOZPCIyKwDT
LzzUCPrSAGOZVekOkFXKlVDjMFunAiEp/soGda7bbP+VrdHJmeRh8fioTOgd/4qL
/QmmJk3bMTlMoVcknOW2qI3n79YA9qnI0vjwBL63bDeZnxZ8CiZzd1SDr10K0rDf
f9ErcmeKAwm+HgehSA3xId0Cph4gnf3xNhNDe2gcZvoFlPIrZT0iU0fBzMRuJPxt
c9g+TqTAHBfx90H58/NF8Sfr3ScXNUHvHzgzrq4w+ogqmp8NYsdDbzG1C318dV2o
nITluENiYgR9Qs6gJda94aEc00IYEBp4lNGp5G1SyHiDB+jMMsiHX6w3x286dgNx
G6DcJ+TabCO+A+Fzq74I2ds+paoEgDegDMCIgK6uSKF0jT2ID579Bf2kRraneOqV
amgBI2CQZG5FAqdhbtpf4PHAK9YR3b42mgF9nBAc+f/oFeAZm8nFmG7LubwxqbgY
HLa7+ct38ygp/pwZ0FQcU5I3VwqYyU+JA3HMsL2yspHJAeQuXAvzkCQ8NaDOMpEY
JRY1pIHl3SwTkV3zh9co8r2Ho8fGYO6KzlNfEdRsx2C6DegM70kpPuYzcCDYAd3S
XAE6EX2dM+NxYqhHEIwKjFMJlROWwhhRhheFZnyYRMsn75NkeqRfPi2tJgMkIMk9
OJ1eekhgFbQr8vaWtrIOhjvQG9ieg2ujuyltVcC2XUFxQONCxbfoXC2oYu1Y
=gTTK
-----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|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml|token)$
mac_only_encrypted: true
version: 3.10.2
@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: get-rhema
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: get-rhema-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -0,0 +1,6 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: get-rhema
@@ -0,0 +1,21 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: get-rhema
namespace: get-rhema
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: rhema-dist
namespace: get-rhema
chart: rhema-dist
# Same CI scheme as the other vhaudiquet charts: timestamped
# versions on main pushes, exact versions on v* tags.
version: '>=0.1.0-0'
interval: 1m
valuesFrom:
- kind: Secret
name: get-rhema-values
@@ -0,0 +1,11 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: rhema-dist
namespace: get-rhema
spec:
interval: 1m
# Public org-scoped chart repository, same one CI publishes the
# rhema-dist chart to (from git.vhaudiquet.fr/vhaudiquet/rhema.rs).
# No auth, unlike the saggar org repo: the vhaudiquet org is public.
url: https://git.vhaudiquet.fr/api/packages/vhaudiquet/helm
@@ -0,0 +1,58 @@
# get.rhema.rs, the rhema distribution (chart rhema-dist, repo
# vhaudiquet/rhema.rs). One single-node Garage, one bucket, the
# saggar-dist shape: the S3 API stays cluster-internal (chart default,
# s3.ingress.enabled=false — release uploads come from the in-cluster
# runners) and the bucket serves as a public read-only website.
# The host MUST be <bucket>.<root domain> — Garage resolves the bucket
# from the Host's first label — so bucket `get` on get.rhema.rs.
bucket: get
garage:
# Single-node store: skip the hourly self-sync cycles — while a
# full sync runs, S3 auth lookups transiently answer
# InvalidAccessKeyId (see get-saggar). Weekly.
fullSyncInterval: 604800
web:
ingress:
className: traefik
host: get.rhema.rs
# TLS terminates at Caddy with the cert-manager get.rhema.rs
# cert; Caddy proxies to Traefik by host, so no tls block here.
tls:
enabled: false
# The write surface, public via Caddy: the release runners reach the
# S3 API by host (the in-cluster Service name does not resolve from
# them). TLS terminates at Caddy, like the web face.
s3:
ingress:
enabled: true
className: traefik
host: s3.rhema.rs
tls:
enabled: false
secretName: ""
sops:
lastmodified: "2026-10-16T06:56:14Z"
mac: ENC[AES256_GCM,data:XuFKJcXb2C22x1GaADmX+QwQNAeUiYsmSh4g0Z5CTyvIXSI5gksAVKNgF0RqRNDLDmDA1jGCS+a0Y//ExXZO1kKQj2jYdYcKU4IvOmniMiwut5ZtobFbuskv7boAxmNRT/Y/4RgyyT8+45b/2+u3i9u2cwSQQ0Itvh5PxpFlE+I=,iv:3qXS6rEkeodOwLt5AOx8atfr15fK1zpmkM8uKjxUB2w=,tag:1Y78Jq8E44IGukCpR99UwA==,type:str]
pgp:
- created_at: "2026-10-16T06:56:14Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+KleFpAm4wpwoyB8U15o27ys2KXyKNFUl0EeRhYBYjcqe
wgtiayZjGbM0Tz2x9+SFLQhezldMlH8N5l0BscuYBMAUgDXS9OMN+v/1nHk0pu43
FUYHEWbYmYgngzGKuQhdrGEEtNBH12oKcBVwIPG7zaTfAlhfZIq/xsh6QyfTZX36
mSzUsshYPmqUM+RymH/PrJjpWz15XBdFUiY59+hNa9kqjalyTg0gijuu6JkKbYTK
SnFd2i9Ud/meniC4oBlLyOc0PX1/uyeIY1SFbGHdwBcHCFdIzMow2fZWLzimsNyB
GIO31PbyhG3ZCb2cOzYC0XqJUdP6lHbAyDBDiGWu+dBupDb8d96XeaIF0cTgOjxJ
0FrDMk1OAc1HjnhGo4QrEPMT0vMJmRDcDWXp60pFycRIrjGyXItMqkW06Xlr5HvF
OM8q3gjz6s7/Yi80EHKyFEHsvLl8jw2OXYhSiUEy6mSfii5k4Hhs2PBJFKcxLqZA
tH0caDA4zJia8FdlaTHI9OE33TvP/9uxvY9kBJUaeMdLxCo4T0keOiam2b0K/H8N
owIhdVJmXtsAFiw+t7KKZku9kQtkav8hEn1G++VQXL/XUjxvv3CewDq9cbNW7aIU
byjUf4jPR+kI4TeyR01YMDP2+O5Ld0/NxlCKqF10w8KVs1OsWFBagC7I4iPy99XS
XAEWw3W3SSGkz+9t2cqmXTxCPIvU0ANjkz8PoNAfx9HC3UWk3So1MGht0FDR9QVZ
AOzPM4U43wnYrTp1sq4N9Xh7xU2m2e7iUt/g2dtRFvx0vv2qMt4ianqzYiB0
=1619
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*key|.*crt)$
version: 3.10.2
@@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: get-saggar
resources:
- namespace.yaml
- packages-auth-secret.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: get-saggar-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -0,0 +1,6 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: get-saggar
@@ -0,0 +1,38 @@
# Basic auth for the private Gitea Helm repository (org `saggar`) —
# same token as the saggar release's packages-auth-secret.yaml. The
# pre-commit sops hook encrypts this file (name matches *secret.yaml).
apiVersion: v1
kind: Secret
metadata:
name: saggar-packages-auth
namespace: get-saggar
type: Opaque
stringData:
username: ENC[AES256_GCM,data:bQ8HUwCqCEIWKQ==,iv:FFcNqBTrA2xJCD2EUf2k+8f1+8DZC9r7Z14Qns0TjH8=,tag:aKWUHSP+8yjbewr/vt3z8w==,type:str]
password: ENC[AES256_GCM,data:bfiHI6tHwtK1qYf9UdAplb5qNE7fceQDjUim3KlWU/sb4Q5mvqK6CQ==,iv:ZtRNqfWZLT1lSd/N9MGwKrRiTtKDBUBZUR1LUy00G40=,tag:f55oMGmPHQB8zMNWtChp+w==,type:str]
sops:
lastmodified: "2026-10-04T21:14:09Z"
mac: ENC[AES256_GCM,data:pbOlIPfHMwbwyBHlwkTYwWSeWD2jxud2zlNYMDyYJmKRpUuf0/erqRUusTrVGUnOG1t7omu+hQycPC3im6v8mi0vECBlkVG3knQa46bnVH9m1qa7lVChuP53TLYZogrOA8Ol9omrLsUsdcPNJfwXTYS/HHkY+ujECnjCWiVoXUs=,iv:Al2lU2xt1Hvv1BokoOx5e1gOlJhxzMJNyyCosmlGDV0=,tag:OxMxotEvYI06Fjjwst++gA==,type:str]
pgp:
- created_at: "2026-10-04T21:14:09Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiARAAgsXy5zMBbREVADgr2VVGgev6fHJUXq6DKCRhQdH1nsrI
xbSN1HZ2UbQjCYCjZl8NdVo3KGhJJ1uQGABAq6ZE+C4ZaMWvfjEO0/CnHmui8LkL
YXvJWWKvP/DDcmLXYxgwP8u/EWtn1bgXN7HeHxYb9JtGEf7XBlS9a6InWDmreabF
lSGkl79NgWDIngNQwTvby76uVARSAj3TkIxO6f4cVx+2f/c7KvWvX9D5vjrz8dpk
tPFdIhsCHdQS2wf2G3fEp4Yb8WnTEgu/HQ/amYwBAplhv3aaFQ0WVxCB91amnJyw
4Hnkcim4e/ZTmlBms/iQMFo+NhcHebRYcganIid23U8j4RfptwbuxED/txDEAAbj
lrgpknUXDG9RRRFTZfViYVJ4KWNduuUmVX4URYtn9d42BEXlXwx+Cd7FV40mlM8F
aT87F8G3IVexcKqLV15RngswCaCNJOnIT1vNNz18hz6sz8qXCzDwKIsS02wzkchz
1E8pi4grh2UkJT/F+mHUnze3ADOIZu6c2+SUwswVi+zAQg566dgFMYfKWc7icbvz
AWJ0hatHKNC4utZ2C0sCrM/34M0J507UMjlGKY9FUQ7wnHubPMfrum/FBNH1X7jM
F+iWsZ4N+kBnpY1Vf64S+97/Nqg5NZ3IBHWyqaSsWmR/h9628XDAa7kUpIsPK2LS
XgEGwyBsqJOWaYa7pXhIuul+1iNTJJ5FhU9qFQci708gund3RSvGJLtUIGlwSLUn
qzSSfl8vWujLNj9Pb0FcegVTYAq4eA59rJFILjyRZ64TaIfPBYxdFSD8t4zcWQQ=
=oHWG
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*key|.*crt)$
version: 3.10.2
@@ -0,0 +1,21 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: get-saggar
namespace: get-saggar
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: saggar
namespace: get-saggar
chart: saggar-dist
# Same CI scheme as the other saggar charts: timestamped
# versions on main pushes, exact versions on v* tags.
version: '>=0.1.0-0'
interval: 1m
valuesFrom:
- kind: Secret
name: get-saggar-values
@@ -0,0 +1,13 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: saggar
namespace: get-saggar
spec:
interval: 1m
# The org-scoped chart repository CI publishes to — namespace-
# scoped like every app, so this release carries its own copy of
# the repo and its auth secret.
url: https://git.vhaudiquet.fr/api/packages/saggar/helm
secretRef:
name: saggar-packages-auth
@@ -0,0 +1,50 @@
# Chart: https://git.vhaudiquet.fr/saggar/saggar (chart/saggar-dist).
# One single-node Garage, one bucket: the S3 API stays cluster-
# internal (chart default — the publish workflow uploads from the
# in-cluster runners, s3.ingress.enabled=false) and the bucket serves
# as a public read-only website. The host MUST be <bucket>.<root
# domain> — Garage resolves the bucket from the Host's first label —
# so bucket `get` on get.saggar.dev.
bucket: get
garage:
# Single-node store: skip the hourly self-sync cycles — while a
# full sync runs, S3 auth lookups transiently answer
# InvalidAccessKeyId, which is what kept failing the edge job's
# prune step. Weekly.
fullSyncInterval: 604800
web:
ingress:
className: traefik
host: get.saggar.dev
# TLS terminates at Caddy with the cert-manager saggar.dev
# certs; Caddy proxies to Traefik by host, so no tls block
# here (same as the other saggar hosts).
tls:
enabled: false
sops:
lastmodified: "2026-10-06T04:20:10Z"
mac: ENC[AES256_GCM,data:ncXYOdUYTaYikkKWVUzWinakZVV7tjja31QIo/xhibZ8Jc9L/dl9U8//xJ95Hlb9uuMJvUHvk78KmH2mYVQhfhyNwkNZXvK3o3azx+WWQYaZebEudRbXdHO6gyywcoywlEFuaVWjVsTpggz2VtlNwP/tqLCf41uTUJB4NZi12uU=,iv:uj13/y/iGeoyqgnx74wh1Pzb01NupeLW55qBhCBNleM=,tag:PGmmMZCw49wt8RmpJH1CzQ==,type:str]
pgp:
- created_at: "2026-10-06T04:20:10Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+MH/izXRcAzwF1Dp5mgQBthTFYX01sUpjU9y5Z9jeRnny
UgtCuURwaI41nG+ZOrv3yy2dSsgABMgr8nZZEju/Tb+jZ/qzkPR8JWTpiieXefH4
Q5lEy6l1rLVOJudsgx7BG07h6gqr0Mu89gcpFThkXiCo5eAV/hlY9Y6eG6ZybWZ/
K2bUv8JB09S8ZsuFsTqp87lZMogWFcIjO8JMirjWRxgd+1NZFoGmSIb+6KkLTD2+
eMjbLnGZ3HyWLSzJBRkF5bGgODNGA8qaHmKKMTT8/H9zD1Z++nKCrx7SQpoStQxw
xluXAyefTiwCqhEVT42C68Lhz5pH6AyHgJGmls/NWv6bvj/3AQwXlkO87Xkd8x3L
aEDHIc5rEso18IZuNzlI193AEhipT8mcMi8IFA4YbnVnkK86PSXQ7qWrbbc4BmkN
cU/vUlpBM1HeiYdTFZf8Dvfw55bNn/pMhPhoLWpHjAnAEDJdrVh33OTurdmtYTRW
nRK3q2WVHa+UGlkKfdpKr1ivZ9O4ulSfyIYKVsLI5sYAbkJ4o6ytlcQlK6E/7AEK
Ux/KAnTb5nXOLN8Vbq0xGlyjYei0GY+IZWkkWL80k59NFfrDLXtG/zCxE74ANplm
qx+dCbggjT2lNsM+homldhYU0VhDnvrWM1/9bRI3DUVUxfGUCKMTqUj2b97vLGDS
XgHGOTHKKTQjpEg7DnnSS/romTxglHrAEa/3Cu4S4uUVIK7aL8JIoHXYaHho6Jp1
9RpCscjyeMfE/wnyTbeR1OZ6wnIMuLXzVzma0fy0fbYqGhJllULpMgsZGe6bhpI=
=MIya
-----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|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml)$
mac_only_encrypted: true
version: 3.10.2
@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: rhema-site
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: rhema-site-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -0,0 +1,6 @@
nameReference:
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: rhema-site
@@ -0,0 +1,21 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: rhema-site
namespace: rhema-site
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: rhema-site
namespace: rhema-site
chart: rhema-site
# Same CI scheme as the other vhaudiquet charts: timestamped
# versions on main pushes, exact versions on v* tags.
version: '>=0.1.0-0'
interval: 1m
valuesFrom:
- kind: Secret
name: rhema-site-values
@@ -0,0 +1,10 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: rhema-site
namespace: rhema-site
spec:
interval: 1m
# Public org-scoped chart repository, same one CI publishes the
# rhema-site chart to (from git.vhaudiquet.fr/vhaudiquet/rhema.rs).
url: https://git.vhaudiquet.fr/api/packages/vhaudiquet/helm
@@ -0,0 +1,42 @@
# rhema.rs, the static landing/download site (chart rhema-site, repo
# vhaudiquet/rhema.rs). One stateless nginx Deployment.
# TLS terminates at Caddy with the cert-manager rhema.rs certs; Caddy
# proxies to Traefik by host, so the ingress stays plain HTTP (same
# shape as every other public site here).
replicaCount: 1
ingress:
enabled: true
className: traefik
siteHost: rhema.rs
# www redirects to the apex inside nginx, so it rides the same
# service; only the host name differs.
wwwHost: www.rhema.rs
tls:
enabled: false
sops:
lastmodified: "2026-10-15T20:28:50Z"
mac: ENC[AES256_GCM,data:jDNsyWKl2WhofVTzlgevHuPoLZUrLTW87Wd+dLv3nWEFWfN3G8fy0IKGbns1NpFyhx/OfqDJjlmDeZyt4dfmRUPC3Y1MI3kd4KUGlKf0lPy94MTJog7DZtVGtS0RUCN7/NevqtopIivj38u1dXjdcRI+F8bL91blf+RHvvvGOe8=,iv:pmVYVtNhczWqk8CLrAP2McUTrn8uTE88LC9oKtYQzf4=,tag:s+TXQDFqipQtfkE/BN2ASA==,type:str]
pgp:
- created_at: "2026-10-15T20:28:50Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//df2F/yV6AzsAeDXunqgf016/km+/O8b37+WSaoB7UHb0
f/3lqxoVD9EWaTLum1pwHbhauDrjsOyyqkmIbEeOdnMQjEhDvnjfkDbTDupwl7Qg
m95ozoUsprhlqEu61ANhAx5xOHfelV5hkL5+ef9o3o0Ist2T8uBv/v+KxnbCHwmQ
e2/rjZ9BF8JgnhYVN3VKnpCgz2k9DVAdIZ4saeaET71MCK2naaO8BcVOH86H2Kn6
croIE0V/RNPBL3V0PDF804jRIPwfwd0sQiSwwpo11a/9Zgfwj2PDft1FPFyRv7Yt
iy5RaJ8rY8C2AqxRj1V0QIp6SyT784yhW02//8zZOA3Mcs9RUJfBosbqQDb3KIPx
MMNNgA1/Fa+7VWI7UX6/24tg2m7MPSCRLvzZMWzriKvcKQj/A0fn4pgcQfQ5wqnm
v/VrdLL8PBfy2dkYAsBvx4mAt11sOPwoT0iFhxInLNGeGsteJ5/texgLmJ/uO6vx
jJLJT8izFKqZKJCK5Db/Qx8RuiuGysaS3NiWVKfdWrwlbNsMKeRFMEaEAfKjPOPG
+1WQcvi+jHfCWsjimxW2+Cs90ZIUY3lbGLuQWhFj8zynQt5rehCZzqjmtx6MbHRT
GdDZm62Ox1sdMq1ZwMVElWelyNSTtPNN53DcEEiTGqaSwJjdLz9WZhcjMl0vE5rS
XAGm3AzBcPNFtWEODV1AyXwOUPea5RJ7ZNOOPy7jTrV0sZwJ8TAc67VP9IW8n1CM
22ri2Xq2qDidxsCKiQeaF77DN2YhBYJnxhvfeplVcKGyqb/EElDznR/fprDR
=IpGk
-----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|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml|token)$
mac_only_encrypted: true
version: 3.10.2
+27 -21
View File
@@ -13,8 +13,8 @@ image:
imageCredentials: imageCredentials:
create: true create: true
registry: git.vhaudiquet.fr registry: git.vhaudiquet.fr
username: ENC[AES256_GCM,data:QijNVgCz8hF0Kg==,iv:eredumkfDLZ6AKM8nCcZwl14EyRRnBvXLL52Yaau0d0=,tag:P/miR7dyjGaMxqM/g7r0ow==,type:str] username: ENC[AES256_GCM,data:Kb01bICyN/BvDQ==,iv:o19woAl9Hqlouo3fgmj6fesiix1bo6fPRcZdE3W55bk=,tag:LzBjc/dOaFv1yUblzAmFBQ==,type:str]
password: ENC[AES256_GCM,data:SY3i9j6rBFh5RfehxBQX+ljVe11cGL1cRNkiFqcNbBlNkF9uqMC9hQ==,iv:qpHKDwzQDr8uTJN9e7OgUr/JN2O+EGJylbH/R+EU9tc=,tag:2DbOvUUTsrNfhIzhjirz/Q==,type:str] password: ENC[AES256_GCM,data:Phft0J0kFY71+icAEP2OuwGOfkNwMv64Yd0mWJkgVXWEJRyczAorZg==,iv:SeM4FVIwAqXxT9P6uUyftehk/eL3Y2JY1beGbruO0mM=,tag:Dezoea9JnN49laU0q+H3Bg==,type:str]
# Login via the home Gitea: the engine is the confidential client of # Login via the home Gitea: the engine is the confidential client of
# the provider and runs every code exchange, so its discovery drives # the provider and runs every code exchange, so its discovery drives
# the endpoints (issuer verified live). Credentials live in # the endpoints (issuer verified live). Credentials live in
@@ -29,9 +29,15 @@ auth:
providers: providers:
- name: gitea - name: gitea
issuer: https://git.vhaudiquet.fr issuer: https://git.vhaudiquet.fr
existingSecret: ENC[AES256_GCM,data:lvGugwt7hGbPGF9JSn88B1c=,iv:1Zqze/jXv8kuVNdGdJB9PwvMFHWBihIsEX9jJo7DQvg=,tag:gSgFdyI7HfAj8dwoGd2kbg==,type:str] existingSecret: ENC[AES256_GCM,data:hqjfc89icY+3fOSMzh0xJ0Q=,iv:K+g5gpi8vcBpw6buktSZlePj9p4TGRV6bxuvSrFx2i0=,tag:FljiBjxAFrQON4J4iqk50w==,type:str]
clientIdKey: client-id clientIdKey: client-id
clientSecretKey: ENC[AES256_GCM,data:6vvWWtiomj1TpNJ41g==,iv:xb9HfW2MQNs9vLmPxujUV8us8Tce08L3si1Qd/CCwWk=,tag:LQdV0f79n9NqKBOrh6DDTg==,type:str] clientSecretKey: ENC[AES256_GCM,data:b01cCxpLg9d8ECChUQ==,iv:IMU1G+3hEyqS6jU7eWpgvQE7/ndLbH5gkbydFisCQeM=,tag:xs0ehG08oU15/N1hN9AHug==,type:str]
storage:
garage:
# Single-node store: skip the hourly self-sync cycles — while a
# full sync runs, S3 auth lookups transiently answer
# InvalidAccessKeyId. Weekly.
fullSyncInterval: 604800
ingress: ingress:
enabled: true enabled: true
className: traefik className: traefik
@@ -71,27 +77,27 @@ docs:
tls: tls:
enabled: false enabled: false
sops: sops:
lastmodified: "2026-10-01T17:39:26Z" lastmodified: "2026-10-06T04:20:10Z"
mac: ENC[AES256_GCM,data:1pn1rHaCx8eYYR6NPt6hgUEwDxRYQQtgkklSu6FroH92gUq2jhX3420lzboTMvvpuBF/vqjbuw1sIR60YfZZ8R5ahw7CCcv8L5sfz9DhUU/vMBYF6r3HDY70AnXkPK3+rPw6ZofB8h+Y/DQEBpPe/LeDEPCOGQjIml349yAvMIk=,iv:A6/PeL8JuFtzS0hMAiP2/dvbXq7Ob3o9VaA0pE2IWEU=,tag:GV2pspKqmaQjafkp4HUwSw==,type:str] mac: ENC[AES256_GCM,data:ztx2M4srmnZs9S86xWOYSkePbi9Gm1n0FIB9oBmiaEn5fzSmPLbbn8IPcRsU+zOjkg5DRZ4LbuNdtmxynTC20yCHpb2vZbIUFiQarxPizI9lcKZyyOXFjoECXYZ5oDEOkAPrvYWTduqvK5o9dsUmebtKCSh9EMVMD47nF76yr68=,iv:Y2DjchwTfIjWMDGfQNwXCxM7MG6iNwU6LHf276osNjM=,tag:oviToaqWMdl1/cDgYX9M7g==,type:str]
pgp: pgp:
- created_at: "2026-10-01T17:39:26Z" - created_at: "2026-10-06T04:20:10Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+PFcuCPKb5Mpej7uym38cwwVgjaJoaeLrKpfWBw4CEy3v hQIMA7uy4qQr71wiAQ//Sgir+7MRZYnuxGArDmyeP57A3xL6F77pLZbNIOjQ6KcK
PbJgTS7kNKyjHqoeHQcLZZwmms1//b7XQfX2kPnNJIo/06cAgYv5AJ4etMNJ3hys 3Giga+m3n2BodCDVzL6bUOtUbtgBVyqD7SSBY4qQ2a9c/H4xBAO0HciDth4O1Wer
ShuiTMmMayKg2U8TdMhzwKFgymhQ5PUzGU1Xg2D9J1hUgW/rRVOb5wHKsBgYkOIx z8fKSphk7tt1yBtzuB1tm0F9Ye53tLaetACXRGGo83jCGse8J0d4+vimra45fjyn
ufuQpPhNm9j1xOqWtnf6xCRbZ1HRlE6mAX+4TvRJk/x3U1YW1gI2neyEtFiuCsCj 9JEnCl0+A2AMMl9/hcfCj8iSj+VeiCJz35Zmo+BWl0KrY0DHAeEyBEtI7O+z8bFF
PSO9W+5WovDLQlCmGRmCweUwODShpdVqBEoXSS3wjGihz9xKH3lS+NnPZVMoeurE 9oGZY/xhTVD4IkbOqXs1fatTmybyzxrTBz/I7d9QOnPx7N08rb/g3KspkCPDSptH
kzHjTxQgv4ZLDo9OuXcZz5mlXju9tmvkpLpqP1oHnN+es6Ks0jIpZcvXaZvvF4W5 h/AnDGg0PDVs7WK0eMwFMsZ8gvEYI76ecf6mAO5x6TbpxVHCPXpbbBTC7ro7usB0
CLsC9dDplvAA3IpiF6+vpdDL0/QHpxo61V4jLLqO6o84x2jD1odR+zSkmxUxaQ94 4jVLrALMtsMn8k45JWFGR3OsujPr1D+yGmsJ2Mqde4AtjE6zTs8TurwuDEY0ivYg
hxlPY+DGTrvHV0qOWlWLLZO6ddwOqeUC6ntBiZu3FG3UwTwPv9YXvi+ApP4Lylov HvAKk6C+ZOmdQEMep2kznSovMx0m6FP8Muv0ORX+pMNOIRhUFbEAXT+s7J7YoLlf
BNKaCxKLalD37BKcPrpaJBwucME56Ny9p0WbHUaBNv74UGIKqPl6BI+9z7oObsrT Rza/lf4VgsWtTUyUZRTH3G2NTwEgBo4GsV6bM07OhN0GEgMH1hOuGo61C+e2d6PR
YfmcB0Wlpz8N6SHntYJDhLJktJ27csy6BTPjQsFEK/dHbGyR5X4CiBSehqGd400s NqeRgvlzfmeoTUBwgNv023739hyB2xDVesr5jo/yomikxFiz0wGUBQ4eRZmRZSjD
bomyLdR7m3g4fFG7Qq9Wzh8MA2WC6Fx+ExUXz91xrsejEJhckUl9N0sQDdCO3trS ZCLoiv+2ymROgWzGqgutRiRD150P45biMs3zW/x3qGP/SiTj35OYyCzMjQb/ZRjS
UQFWjDQEh9LAJ3U/nQ0SWjaNnJ25U0qJ9qMZYyDDR2aiMqRAwcOZc315S+S/FrGE XgGHEtiiRWv954k5eXRF3DOHxrZ/oxtjyc4+EjlS3VsgtOCjePSzKg/WQa8Zx3ns
lMkMngLiKqznm9GSsgcBgRIcqovbJr1gCJS/b2+4abjQtw== MT2BKgtlFwM2eG5V7jHfHOmAuVIuH249iyER5AJDzot/0kAO7ekH/y72kfloDKk=
=gAn1 =3vCq
-----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|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml)$ encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*PASS|.*SOCIALACCOUNT_PROVIDERS|.*\.ya?ml)$
@@ -80,13 +80,13 @@ spec:
- longhorn-system - longhorn-system
selector: selector:
matchLabels: matchLabels:
app: instance-manager longhorn.io/component: instance-manager
- resources: - resources:
namespaces: namespaces:
- longhorn-system - longhorn-system
selector: selector:
matchLabels: matchLabels:
app: engine-image longhorn.io/component: engine-image
mutate: mutate:
# `request.object` is available in BOTH admission and background modes: # `request.object` is available in BOTH admission and background modes:
# the backgroundController synthesizes an admission-like request for # the backgroundController synthesizes an admission-like request for