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
32 changed files with 543 additions and 50 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
creation_rules:
- 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
pgp: DC6910268E657FF70BA7EC289974494E76938DDC
- path_regex: .*.yaml
+5
View File
@@ -23,6 +23,11 @@ zones:
- config
targets:
- cloudflare
rhema.rs.:
sources:
- config
targets:
- cloudflare
saggar.dev.:
sources:
- 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
+1 -1
View File
@@ -1,6 +1,6 @@
services:
n8n:
image: docker.n8n.io/n8nio/n8n:2.43.3
image: docker.n8n.io/n8nio/n8n:2.26.4
environment:
- TZ=Europe/Paris
- N8N_SECURE_COOKIE=false
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
version = "0.81.0"
version = "0.119.0"
}
}
}
@@ -143,3 +143,67 @@ spec:
- 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
@@ -127,3 +127,23 @@ data:
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
}
+70 -42
View File
@@ -10,7 +10,7 @@ image:
repository: caddy
pullPolicy: IfNotPresent
tagSuffix: ""
tag: 2.11.6
tag: 2.11.7
service:
type: LoadBalancer
# Cluster (not Local) so any node can forward to pods on any other node.
@@ -36,44 +36,61 @@ health:
volumes:
- name: vhaudiquet-fr-tls
secret:
secretName: ENC[AES256_GCM,data:16xnpbPT5Q3QPhiOVW09rO4=,iv:rITfPR/pb9otdRXURijM9l4eOyjAm/LpMCVzDI1HdiQ=,tag:XTt5U79sfX4F7gL3pdfCIQ==,type:str]
optional: ENC[AES256_GCM,data:ghlFPw==,iv:nZ6HKGVI7z0R7ZDnxdKCFdAtPrUCYTPc6C3ahLhi05o=,tag:zKbUifBUjU2haTMIldoKhA==,type:bool]
secretName: vhaudiquet-fr-tls
optional: true
- name: wildcard-vhaudiquet-fr-tls
secret:
secretName: ENC[AES256_GCM,data:HFV3Bw6giG42LsVv7NHQCNbsk0ewFftMuNE=,iv:lhlMGwLwaKTjXwqErw/bsSG6zRuc9lfwwF9Ru/WiFG0=,tag:gU4IW396EUuiZUdRIz5neA==,type:str]
optional: ENC[AES256_GCM,data:NSoRKQ==,iv:0xYJ3X2fajkm+KuXLB67nzKJtlszZz/iLlpPBkPgsGc=,tag:pQ0P4pak230kfNvxILH7Hg==,type:bool]
secretName: wildcard-vhaudiquet-fr-tls
optional: true
# semery.fr certs from cert-manager (OVH DNS-01)
- name: semery-fr-tls
secret:
secretName: ENC[AES256_GCM,data:J7uLCquEggEP2naKHg==,iv:8RudvW7ki/DkWZwVHd1AXAt+6YrLrOpXotQDh9vwgp4=,tag:1PzTWbWEqKUdhlwRcctpGQ==,type:str]
optional: ENC[AES256_GCM,data:1q/Bng==,iv:jEnPnyR3pCV0CL8hK+NfMxH1LDKSRyansf6GZDshzQE=,tag:TzOXcGF91InOrCdCCm/Bcg==,type:bool]
secretName: semery-fr-tls
optional: true
- name: wildcard-semery-fr-tls
secret:
secretName: ENC[AES256_GCM,data:5n5namMP+KepRLRQZgvzlr9hEzNmvQ==,iv:Xnh7FIAVaxQ1Mxd8+en8bM9ueFsG1ujxh472mQhqFFw=,tag:omVRURP2KbSEyHsUqUhfCg==,type:str]
optional: ENC[AES256_GCM,data:0GArbg==,iv:1wW6BFk6Vs2y42iIniy4YbMFBOYdqwXop2WCEldwBBA=,tag:gmZlb7zIh3W/0L3qg8XQCQ==,type:bool]
secretName: wildcard-semery-fr-tls
optional: true
- name: buildpath-win-tls
secret:
secretName: ENC[AES256_GCM,data:CTR7I92zQSaOKCcLPGnAs4Q=,iv:egtHKvBbs1dJsMgoIFK+gyOnC7ZX/3UfaAGIDkryd+c=,tag:vk3xGP8YeXhQSi6QLk+3Ww==,type:str]
optional: ENC[AES256_GCM,data:nOml1Q==,iv:viRMNPrBLmm8IfJDqcfWOuyMx/y7eE0CTMYjWmK5/rE=,tag:VpAuffCx/VqP2X947l/p3A==,type:bool]
secretName: buildpath-win-tls
optional: true
# saggar.dev cert from cert-manager (Porkbun DNS-01)
- name: saggar-dev-tls
secret:
secretName: ENC[AES256_GCM,data:5eb4Fv9OJqjbPuxT1/8=,iv:ZsOSvoCc9+ZtTVboRKJBRR8FITk3gowa/uylv+mfA+k=,tag:hkoQ8QHt9evQfDUT4rq51Q==,type:str]
optional: ENC[AES256_GCM,data:iac+qA==,iv:hf1rDOHE3frRL702sotOP8akjBi20mRTXQ6vlUb4Ac0=,tag:+G8rgN61c5agYmbJsldqrA==,type:bool]
secretName: saggar-dev-tls
optional: true
- name: api-saggar-dev-tls
secret:
secretName: ENC[AES256_GCM,data:5NJaLtBQizRFNbF5IS2YbEmF,iv:lTJkrES8y7/QO73p7G8RG/CmxGedyXAvfrK3Q26OtU0=,tag:92P2+010Isgg3SQjYwPBCw==,type:str]
optional: ENC[AES256_GCM,data:3ax/5A==,iv:CvLi5JqkXPfq9+jVA/Q+mpdEZJ7UosxzZAR1aArpDbk=,tag:yOsLJuqtCrvg8YneJRUeoA==,type:bool]
secretName: api-saggar-dev-tls
optional: true
# docs.saggar.dev cert — the saggar book (static nginx)
- name: docs-saggar-dev-tls
secret:
secretName: ENC[AES256_GCM,data:xDf3adcsj6i0FJ2kAc5UxnVE3w==,iv:+qGMWJKoQo/MjibTR9mbgX3T6/xwr+vq1U+ef14xXfs=,tag:Y2jZHktvL8RKUacSv9JDJg==,type:str]
optional: ENC[AES256_GCM,data:wEEiYQ==,iv:zNWY0N5935+biGIjIl+q5XPyLLX7/ABhnwHsp4FEZpM=,tag:v8trm6fiM5q/T6EOh1fxcQ==,type:bool]
secretName: docs-saggar-dev-tls
optional: true
# get.saggar.dev cert — the saggar distribution host (garage web)
- name: get-saggar-dev-tls
secret:
secretName: ENC[AES256_GCM,data:iFG9+7bSIUgFZpm8h5Tc362g,iv:Wm6cW1+ehjoylvjwSE3oT0VcQFZONq9znpfi2w/wP9U=,tag:UoEXdJzWoVX6/g8UtbByzQ==,type:str]
optional: ENC[AES256_GCM,data:t8VFbw==,iv:Imo0wBOb9ufS9YPqtTegEHQFnyhgSYmcg2FHEzBkW9I=,tag:19zicABMKqAR/nDr85WpCw==,type:bool]
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
configMap:
name: caddy-routes
@@ -106,6 +123,18 @@ volumeMounts:
- 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
mountPath: /etc/caddy/routes
readOnly: true
@@ -130,7 +159,7 @@ affinity:
- weight: 100
preference:
matchExpressions:
- key: ENC[AES256_GCM,data:RTux56Pd/U6b6MLk5uRUC2YXP3w=,iv:K/9+Mh8dyp9DOumKFLmZFHXqjxzhhYEKKSnXRc/Pb2A=,tag:fk03mWjQEQPCdALb2gEMdQ==,type:str]
- key: ENC[AES256_GCM,data:AsOdq9OGQbAGV42W4d22EGVMi5E=,iv:U3sLu8pI7fqOPbvpfpVz21cUfwovKRFi8jY6laTyStY=,tag:EQVSFAzTYw2En2xdGTCF3Q==,type:str]
operator: NotIn
values:
- "true"
@@ -144,37 +173,36 @@ affinity:
topologyKey: kubernetes.io/hostname
tolerations:
# Tolerate the failover taint so caddy CAN schedule on p330 (small-node-1).
- key: ENC[AES256_GCM,data:JPKKj4UA7JWi,iv:0PNgCHVFO2bywVfcXrOrcTQpNjz2TUUM0RrBmF6godw=,tag:h27cJ4dd9C1iLKgffNLVfQ==,type:str]
- key: ENC[AES256_GCM,data:s3X0PmRJCCVh,iv:UYZl3EsmdSTdF9NoYsL+zbxLlkfO2GU80Sy3CpSXMBY=,tag:35UtC37ldCItR9fAtSXVVw==,type:str]
operator: Equal
value: ENC[AES256_GCM,data:7dtvTUy+xUI=,iv:pQdnyz5X+gQB0DOFFxs5D+2RAPD8xl+hgJFwARcbBWo=,tag:A321CiM+q8tLJJyanRn/Ww==,type:str]
value: failover
effect: NoSchedule
- key: ENC[AES256_GCM,data:t71fVLGG7y2am6kXa3DcpGt76uZJ+cOuYZKiaRF2LljtRCxzpw==,iv:Fa0zVUsH/TbWBbL2foIsvq7UQ2kIcA3yNvG2qMuGnng=,tag:KchzYUpe4Z6JIZCvSM2ztw==,type:str]
- key: ENC[AES256_GCM,data:NYCyZsj7wMxKUjaDu+rUOQYxDKvvEwSWuDAxQkSGTczXyApCbw==,iv:3AcvLXryeZ6dfmqanFpGOgEf1nGuEVbvUmZzruxzL98=,tag:Daa9AgXQZkkr7RIzljWOeQ==,type:str]
operator: Exists
effect: NoSchedule
sops:
lastmodified: "2026-10-04T21:14:10Z"
mac: ENC[AES256_GCM,data:vv4/zTp8LHusfYtM4xUwKHnesHu49VXfhRmKPo/nB7ItGYATsD5PtnXrGluOkwng/5pvRVs5WCtLt9fdZ9k7aKsfFHisi2OylEkx76xcAQ1f8GOCNkvfnjVuPEbaIZK1Mvdepbe1oZ0B4m5I2KqfvnUpXzmG82vNq0hj5vlQ1uM=,iv:7mKc4OBbPUYuLXer5f1OZcHggJBOu5rD/luh64in5lc=,tag:ch1Nvtyfa94AI9tAOm81hw==,type:str]
lastmodified: "2026-10-16T07:06:11Z"
mac: ENC[AES256_GCM,data:kMIxep2WVIr8/uAiw12T1JXMbtpyijo1c1MOOUKuok2Z1zSrnFZovgIup3u8/2BhqJ2UUDm5hFJi41Tsq45ba5ELs4PX1whi6EXlHQJxNo7ScfepEi10es/wa+p+3w9V8Yv9cklIWk14zh0UABs8jRzOJXhn5XI3O644CJSULQA=,iv:3ssxqRNRvXbmn0HiQFdwoGVbsnzvtQxfpHPIUpplMK8=,tag:5VRyB/Hh4tZUWp6KCPNSQg==,type:str]
pgp:
- created_at: "2026-10-04T21:14:09Z"
- created_at: "2026-10-16T07:06:11Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+Io9dFjaXDz2CSdPjMBiT8ISxnUxZ9F3VX+bqKg9nRusr
slx5VsHGCsfK4DyF4GXcqsyDPkz6v39ehhUFdseZewg1AbYTNy9RIEgeSo3fwcnO
bee48z1Nti+8F3h+4O2ao+nGx4wSS6MYO3oO5vV5a4oNKe6T59X7eGT30uohatO6
jo6UuHu3/e7eyzK7/iSF3SemtkZ1ZiXOgKKeBXashrp+2vDdY+3ow/pRpFyohqWh
4mBt8SyCWOsf0BUdNZfJPDO594hwTjrrRIsmBeXde97rFXKBDd5tPR9tjNlihWsw
lC0e4331jvwns+rlSOASBX/BVsqVGh8nw/5XWxqW3oMqjvolgofGhP8CtFQkUuoq
VoHcgQd79wo0Q107wcp3ftMak010/NweAER1CFtCDBE6DAS05qaaOwwM3erusaw2
ZY/ezGULEmSgZ8RA3HHjtxo1ExLMZ+CpPb0mAAamql8O0uCpLl0TRkWvR4zwpo2K
ojOTW2dLjhJwJaodAMnKQm8mWtegC8Uektw1RdYCbCTD4sKv9vkxymnSLmE3dvWD
Htp/hCSTqDCc0sSBDdagIZWo8VtdduWqeGG7+Qs1wY+NizSlYRDmEsahbgPk9Bcu
W7vhpJFZ/98jxEmgaiUVJ3BVqZYiJBdDk4GvSw+/QmyNvd39xNLXIN3DcRTLmqvS
XgH/TZt96utCGDUjYFAFw4s4UL3EhttfDe+hSwzrAcslhjyeCORFhYrnwOncCr51
tr+maBFPip6FgASJQjDVnxtw9zFDfurbx8W2wk9uh6w3qw4jbGDq9wsI0wvfous=
=C10g
hQIMA7uy4qQr71wiARAAuN5nBauJiH5bFx80iF2W2XJDwMCFG+SPlqv2ErxVaYkD
kSt8pA0o4Bzqr6gP6cEgEhzQHAVVvsvTZJTY5lX6KWNRxhz/RXDhxAi9xdBHQ81f
dDWn7pgD8sv8cODM39yeukhGlHxZuk7FiUJ4fBnouojWUCxf2Ib5m5TEaWwmmv5n
EBBjjcbGZzyWBzCkLbEY/ML1FIx5j/jyZjpjMp2En1309ljIBckjLk5s9Kntp6oJ
/TkW/BhU96y8fyGM6u3FV54wORNlCT3P5cDT4rsQd+KgG0DDchAdUSb7hmBEn+iC
W/eUsp7nhObkZZBjTKYeS502Q+3RUEXoLnVLWougDxMSA1rJNS3nkgzK1cmKs97/
Ghnb5TUGPmoQMUltQzxInDq1mgeGfuFUffprYprYKGeVC/oQ6uPHE4jVZImlWRjv
w6YPHv/2XhWMN5vH/ybsrqxcFb5+1z8u8J58GAJ37hDXzkL8ENJUouonM3sywaBc
VbXHzJwYEuLhRfNpay6ovwPkhU25gV3atBiXloIWc0PivPjOAJqqs0vkMgRiA+3R
yUagVKdyavVUhqou2LOxSGSv77uFPWZwhqUILtqzTeSE6GHUxVqKQPa91klRRNI7
YWNtM7ZqSeANK99h5vgphhPZpuKkIzXHSLEXdplxvaRERfWMU3UGCDZOMVcDMlbS
XgGovkHZ9+NKVgZVpsRyQQutbSJqvHVZJx162gu3UKC1IgnDnhslOGKVWw/oKNb5
KyPf0CLk9BCAlSngr5D5pw4GJ9eq7RNFOqC32LPwXgNSD1AfLFHYGWh3RZM+81w=
=eA3w
-----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
encrypted_regex: ^(data|stringData|.*key|.*crt)$
version: 3.10.2
@@ -22,6 +22,7 @@ spec:
dnsZones:
- vhaudiquet.fr
- buildpath.win
- rhema.rs
# OVH solver for semery.fr (via cert-manager-webhook-ovh)
- dns01:
webhook:
@@ -12,7 +12,7 @@ spec:
name: cert-manager-webhook-ovh
namespace: cert-manager
chart: cert-manager-webhook-ovh
version: "0.9.17"
version: "0.9.18"
interval: 1m
valuesFrom:
- kind: Secret
@@ -7,7 +7,7 @@
# Container image
image:
repository: stalwartlabs/stalwart
tag: v0.16.24
tag: v0.16.25
pullPolicy: IfNotPresent
# Single-node RocksDB deployment.
replicaCount: 1
+3
View File
@@ -36,6 +36,7 @@ resources:
# Personal (apps storing my own content, grouped by content type)
- personal/paperless
- personal/radicale
- personal/rhema-claw
- personal/syncthing
- personal/media/photoprism
- personal/notes/notesnook
@@ -48,6 +49,8 @@ resources:
- production/buildpath
- production/saggar
- production/get-saggar
- production/get-rhema
- production/rhema-site
- production/semery-fr
- production/umami
- production/vhaudiquet-fr
+1 -1
View File
@@ -12,7 +12,7 @@ spec:
name: derwitt
namespace: radicale
chart: radicale
version: "2.1.2"
version: "2.1.4"
interval: 1m
valuesFrom:
- 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,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
@@ -80,13 +80,13 @@ spec:
- longhorn-system
selector:
matchLabels:
app: instance-manager
longhorn.io/component: instance-manager
- resources:
namespaces:
- longhorn-system
selector:
matchLabels:
app: engine-image
longhorn.io/component: engine-image
mutate:
# `request.object` is available in BOTH admission and background modes:
# the backgroundController synthesizes an admission-like request for