Compare commits

...
Author SHA1 Message Date
renovate[bot] d703fcfbca chore(deps): update terraform proxmox to v0.116.0 2026-10-10 04:01:29 +00: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
vhaudiquet 89420bae2f saggar(kube): set the device login's web origin (auth.uiUrl) 2026-10-01 21:25:56 +02:00
vhaudiquet b8879b2025 saggar(kube): expose docs.saggar.dev
The chart's docs book (static nginx) was up in-cluster only: give its
ingress a host, with the same edge path as the api host — dns A
record, cert-manager certificate and caddy route.
2026-10-01 19:39:26 +02:00
vhaudiquet 32207635fe gitea(kube): raise limits to receive a kernel tree
index-pack on ~12M objects OOMKilled the 1Gi container mid push, and
500m of CPU stretched the receive for many minutes before that.
Bump to 6Gi / 4 cores; the node has ~40Gi free.
2026-09-30 23:03:47 +02:00
vhaudiquet e6ab21317a traefik(kube): raise web entrypoint read timeout to 5m
Traefik v3 defaults respondingTimeouts.readTimeout to 60s counted
over the whole request body, so large HTTP git pushes get a 504 the
moment they pass one minute. writeTimeout stays unset: a cap there
would cut long-lived SSE streams mid-flight.
2026-09-30 23:03:42 +02:00
vhaudiquet ae8a4ddb27 saggar(kube): deploy
Flux HelmRelease of the saggar hub (chart saggar-hub >=0.2.0-0,
CI-published on the gitea saggar org, appVersion pinned to the image
commit) with the web UI. Engine on api.saggar.dev for the CLI and the
docker/apt registries, UI on saggar.dev — new cert, caddy route and
dns A record for the api host, TLS terminating at Caddy as usual.
Login via the home Gitea as an OIDC provider; private registry and
helm repo auth share one packages token.
2026-09-30 22:30:47 +02:00
vhaudiquet c83b4550ed Merge branch 'main' of https://github.com/vhaudiquet/homeprod
* 'main' of https://github.com/vhaudiquet/homeprod:
  chore(kube): bump chart Helm release cert-manager-webhook-ovh to v0.9.17
  chore(kube): bump chart Helm release notesnook to v1.0.38
  chore(kube): bump chart Helm release stalwart to v0.7.19
  chore(kube): bump chart postgres Docker tag to v0.20.6
  chore(kube): bump chart redis Docker tag to v0.35.4
  chore(kube): bump stalwartlabs/stalwart Docker tag to v0.16.23
2026-09-28 01:24:28 +02:00
vhaudiquet 50d992b727 saggar.dev(kube): deploy
- cert-manager-webhook-porkbun via Flux (chart 2.0.7, octabits fork)
- porkbun DNS-01 solver on letsencrypt-production for saggar.dev
- porkbun API credentials secret (sops)
- saggar.dev apex Certificate + Caddy site block -> traefik
2026-09-28 01:14:58 +02:00
vhaudiquet fc6db118d3 dns: manage saggar.dev via porkbun provider
- new saggar.dev zone (apex A -> 82.64.154.58) targeting porkbun
- replace '*' zone glob with explicit per-zone targets (cloudflare
  for vhaudiquet.fr/buildpath.win, porkbun for saggar.dev)
- CI: switch to octodns/octodns image + install cloudflare/porkbun
  provider modules
2026-09-28 01:05:00 +02:00
renovate[bot]andvhaudiquet 7e5fa8a5b5 chore(kube): bump chart Helm release cert-manager-webhook-ovh to v0.9.17 2026-09-26 19:34:36 +02:00
renovate[bot]andvhaudiquet 30845bb249 chore(kube): bump chart Helm release notesnook to v1.0.38 2026-09-26 19:34:25 +02:00
renovate[bot]andvhaudiquet 52ac77a74e chore(kube): bump chart Helm release stalwart to v0.7.19 2026-09-26 19:34:04 +02:00
renovate[bot]andvhaudiquet e189bc66ea chore(kube): bump chart postgres Docker tag to v0.20.6 2026-09-26 19:33:47 +02:00
renovate[bot]andvhaudiquet 008238922b chore(kube): bump chart redis Docker tag to v0.35.4 2026-09-26 19:31:12 +02:00
renovate[bot]andvhaudiquet 82d646d399 chore(kube): bump stalwartlabs/stalwart Docker tag to v0.16.23 2026-09-26 14:19:15 +02:00
43 changed files with 796 additions and 68 deletions
+5 -1
View File
@@ -12,10 +12,14 @@ jobs:
update-records: update-records:
name: octodns name: octodns
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: octodns/cloudflare:latest container: octodns/octodns:latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install DNS providers
run: pip install octodns-cloudflare octodns-porkbun
- name: octodns-sync - production - name: octodns-sync - production
run: octodns-sync --config-file ./config/production.yaml --doit run: octodns-sync --config-file ./config/production.yaml --doit
env: env:
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
PORKBUN_API_KEY: ${{ secrets.PORKBUN_API_KEY }}
PORKBUN_SECRET_KEY: ${{ secrets.PORKBUN_SECRET_KEY }}
+15 -1
View File
@@ -7,10 +7,24 @@ providers:
cloudflare: cloudflare:
class: octodns_cloudflare.CloudflareProvider class: octodns_cloudflare.CloudflareProvider
token: env/CLOUDFLARE_TOKEN token: env/CLOUDFLARE_TOKEN
porkbun:
class: octodns_porkbun.PorkbunProvider
api_key: env/PORKBUN_API_KEY
secret_key: env/PORKBUN_SECRET_KEY
zones: zones:
'*': vhaudiquet.fr.:
sources: sources:
- config - config
targets: targets:
- cloudflare - cloudflare
buildpath.win.:
sources:
- config
targets:
- cloudflare
saggar.dev.:
sources:
- config
targets:
- porkbun
+17
View File
@@ -0,0 +1,17 @@
---
? ''
: ttl: 600
type: A
value: 82.64.154.58
api:
ttl: 600
type: A
value: 82.64.154.58
docs:
ttl: 600
type: A
value: 82.64.154.58
get:
ttl: 600
type: A
value: 82.64.154.58
+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.116.0"
} }
} }
} }
+28 -26
View File
@@ -30,10 +30,10 @@ postgresql:
global: global:
postgresql: postgresql:
auth: auth:
postgressPassword: ENC[AES256_GCM,data:AGdZp0KNk6+v+w==,iv:dc7B8GYA1hlC6VgO1m3jdHimIVb4QeR1DTmh9kqRDa4=,tag:JEFWOgvgvUDJ+S9yS446cA==,type:str] postgressPassword: ENC[AES256_GCM,data:4Kd4qz3DuJboaA==,iv:I9K1+j2tv7MKel9ej2/AED0JrxIfeb3D1xdDKCS+jTs=,tag:MpQ0NjglUvGZXzeOQjIj3Q==,type:str]
password: ENC[AES256_GCM,data:kuR59jqrN/YFmA==,iv:qAIwiTzi2Fr9R9fIc3sfPqhIHSPI8K3eNmed8DBm7PQ=,tag:hf7CMUissSbO4RVn+kRUJw==,type:str] password: ENC[AES256_GCM,data:YX6VvEJWfkO0dg==,iv:ixQkW2q7Y9YRIGMIbqWclA5q9Ufw+lNS7Gc4Wd1toiY=,tag:krGDeY+E4+PUjowt8jKAmA==,type:str]
database: gitea database: gitea
username: ENC[AES256_GCM,data:rCEYTAA=,iv:zeWzB+vpMl+oGUfQRPYFneLwnXF7Dlg4XAYB4QynAyk=,tag:zqJDiBiKJJIDgNKdOtGlMg==,type:str] username: ENC[AES256_GCM,data:KvdO0oE=,iv:vFYOVlo2kvOHOhASDlccTfcpsgAkS6YXOLCm5sDcxaQ=,tag:9J6Dmc3vYpHlFSggoGVmLQ==,type:str]
volumePermissions: volumePermissions:
enabled: true enabled: true
primary: primary:
@@ -77,8 +77,8 @@ gitea:
oauth: oauth:
- name: Authentik - name: Authentik
provider: openidConnect provider: openidConnect
key: ENC[AES256_GCM,data:LekdKlJJX6AYZX2PgooenJtANvE8HNdzePN9yeljrnoKV7pbexDnAw==,iv:pZm4+Dj2uqprBRIgchq78nEzqkC/zVoiyRK0cj98WPo=,tag:iSiuwP8N6BBVeGWS54j+dw==,type:str] key: ENC[AES256_GCM,data:F0AGCSAkU2ZWmS4jniL8k32ABwrjtURAPLa3RKOCpJoaMkKRlRrqwA==,iv:vQcD73C3itBqKFEiv8PhLD2G3exC0zc2NDE3LGYpvXA=,tag:24nO98pP7a00sTBDWEMsBA==,type:str]
secret: ENC[AES256_GCM,data:J7WJghH6Xp9Fg3Y+PO1lN1mEEJ0HbVSM1YP2d8//NX2xmYK/PK1y6xSVQ4+VSsYTZhIAM3ZXVrBE/5smuNLUZkoj2EKY275fXcN2kOkEwiftdsJHSKdevCtO57TQipJToh6mfLxz51LDxpz85rVNj4Rvra1d9UvC5x1nUBm8AR0=,iv:lMiMQGsKn4ZxFctakj5MyVlX+8Wu93d5wM9cIqEBhSc=,tag:CkuTAGJqg+dUzyP9z5gwzw==,type:str] secret: ENC[AES256_GCM,data:0/6XDvRXUnQXrJzivtDS6b+mmYjtOVcHhGmQJPFG1zDyO9BksHKau0D+hIsfM85761U7LAISct0HungGNeOQOULnmvVT8hEIgC21RHjArXztJY2964NS5XXfURc7pVxOJ7LSDFFd4azExwhrTktqmerG+F6SI5V/oq2iYYqJA7o=,iv:ShYcIgyccHvEFhVn++gBR7gmMOEKcBz9sj/Y+4pk/Hc=,tag:SkFM2d06O/zhpfVji4QDKA==,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
@@ -104,37 +104,39 @@ gitea:
indexer: indexer:
ISSUE_INDEXER_TYPE: bleve ISSUE_INDEXER_TYPE: bleve
REPO_INDEXER_ENABLED: true REPO_INDEXER_ENABLED: true
# Resource limits for Gitea container # Resource limits for Gitea container. Sized to receive a full linux
# kernel tree: index-pack on ~12M objects needs several GiB and more
# than half a core (the 1Gi limit OOMKilled the pod mid push).
resources: resources:
requests: requests:
cpu: 100m
memory: 512Mi
limits:
cpu: 500m cpu: 500m
memory: 1Gi memory: 1Gi
limits:
cpu: "4"
memory: 6Gi
replicaCount: 1 replicaCount: 1
sops: sops:
lastmodified: "2026-09-22T20:35:36Z" lastmodified: "2026-09-30T21:03:47Z"
mac: ENC[AES256_GCM,data:xGtSdlGuJL3qSbnfbh/ON1q3c+n6l991fCy9t9ZLnrvSrU15vkK/WVHh84V132C72pEakwRy8nFcUl7KT3C3J2l2uJHJyDWDqA8NTvHq7FAcomKGKpNOqAOFXVUKSr6O4BtQr9x6h4jzAZSlpaTx3GEiLRzygSkZmcEcaXZ6/hU=,iv:JfQ3W3UZV1m1SkapNmUpZ1lkxgTs5F0auXukupK/yAg=,tag:xCNpJUc5mPv2dBhS+ob+fA==,type:str] mac: ENC[AES256_GCM,data:eHMr2BqfWNI32S14XEivXtXSIRiCBCAQz06mwtbNyXc1dI6YgF4pKdyIbfRWQW0ZYcbvqKxtyugao+lhc24Ds/GgIbdwchlMyz/DyuOQtM5GMHcSoInQUQVGzrM8hSyztKzq10bH0DmKvT68+uaVx0hf6rzxEqLRb3GAk4q3310=,iv:5kJ6bYE/54EbDWctSXBcVTjJtc/J3mV664tFD1WTK90=,tag:AAbHK3njH0PCqw9yjSWevQ==,type:str]
pgp: pgp:
- created_at: "2026-09-22T20:35:36Z" - created_at: "2026-09-30T21:03:47Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/8DiM04ZZ18qFndWSlo+hHV05hlt7GmwG9dx/3xEXgpdEb hQIMA7uy4qQr71wiAQ//Vf2Rdp8NG4AsbIIOiXabY3AzLyVbE9Pn52+FBF+NIfkS
TkA3HNi5rUMvA8j/mStmP4sZiqrxlPk9sdMtVsPAppT3qAihcF3DyyUFYkSoY3oF XDqlgvMAWHtmV2LzvJPwPIUjCZkoRwmDsh9zi+W1XzHh9kKxzwvIxfjiqm8fwJh8
Et5qeeC6DP1aKdsgAQVVZyeLy7l/CbO5CYORm5+TuGmnr0HxN1qZimbF15pspvNN gb4a/y5mkkEqs+H0zE1H4D91dPbfOmDABJKaePmWTB+tc48bY6qX+LYs7hkPwsHU
9pprI7XDKb6QEbXhADN9gafNwTIQgv3LGQVdoQgfyzZEcQR8O5bxUFTwdR9LO646 sN64cidbIbzBoq0t1TWZFkl6MZYWX9IyqJE1XcqYDAvwxlJ4JMJH2pGQlY8+7U96
zogHuQfPC70jpA2IRxdBHuSTjDkZimyehsKPzq7MpBso/85q3q1TlSQKJsjxZWrZ YQgbXhuAik5IzNQlmdpq0mt0j3KZgM7KbLJ2en6JAiO0EhD3xKbFnC0bPniUEX2c
NBKmEhL/Q4M+8mj+N/aVFJldIUF2Juto5d2BUuIG/lBtNL2QHdiJN3Rxc1gL4qP2 Yv6Z/1NrmNImCwbOkrNF9sqto4d9VHFDH8udSHKCXcSbzJmkfF4XUOBuNxtprmQV
eZYESQ6IRXAycUXAQgMJf5p/lhgmVjv8b3lhKSFJq66hZyo5g6wdhLIEunPglNbP Wlcw5ZMFpnOgRn+V2gb0Cd3cm5rje0QAYCgIGUfduvMm9BReAQTvpUdKkqKs0mLr
BcJXUbl5SScTgOAi9o/soezUuggvzgg3zwM38PAghve1/j0rL7EupYX+u2v7zbUH XiRAG0HfjjGNcVqWA0H0L5UxlVwHJh6zSNHDzTPVlGenVcQSpiUORKxZqANpQchW
BA7T30SnkvDCmTzW4+Sac1dg/w06u+4oSGTNnTuKOzmzfIjGlwkJeAtPVcvSFAgK /wtFghatZFKbbzEz6Mo5C3hMKOXjl/VNWsmva8BoloDKPm9pWH5S4x0ExYiOWSOk
TCKDmvtkPWUxGrxjBbJZUwqCp4HEOwOp6HeGeNbWFZ2UU+JTvTizkxbReN37Q4+f Yk9j+twTgJXMeptO55qMCJKl6CcRsbgVr5yJJXWC6I3tr2ssx1BnSAPYDviuhsC1
8oIyQuyRpDHgDV5IrbDtCcqWsEFpUXyi8snIMDTCkKdLZv1WjYhjoNmvOoRagQvS YAbgFlvdzE6n8FmTixVwzVZrTbZV7alz9PECViMP5evAphe3n1MvnLEvMM0WOm/S
XgEQDrDBeC3HZvUuvqMqgmHI+IEjmpad1CNVGE2q7FnAhFYutjBGF78co2X9t+ib XgG0Ty4hQ9ZD7gzhIrh06xVuh+MC/PaMYIZ7LBVHgQy8xbAgQH0qXkF39/9rCIws
B9o6aIwPzS4ANsh47rupGDBt/x46RCorCYhCaJm4B3v0+tYSA7mSBoHQwp1p+AY= A/D0FN29uXvfSWzlgSrGOj218eKHX9g+nZGIAHeejd/FJVnOKQpUboUlg/x3jqQ=
=kRPK =943y
-----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)$
@@ -79,3 +79,67 @@ spec:
- buildpath.win - buildpath.win
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: saggar-dev
namespace: caddy
spec:
secretName: saggar-dev-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: saggar.dev
dnsNames:
- saggar.dev
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-saggar-dev
namespace: caddy
spec:
secretName: api-saggar-dev-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: api.saggar.dev
dnsNames:
- api.saggar.dev
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: docs-saggar-dev
namespace: caddy
spec:
secretName: docs-saggar-dev-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: docs.saggar.dev
dnsNames:
- docs.saggar.dev
duration: 2160h # 90 days
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
@@ -107,3 +107,23 @@ data:
tls /etc/caddy/certs/buildpath-win/tls.crt /etc/caddy/certs/buildpath-win/tls.key tls /etc/caddy/certs/buildpath-win/tls.crt /etc/caddy/certs/buildpath-win/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80 reverse_proxy traefik.traefik.svc.cluster.local.:80
} }
saggar.dev {
tls /etc/caddy/certs/saggar-dev/tls.crt /etc/caddy/certs/saggar-dev/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
api.saggar.dev {
tls /etc/caddy/certs/api-saggar-dev/tls.crt /etc/caddy/certs/api-saggar-dev/tls.key
reverse_proxy traefik.traefik.svc.cluster.local.:80
}
docs.saggar.dev {
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
}
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
}
+63 -32
View File
@@ -10,7 +10,7 @@ image:
repository: caddy repository: caddy
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
tagSuffix: "" tagSuffix: ""
tag: 2.11.4 tag: 2.11.6
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,25 +36,44 @@ health:
volumes: volumes:
- name: vhaudiquet-fr-tls - name: vhaudiquet-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:HYQb37rKxMqxFTsCz5kw6qY=,iv:dI9uqUVLLqPv3a5vwz1vowTvO9WduQaXqj7XZREd7oA=,tag:mz257AC3pvubgzOMxbHfrg==,type:str] secretName: ENC[AES256_GCM,data:16xnpbPT5Q3QPhiOVW09rO4=,iv:rITfPR/pb9otdRXURijM9l4eOyjAm/LpMCVzDI1HdiQ=,tag:XTt5U79sfX4F7gL3pdfCIQ==,type:str]
optional: ENC[AES256_GCM,data:k9FVxw==,iv:XMAGop2PvSGD1R1cy6qqE39bsIAOFIqGzTnwDmYRhHM=,tag:7zZAwSzRWWiT9Y2iMWkI6w==,type:bool] optional: ENC[AES256_GCM,data:ghlFPw==,iv:nZ6HKGVI7z0R7ZDnxdKCFdAtPrUCYTPc6C3ahLhi05o=,tag:zKbUifBUjU2haTMIldoKhA==,type:bool]
- name: wildcard-vhaudiquet-fr-tls - name: wildcard-vhaudiquet-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:2OUkq/AMuv2wQyIlLPS3bSRrnV1mvDR6vd0=,iv:1e9HC8FFC4vo7GjCnJyNjF05R+Js41ONy2in5a+/doI=,tag:icKdtLhvQ40YI+KCE+6fXg==,type:str] secretName: ENC[AES256_GCM,data:HFV3Bw6giG42LsVv7NHQCNbsk0ewFftMuNE=,iv:lhlMGwLwaKTjXwqErw/bsSG6zRuc9lfwwF9Ru/WiFG0=,tag:gU4IW396EUuiZUdRIz5neA==,type:str]
optional: ENC[AES256_GCM,data:b+zvMw==,iv:QyU+T1BGZenO/nO8wq6R+KkrT/I6ZXIIhAnf5npFhvw=,tag:4UPyop81BQu4zxhZmK2n+Q==,type:bool] optional: ENC[AES256_GCM,data:NSoRKQ==,iv:0xYJ3X2fajkm+KuXLB67nzKJtlszZz/iLlpPBkPgsGc=,tag:pQ0P4pak230kfNvxILH7Hg==,type:bool]
# 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:cLzhXgUhrwgIMACU1Q==,iv:DJ+6mjtjYmWxNcHl1gzeoifpcFCJsXiOXeyxEWnRU3g=,tag:7yc2bt6fBWwBuefPY48xyA==,type:str] secretName: ENC[AES256_GCM,data:J7uLCquEggEP2naKHg==,iv:8RudvW7ki/DkWZwVHd1AXAt+6YrLrOpXotQDh9vwgp4=,tag:1PzTWbWEqKUdhlwRcctpGQ==,type:str]
optional: ENC[AES256_GCM,data:DTfxaQ==,iv:K7TJjSI/vF3x34SWmwmivYo+mSsUAg9nB94Ui85nHCI=,tag:1/JRBMlb07+aHKEulIYpQQ==,type:bool] optional: ENC[AES256_GCM,data:1q/Bng==,iv:jEnPnyR3pCV0CL8hK+NfMxH1LDKSRyansf6GZDshzQE=,tag:TzOXcGF91InOrCdCCm/Bcg==,type:bool]
- name: wildcard-semery-fr-tls - name: wildcard-semery-fr-tls
secret: secret:
secretName: ENC[AES256_GCM,data:Qq+ybi1kSVdVn9RP/kTkTcw0lkao3Q==,iv:vFmV3YvSNhLizgJVBnq1ZERqDP70onuZDvy/I3joPtI=,tag:AiEW+yh51Dexz3Vha4MPgg==,type:str] secretName: ENC[AES256_GCM,data:5n5namMP+KepRLRQZgvzlr9hEzNmvQ==,iv:Xnh7FIAVaxQ1Mxd8+en8bM9ueFsG1ujxh472mQhqFFw=,tag:omVRURP2KbSEyHsUqUhfCg==,type:str]
optional: ENC[AES256_GCM,data:0o4ODw==,iv:VwnCs2C1MVUJEfBvNJT1rkDV7m60sNZPdtERo9wWPJk=,tag:oo+liLatrjqEtlrKQyjhyg==,type:bool] optional: ENC[AES256_GCM,data:0GArbg==,iv:1wW6BFk6Vs2y42iIniy4YbMFBOYdqwXop2WCEldwBBA=,tag:gmZlb7zIh3W/0L3qg8XQCQ==,type:bool]
- name: buildpath-win-tls - name: buildpath-win-tls
secret: secret:
secretName: ENC[AES256_GCM,data:SejgJvZY/B7DDgf3YJcxcFA=,iv:bDZWhie17exL+9r9A7Ea/a8Rgpex7nuabVtW60LotJQ=,tag:WxqFbzulxxPgsynqfo5hzQ==,type:str] secretName: ENC[AES256_GCM,data:CTR7I92zQSaOKCcLPGnAs4Q=,iv:egtHKvBbs1dJsMgoIFK+gyOnC7ZX/3UfaAGIDkryd+c=,tag:vk3xGP8YeXhQSi6QLk+3Ww==,type:str]
optional: ENC[AES256_GCM,data:nBNRkw==,iv:JEvsFzMli7AzUj6GXJlHXOnANm45gnFE/kXrSbBotPQ=,tag:Puss6mCkoC7SGCb86guI2w==,type:bool] optional: ENC[AES256_GCM,data:nOml1Q==,iv:viRMNPrBLmm8IfJDqcfWOuyMx/y7eE0CTMYjWmK5/rE=,tag:VpAuffCx/VqP2X947l/p3A==,type:bool]
# 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]
- 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]
# 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]
# 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]
- name: routes - name: routes
configMap: configMap:
name: caddy-routes name: caddy-routes
@@ -75,6 +94,18 @@ volumeMounts:
- name: buildpath-win-tls - name: buildpath-win-tls
mountPath: /etc/caddy/certs/buildpath-win mountPath: /etc/caddy/certs/buildpath-win
readOnly: true readOnly: true
- name: saggar-dev-tls
mountPath: /etc/caddy/certs/saggar-dev
readOnly: true
- name: api-saggar-dev-tls
mountPath: /etc/caddy/certs/api-saggar-dev
readOnly: true
- name: docs-saggar-dev-tls
mountPath: /etc/caddy/certs/docs-saggar-dev
readOnly: true
- name: get-saggar-dev-tls
mountPath: /etc/caddy/certs/get-saggar-dev
readOnly: true
- name: routes - name: routes
mountPath: /etc/caddy/routes mountPath: /etc/caddy/routes
readOnly: true readOnly: true
@@ -99,7 +130,7 @@ affinity:
- weight: 100 - weight: 100
preference: preference:
matchExpressions: matchExpressions:
- key: ENC[AES256_GCM,data:oCV218wXg+k2L/edhWv6qpiyiaY=,iv:Y+O2of2NCOvcjSwr0EenGns0BtpT+P6pjCzEZUIMpm0=,tag:kY/WyHJ4Jr5ZLMe6ZcT/Tw==,type:str] - key: ENC[AES256_GCM,data:RTux56Pd/U6b6MLk5uRUC2YXP3w=,iv:K/9+Mh8dyp9DOumKFLmZFHXqjxzhhYEKKSnXRc/Pb2A=,tag:fk03mWjQEQPCdALb2gEMdQ==,type:str]
operator: NotIn operator: NotIn
values: values:
- "true" - "true"
@@ -113,35 +144,35 @@ 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:K6vJkO2dpKRi,iv:b7NIPKTMYOxNao6KcSJUhsxKNRJ2J3ksEtmXkI8b0So=,tag:pMRmz17upWMTEZjwBRNyZQ==,type:str] - key: ENC[AES256_GCM,data:JPKKj4UA7JWi,iv:0PNgCHVFO2bywVfcXrOrcTQpNjz2TUUM0RrBmF6godw=,tag:h27cJ4dd9C1iLKgffNLVfQ==,type:str]
operator: Equal operator: Equal
value: ENC[AES256_GCM,data:4ULPtEoUhgs=,iv:ikqWRqRR9ki35QQ6VnMEzOgT0/e+5DggGP8w60BhW/Q=,tag:MW9lX8miIWb9nnbc0woZTg==,type:str] value: ENC[AES256_GCM,data:7dtvTUy+xUI=,iv:pQdnyz5X+gQB0DOFFxs5D+2RAPD8xl+hgJFwARcbBWo=,tag:A321CiM+q8tLJJyanRn/Ww==,type:str]
effect: NoSchedule effect: NoSchedule
- key: ENC[AES256_GCM,data:l7abu6ywKFevJdJod2Af2bj7XSfBJATL7UnfiUHrRJoCjBsl9A==,iv:xnUvzVX8z4doC+mQs1r0rNCSqaZ8KlXxr5Ee9FOFPjI=,tag:mnqCx9NSMSyeYwz57QFQIQ==,type:str] - key: ENC[AES256_GCM,data:t71fVLGG7y2am6kXa3DcpGt76uZJ+cOuYZKiaRF2LljtRCxzpw==,iv:Fa0zVUsH/TbWBbL2foIsvq7UQ2kIcA3yNvG2qMuGnng=,tag:KchzYUpe4Z6JIZCvSM2ztw==,type:str]
operator: Exists operator: Exists
effect: NoSchedule effect: NoSchedule
sops: sops:
lastmodified: "2026-08-26T19:28:03Z" lastmodified: "2026-10-04T21:14:10Z"
mac: ENC[AES256_GCM,data:gn90e5Gjq5/CraT7Cl43DVMIQukD798faKGbVO5IJlbpAuTwDrhvqnnojFq4R7LEEETtedpR3MRyqcnbfSWVruHoysebycL7EZJkiy7H36JmzQAOWKusshMF9kOyZIV6+AFfz8As/Mu4pF1p5+3jmgy6oOJn7Ewm0C930Gpa3gs=,iv:cf1UC/2NGBHtQgx6h8vRpMjeJRaAvG7ZznhErn2b+cE=,tag:3Ule+pq7pZHWA7NqhlgfPg==,type:str] mac: ENC[AES256_GCM,data:vv4/zTp8LHusfYtM4xUwKHnesHu49VXfhRmKPo/nB7ItGYATsD5PtnXrGluOkwng/5pvRVs5WCtLt9fdZ9k7aKsfFHisi2OylEkx76xcAQ1f8GOCNkvfnjVuPEbaIZK1Mvdepbe1oZ0B4m5I2KqfvnUpXzmG82vNq0hj5vlQ1uM=,iv:7mKc4OBbPUYuLXer5f1OZcHggJBOu5rD/luh64in5lc=,tag:ch1Nvtyfa94AI9tAOm81hw==,type:str]
pgp: pgp:
- created_at: "2026-08-26T19:28:03Z" - created_at: "2026-10-04T21:14:09Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/9FKZhqwE2RZcfsIeMOtAkOTf/4aEbrSzsHbEO8DP8V3Ct hQIMA7uy4qQr71wiAQ/+Io9dFjaXDz2CSdPjMBiT8ISxnUxZ9F3VX+bqKg9nRusr
rQBu/v8y1Hcu3fVU/OjVk/7QbEBjPNu1AJST55DBIWktnYUgSo4fIujvG54/hqwM slx5VsHGCsfK4DyF4GXcqsyDPkz6v39ehhUFdseZewg1AbYTNy9RIEgeSo3fwcnO
9u0iuA1EcqVzGDa+vLSqgmi4Oxbujs0Ytn7uQrefqkdAOjltKqvknebI9EBdSRUi bee48z1Nti+8F3h+4O2ao+nGx4wSS6MYO3oO5vV5a4oNKe6T59X7eGT30uohatO6
GjVFwysR6jHmIVf9S64vu4VsjfC7ju9MBYZniaKsJ1GOBhIjUZ6ogkYs5S2E5PJ/ jo6UuHu3/e7eyzK7/iSF3SemtkZ1ZiXOgKKeBXashrp+2vDdY+3ow/pRpFyohqWh
zE8cn79x61YLX74H+BAqnFcxbprtsCwMJPgyerfgijV6d+JpwT/6mp1VUrLe9Zz7 4mBt8SyCWOsf0BUdNZfJPDO594hwTjrrRIsmBeXde97rFXKBDd5tPR9tjNlihWsw
WEd/lVMlIcwnYCtIDAvuURvMP2OebWplr95d5V1Vb5Yywnl3M0pwkqL4dRiJISvk lC0e4331jvwns+rlSOASBX/BVsqVGh8nw/5XWxqW3oMqjvolgofGhP8CtFQkUuoq
N2rBQYvDfXBtJA7yTAkJ3PymrECKoFs6nspEBie/kDJmdRGv8s2aajzTTQ1qLAkP VoHcgQd79wo0Q107wcp3ftMak010/NweAER1CFtCDBE6DAS05qaaOwwM3erusaw2
FeJe0TcowjCCWMxk4W5DEoCh+PUA1HVo+/KmHjnIVgzdgxaeqT90VXwN8H7MPPeu ZY/ezGULEmSgZ8RA3HHjtxo1ExLMZ+CpPb0mAAamql8O0uCpLl0TRkWvR4zwpo2K
LKE01+Guue821h7GykkIhe9sf3nMGbI5rOiCcsVtgu5bODkRk8jXpXh1qdRAliuq ojOTW2dLjhJwJaodAMnKQm8mWtegC8Uektw1RdYCbCTD4sKv9vkxymnSLmE3dvWD
uddjy1mWEfdUHNBj8YxvZ8WOU7h9FyZjsYZB96n9du1vqcuuP5eTJDVuvjjtDuTK Htp/hCSTqDCc0sSBDdagIZWo8VtdduWqeGG7+Qs1wY+NizSlYRDmEsahbgPk9Bcu
fbXYQbxwA5j4akyI4AKJYLA0Y/lcSXc84r6q8IA52nZz6uQZExbkoc7PPX7Q/ufS W7vhpJFZ/98jxEmgaiUVJ3BVqZYiJBdDk4GvSw+/QmyNvd39xNLXIN3DcRTLmqvS
XgE0CWRS+0tk2oVANMVU31UrCvitttezjR6sUSAINh122a5kcmOfJzLlB2OqVKc5 XgH/TZt96utCGDUjYFAFw4s4UL3EhttfDe+hSwzrAcslhjyeCORFhYrnwOncCr51
wMAyvOYccrQMrPDX1WJE7agDOaqGUQcwuFnvqpHhe8q9Yg1uOUU4sK1R8A1Qs0Q= tr+maBFPip6FgASJQjDVnxtw9zFDfurbx8W2wk9uh6w3qw4jbGDq9wsI0wvfous=
=wlYf =C10g
-----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)$
@@ -42,3 +42,18 @@ spec:
selector: selector:
dnsZones: dnsZones:
- semery.fr - semery.fr
# Porkbun solver for saggar.dev (via cert-manager-webhook-porkbun)
- dns01:
webhook:
groupName: acme.saggar.dev
solverName: porkbun
config:
apiKey:
name: porkbun-api-credentials
key: api-key
secretApiKey:
name: porkbun-api-credentials
key: secret-key
selector:
dnsZones:
- saggar.dev
@@ -5,3 +5,4 @@ resources:
- clusterissuer.yaml - clusterissuer.yaml
- ovh-credentials-secret.yaml - ovh-credentials-secret.yaml
- ovh-secret-reader-rbac.yaml - ovh-secret-reader-rbac.yaml
- porkbun-api-credentials-secret.yaml
@@ -0,0 +1,49 @@
# Porkbun API Credentials for DNS-01 Challenges (saggar.dev)
#
# Create an API key at https://porkbun.com/account (API Access section), and
# enable API access on the domain: Domain Management -> Details -> API Access
# (disabled per domain by default; the API returns a generic error otherwise).
#
# The secret MUST live in the cert-manager namespace: for a ClusterIssuer,
# cert-manager reads webhook credential secrets from its cluster resource
# namespace, which the webhook chart's RBAC already covers.
#
# SOPS will encrypt the stringData fields on pre-commit.
apiVersion: v1
kind: Secret
metadata:
name: porkbun-api-credentials
namespace: cert-manager
labels:
app.kubernetes.io/name: cert-manager-webhook-porkbun
app.kubernetes.io/component: porkbun-api-credentials
type: Opaque
stringData:
api-key: ENC[AES256_GCM,data:OLTDhFnbK70gAsvMR/4iKjKr9ckEkbXhYfG4xgTWP2gjruI9HaNAWzSBJcmDyRXRSz18XnvnSlUy/P5VXG5S6uH84wg=,iv:DrOWWf5h1FLNg+emJ/MMp80k8u+A/2HzC07EmjcWORg=,tag:2ep8o1zmXNPV54Byq2Dl7Q==,type:str]
secret-key: ENC[AES256_GCM,data:wtGiMCpU8PqTXvH27l+tUvJLivuK/zZp5KePFSeYfjb3ieFszbnjWFd3xQkgtFM3HrmjhRaGWUEFOIEvgTTMDBDyL+k=,iv:iVxMwt6UtpMAqdZj13YUzr3/gDUVTJecyc4ptYvHyNo=,tag:R/tn/BrARGvXjL1EIHBCRQ==,type:str]
sops:
lastmodified: "2026-09-27T23:12:14Z"
mac: ENC[AES256_GCM,data:XWzKEL3qi4/KoKUZm1uEfj6GNW3ZLq71PDEyo7w2fHHmkgFMW/xwwXoBLRYFWVx3RvT82NwOCld/Savbs0qXY+Ws1AsgjklEim7MRyIjOKTT8Jkuh39WNCc+8C13yAHSrfPa3tEs10a8lk4nOaFxVn87zAnfnEt6LGt41+/HDxI=,iv:TxW4wJSqHVB9VH9pn/9lYsg8Og3JHTKRPHOrSjeAvuw=,tag:eKZkHptFhE95bPeNegTx8g==,type:str]
pgp:
- created_at: "2026-09-27T23:12:14Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/7BAr8vmZ9i0Www7U8EkhPqOi1g0MVD8tVyhnTptBbS4MG
irer3UAy7ktovNUso1/wljKif/b2Q8EK6Sawgv4Sv2jN8ShWewginRQ7DeRGtwNE
TkNnnZoIMQmKwUZq0NnTmStg0wY/bRDYrovGhvPO8F/ZebU/cEXRFdHDzsKsTo6p
9LOu8DnTj9CwvhBLCyzqCeMwvL7DZryXuTS+aEVnrS0J4OUydK4VKYsvwXVsF6XT
4Jkpcf4yAiwxBsnZiszvL+L1BPzku1peU/p/d1fciVq54TmgrRwyC7GrlCLm/f09
xEPLnBMtmp1w5M2aONEYXXrk5fMWLIuSU7SmFzWduwLAMPTfHvGbpIS4U8eMCuIy
THKmeuyPL4/BW+PIc/L/UucOF0pjPDAPsdw3dEkB0+MlX3YDuTc37PpiX3pMRy1C
kxhwRVNPZqWMjkrAqg0BR9ZHEOQiv+HwHXZNG5CSHaYYC/mJUSVGaL7R0yOP3nIy
cWDA6Pyk5XWLspVh534xQODm1oArMdZ+xnD6NUqt+Bv6facrZkmT6r66LnCLb9fQ
rTS1aDm4gxuG5SX7lafDWL9Rh+z2DgFDde9cEAJZiBna4lTE7tJFPHF4OolqzrnN
MEhN8no5bLcMv1knE2nKkeKmOoXEKQ80mwgcVkdiRtQf2eZWAXAmpkGehuW/nIHS
XAHZXogqlqxbGDtIe2dM0qun1OA0HxsGw5J2EcFUt53wSg/YaZdEPN6aARPdRi8P
qGCEhZ43OokTCffCzf2Z52f7nx2NHIOoV3O3+80g6jw/Lrfe8WsZZZyXgjqm
=AViA
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*key|.*crt)$
version: 3.10.2
@@ -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.16" version: "0.9.17"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: cert-manager
resources:
- repository.yaml
- release.yaml
secretGenerator:
- name: cert-manager-webhook-porkbun-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
@@ -0,0 +1,11 @@
nameReference:
- kind: HelmRepository
version: v1
fieldSpecs:
- path: spec/chart/spec/sourceRef/name
kind: HelmRelease
- kind: Secret
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
@@ -0,0 +1,19 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: cert-manager-webhook-porkbun
namespace: cert-manager
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: cert-manager-webhook-porkbun
namespace: cert-manager
chart: cert-manager-webhook-porkbun
version: "2.0.7"
interval: 1m
valuesFrom:
- kind: Secret
name: cert-manager-webhook-porkbun-values
@@ -0,0 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: cert-manager-webhook-porkbun
namespace: cert-manager
spec:
interval: 1m
url: https://porkbun.octabits.io
@@ -0,0 +1,49 @@
# cert-manager-webhook-porkbun Values
# groupName must match the ClusterIssuer webhook stanza
groupName: acme.saggar.dev
# cert-manager deployment configuration for RBAC
# The chart creates RoleBindings so cert-manager's service account can reach
# the webhook and read the Porkbun credential Secret
certManager:
namespace: cert-manager
serviceAccountName: cert-manager
# Restrict the webhook's Secret read access to the Porkbun credentials only
rbac:
secretAccess:
secretNames:
- ENC[AES256_GCM,data:WXGjM38wR7oKcvetV91WocOt48njb5Y=,iv:7UEsgh62qq/0fGfmjG96Kko/r2h9IOD7IqRnu7poGFo=,tag:qdb4+n9ZnQidlz5fnHq94g==,type:str]
# Pod configuration
replicaCount: 1
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
memory: 128Mi
sops:
lastmodified: "2026-09-27T22:55:14Z"
mac: ENC[AES256_GCM,data:rSc+2n8PYZLdBJRWB3lgiH40+24/5v0vLRAkHV3vM3IyxZgBrjJxmWjAu5PJWHDobQiw7G7x7ZMotJx6TbJztbnBpB5GmdoFC0kVkxxdE8txCWlmcwed6oktCJQ0nR09DaqTk3OvRZgFsWwkVMhZwCjLS+gZBzTTcw84MKqQcGg=,iv:tJd2rGP0EzrjVSp5ESHf5BnFU7fFjMUgfZTgZeM2yRk=,tag:hxVTpxEjz1naTbrDTQUSYA==,type:str]
pgp:
- created_at: "2026-09-27T22:55:14Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/5AVsqIJQvmzAAexGSmYjPrdmX7W7JaVHYpUCFbiU9RP32
S1ffbzV+YjmYkrLhnwhosNeheEVbEiWeyrea+B9wlTgUp1R9+oy8ooc30uDr/vhY
9K56DoEcUhi95mQD1U7e7LK6qUkMowS0HWXEEOb/r/bvL3lQNmc4rNJ8Dz+MDFh3
A59ZkrvspjccrLd9wJUb1QbwLKRw/QpE/bT17nj8bOwcAipdz2Q/GoX0LGp88fgS
Yy6G/zwVpY/mDylHZbunDVBEqAziR3TAbQsRQZou2oB69Q0jwVs8//vVhWSpniUr
an/XdNaEDR5LFJESJK9Kf3H2Qe/Cq8ynC3NFAwk+tHVLOW8MxQrDUvq3fTQq/Zl+
CEzMD7+5bQDLQX82QMZ0TdjcLCIEouqCHo9dnGQGUX7NQd1ePV3xda6750zr1maX
PVTmx12nS+fCwo1DVLSTVa907TLg3h/DoADzpzcmhTfE7xO2mNcfN+P1dnHT2+U4
FhUXqYgZSkgjlkkpVr8XmZg4Cb98lgpS6hDqXylrXhdsCvGgW9YKg0wdQqb6H4Sr
ycBsXmj4/j1EMB9yqfSpO/6NNDjTMms0nWsrGXI7NHpROj+AV7fWXC1yxhw6uTus
SYhve/6VvbCb3hw9gHb9lzQ9VvTq/0jOqIMBoLoD1Wd45tHczPx1xbVf3KyB1HTS
XgFYYLiLku1Jj87DtdbsAbN0tNQNets9TBVffkawgFNsei/H5ZazKFPOC5NrwnJ1
FWLWI1fwFZG18c29b8mrEUKqX8GD+YO0BKwmtL7n9out6YAA+hK780RytQDdD00=
=yh2A
-----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
@@ -14,7 +14,7 @@ spec:
name: stalwart-helm name: stalwart-helm
namespace: stalwart namespace: stalwart
chart: stalwart chart: stalwart
version: "0.7.18" 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.22 tag: v0.16.24
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
# Single-node RocksDB deployment. # Single-node RocksDB deployment.
replicaCount: 1 replicaCount: 1
@@ -9,6 +9,11 @@ ports:
trustedIPs: trustedIPs:
- 127.0.0.1/32 - 127.0.0.1/32
- 10.0.0.0/8 - 10.0.0.0/8
transport:
respondingTimeouts:
# v3 default is 60s, counted over the whole request body:
# large HTTP git pushes die with a 504 past one minute.
readTimeout: 5m
# Tolerate failover node # Tolerate failover node
tolerations: tolerations:
- key: ENC[AES256_GCM,data:r4uAu1ni9/Z8,iv:aKgn6DgT9XnjzmotnaEIL+WzUiQ34CazfervJwrYsdM=,tag:EeOY1YZwNCOPgHwXpas3ew==,type:str] - key: ENC[AES256_GCM,data:r4uAu1ni9/Z8,iv:aKgn6DgT9XnjzmotnaEIL+WzUiQ34CazfervJwrYsdM=,tag:EeOY1YZwNCOPgHwXpas3ew==,type:str]
+2
View File
@@ -46,6 +46,8 @@ resources:
- utilities/open-webui - utilities/open-webui
# Production (public-facing websites/apps) # Production (public-facing websites/apps)
- production/buildpath - production/buildpath
- production/saggar
- production/get-saggar
- production/semery-fr - production/semery-fr
- production/umami - production/umami
- production/vhaudiquet-fr - production/vhaudiquet-fr
@@ -12,7 +12,7 @@ spec:
name: notesnook name: notesnook
namespace: notesnook namespace: notesnook
chart: notesnook chart: notesnook
version: '1.0.32' version: '1.0.38'
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -12,7 +12,7 @@ spec:
name: cloudpirates name: cloudpirates
namespace: paperless namespace: paperless
chart: postgres chart: postgres
version: "0.20.5" version: "0.20.6"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -12,7 +12,7 @@ spec:
name: cloudpirates name: cloudpirates
namespace: paperless namespace: paperless
chart: redis chart: redis
version: "0.35.1" version: "0.35.4"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
+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.2"
interval: 1m interval: 1m
valuesFrom: valuesFrom:
- kind: Secret - kind: Secret
@@ -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,40 @@
# Gitea OIDC client credentials for the saggar login provider — the
# OAuth2 application registered on git.vhaudiquet.fr (Profile →
# Applications → OAuth2), with redirect URI
# https://saggar.dev/auth/callback/gitea
#
apiVersion: v1
kind: Secret
metadata:
name: saggar-gitea-oidc
namespace: saggar
type: Opaque
stringData:
client-id: ENC[AES256_GCM,data:8NHXVbeLNBbFfxtVDk8AtbBWnjpwMWlihjqoEFSJmCDH3Cjz,iv:3PqTABU6ZxNEm0jshvDEkKbSHpdqf2/7DzVVjx/cXVA=,tag:YYuNIQU4nsNxVWZA2WVVbw==,type:str]
client-secret: ENC[AES256_GCM,data:WiqVhGyNHyeVQY9bX2qkvcaiasejyUUyNXBN4kTKl+TfP8vsedex0U8Va5Ns+9KW/Uget3+kH/o=,iv:K1zLz8am7Vox5IZc5zSDSEeDu9t6R5swEeeqTRrnZdo=,tag:OEbZAqNBkgpX/RdvH5Tb8g==,type:str]
sops:
lastmodified: "2026-09-30T20:30:47Z"
mac: ENC[AES256_GCM,data:MKm2CMBDtNL2GzO2pvmX7WLcTYNap9Xh/loBjZESkHbS65V2QpNU4+yTXcDewyDld9q2zKock1kPRQbhSyptlpxRQN6WZ+LhenS3f6p7rjPq+6gquNJ9j6ccgMFKvBKXoitYsbvfdpp6F6FN8vj24aH6OmTO2gUuvsdj7LIF1bI=,iv:20tkg9yg1kPeo2tbNbXNKNWXAbUqL352NV3+HOCqnqQ=,tag:35vyPxiRTUPuQkxy1/zD0Q==,type:str]
pgp:
- created_at: "2026-09-30T20:30:47Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+INz4B5GdyNfaR4b6DXha7chZN3Qh+nh8oRduzFGKak76
C3fANw2+HJ4/eV/j1ImNMbON0v7fbPpEe417nkRPESxnkEONi2Rrt0qoCVtnI64u
isewcMXEJCvTqAa460lE5AIC3tMjfYZd7h3tUe9N7HL3ufOB7hDVflGq954Zo+qu
rwGH5RZ5s4B5xnW6upVia+TRpu907ibpCKSfzm2uH6CRSIuuvIZrhu/qMnEUaa9F
9SEEr87orU7YhYltPmK6k3oFaZLbXNsIYCLl7AIeMA3ZlvKKwk4HkTxYU5BUsAK9
Zhv7yWIFyhTLVOv2k1dbOym3aRGe2KA/+LGHn0bi9ps2A5Vf6rSIQ1v2ya+OVCmw
Ibofs6/pfI1sZ56pOo1BGv0e6hBTe+jzimtBrTSAuCytDcTDmWusnH3HU8EefanN
96Dw1NMCVqYn+yl8CL9UPMOL4UT+CDJEbWVBjfVvsoeaER+ipPbspo9eRZypq7D7
aOWrP9Uiig/PeLt4ZMpsTWM27/tsVy2CPEFQ+XlgandVLQ6qTUQK42oAtepDSWuP
z8b12dkZ+xraI/wPqlrf6fXU+oKU2KteZxiMn89KqEgTbMp+BGycDHsKLA7VE+uz
Ni97MN8fbkT85VgwGE95xvUDGMMGyQuJrKbwc6gXzHQoCzZ/RfPBSUeXM4iyAa3S
XgGXEdIV02aQjl+kOqXu1VZLDVnb46fXTA5GDU51HKHeyT6YoE3rNljdFp2/hub/
rYX5lJ4j8XXo6s9xUQ3BEw3JMbrc0++SrIXGk3Hqid3Ez+cBm3Q/wqF3YpF5tIs=
=GpPh
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*key|.*crt)$
version: 3.10.2
@@ -0,0 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: saggar
resources:
- namespace.yaml
- packages-auth-secret.yaml
- gitea-oidc-secret.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: 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: saggar
@@ -0,0 +1,38 @@
# Basic auth for the private Gitea Helm repository (org `saggar`) —
# the same access token also goes into values.yaml's imageCredentials
# for the container pulls (the chart renders the imagePullSecret).
apiVersion: v1
kind: Secret
metadata:
name: saggar-packages-auth
namespace: saggar
type: Opaque
stringData:
username: ENC[AES256_GCM,data:gQXori8DR18jnw==,iv:X1rqJ3gTlIdY6qDYYDLjW+r+/PZVvVvZJaHuRflA50k=,tag:QOLVAuGO/deRAxwelHq3jA==,type:str]
password: ENC[AES256_GCM,data:aGrzZOtE7PeFXB8ybbAGgVdstb6De7ha/GARPyXP8nxP/tv542d3YQ==,iv:ngBYMmLVtG/5Au5txvzM25LOT2FswrAHP7LMRth2yek=,tag:+uKN2Zjl/ueYIHrXvWBTaA==,type:str]
sops:
lastmodified: "2026-09-30T20:30:48Z"
mac: ENC[AES256_GCM,data:G5Z0s30VsnEsvCVQin/fNg8n2UamvhDv4TMOzvBWXXjW5b43aXdzbQ++x3AetBCgocuTkAXqoPmpYG5f0DVH3n+55lqeE3ChtUlkb0S3zJPZ1jna5rNqKHMFuI8nItyxowAVVKJ06tscRCPlvwRcYWuTGEep0Lq7fSgt6BR/7TQ=,iv:x0uJXcRo8CDjzd4msHMBwloATMryQxmo3eGpzBhzn80=,tag:AwI4lslApzy0wyJgRcYdLg==,type:str]
pgp:
- created_at: "2026-09-30T20:30:47Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiARAAsQDZ1Uan1oGs6/mBJ9RvdMWH7fhCJfIWXv9Ldljn9lFv
Cp7ygWA9xgmUW2emtybn28s6uNr4kEH5/x5+0BIIVAmb/LKWi40bQKhSuaWKEgZf
OmZMNRilgwKFODbfif7UzsjKmogJ5DBFZqiJXP9uFSbF8klH4HSbJcKHR9jCjiM8
cnWcpZ4xPaPxV7ARC8vKh3jvC7Eh6ivjEhJJSUQTt7w4ucs2e07n2WrCLAQDtu4m
xzVMDV6y2Far3Rv3Lk5O+FRprmpIKhGwU5nfEFighj7K8/ynZDUEsE5EUtuxDw1p
BBFFAsuNf4J+qVctfCFwEr2PTsT1VU0jKcB6t9lJZE3aT2xu9mu1Ezn9m/YGWzp2
airb4UVACWLXj9sqcv7YIG8aUHpm7qVm8AE5UF1OhNJbDCQbpUEklGNRV3N0R4nr
ehatG1fCLUmXj7CUHdLmfGkhahfUIl2SJAp42h9VdQN8NB8Plj4j+hzluZSqU8XS
KP7kdIbDheeqZvSxA4KAeXrvvUzOWp4VK6ClL9pVjEh5HTu38atFGQ99daILy95L
f2z4l1Gc73+zRCHWPKtz5SiPT/G4RlxL2lrgKnykfpOCbJ7wV+XC5kAi+Lj8BM7s
EB2bqYewal8k2+VVFGD8vzyB/0mV2i37AJFJ8uJTU09D0CKGpDlgrFw1D3YkwA/S
XgGxHYtmARZxCBEbCeizPE4nk+UZtvVtngPUKABPe5euwX40kOwy81dadjoIZsks
Vev3d9txiEO6QKcx5rTEp7uju9QO8meqWIM97f0dB1hj1l+tRwmo91XJVKBRgFQ=
=ZysC
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*key|.*crt)$
version: 3.10.2
+19
View File
@@ -0,0 +1,19 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: saggar
namespace: saggar
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: saggar
namespace: saggar
chart: saggar-hub
version: '>=0.2.0-0'
interval: 1m
valuesFrom:
- kind: Secret
name: saggar-values
@@ -0,0 +1,10 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: saggar
namespace: saggar
spec:
interval: 1m
url: https://git.vhaudiquet.fr/api/packages/saggar/helm
secretRef:
name: saggar-packages-auth
+105
View File
@@ -0,0 +1,105 @@
# Hub mode (the chart default): intake + registries + web UI, with
# artifacts in the release's embedded Garage store (chart default in
# hub mode, longhorn-backed). Builds happen on runners from the
# saggar-worker chart, to be paired against this hub once it is up.
image:
repository: git.vhaudiquet.fr/saggar/saggar
# Empty: follows the chart's appVersion — the commit SHA CI stamped
# on the pushed images.
tag: ""
# Private Gitea registry: the chart renders an imagePullSecret from
# these. Same access token as packages-auth-secret.yaml (the
# pre-commit sops hook encrypts this file).
imageCredentials:
create: true
registry: git.vhaudiquet.fr
username: ENC[AES256_GCM,data:Kb01bICyN/BvDQ==,iv:o19woAl9Hqlouo3fgmj6fesiix1bo6fPRcZdE3W55bk=,tag:LzBjc/dOaFv1yUblzAmFBQ==,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
# the provider and runs every code exchange, so its discovery drives
# the endpoints (issuer verified live). Credentials live in
# gitea-oidc-secret.yaml — both ride the Secret (clientIdKey opts the
# id in too), so nothing sensitive renders into the ConfigMap. The UI
# needs nothing: it discovers the provider from the engine's open
# /auth/methods.
auth:
# The web origin the device login names: `saggar login` prints the
# confirmation page under it (saggar.dev/device).
uiUrl: https://saggar.dev
providers:
- name: gitea
issuer: https://git.vhaudiquet.fr
existingSecret: ENC[AES256_GCM,data:hqjfc89icY+3fOSMzh0xJ0Q=,iv:K+g5gpi8vcBpw6buktSZlePj9p4TGRV6bxuvSrFx2i0=,tag:FljiBjxAFrQON4J4iqk50w==,type:str]
clientIdKey: client-id
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:
enabled: true
className: traefik
# The engine host: CLI intake + the docker/apt registry front-ends.
host: api.saggar.dev
# The chart's default annotations are nginx-specific (SSE
# buffering); traefik streams unbuffered by default, so clear them.
annotations: {}
# TLS terminates at Caddy with the cert-manager saggar.dev certs;
# Caddy proxies to Traefik by host, so no tls block here (same as
# pkgatlas's ingress).
tls:
enabled: false
ui:
# Sign-in redirect base — the UI's own public origin.
publicBaseUrl: https://saggar.dev
# The engine's public origin for the docker pull / apt usage lines.
# Set explicitly: the chart derives it from the hub ingress, whose
# tls is off here (Caddy terminates) — that would render http://.
apiPublicOrigin: https://api.saggar.dev
ingress:
enabled: true
className: traefik
# The UI lives on its own host: the engine mounts its API and
# registry surfaces at root (/v2, /apt, /nodes), paths the UI
# pages also use.
host: saggar.dev
annotations: {}
tls:
enabled: false
docs:
# The chart deploys the book by default; the ingress renders as
# soon as a host is set (no enabled knob).
ingress:
className: traefik
host: docs.saggar.dev
tls:
enabled: false
sops:
lastmodified: "2026-10-06T04:20:10Z"
mac: ENC[AES256_GCM,data:ztx2M4srmnZs9S86xWOYSkePbi9Gm1n0FIB9oBmiaEn5fzSmPLbbn8IPcRsU+zOjkg5DRZ4LbuNdtmxynTC20yCHpb2vZbIUFiQarxPizI9lcKZyyOXFjoECXYZ5oDEOkAPrvYWTduqvK5o9dsUmebtKCSh9EMVMD47nF76yr68=,iv:Y2DjchwTfIjWMDGfQNwXCxM7MG6iNwU6LHf276osNjM=,tag:oviToaqWMdl1/cDgYX9M7g==,type:str]
pgp:
- created_at: "2026-10-06T04:20:10Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//Sgir+7MRZYnuxGArDmyeP57A3xL6F77pLZbNIOjQ6KcK
3Giga+m3n2BodCDVzL6bUOtUbtgBVyqD7SSBY4qQ2a9c/H4xBAO0HciDth4O1Wer
z8fKSphk7tt1yBtzuB1tm0F9Ye53tLaetACXRGGo83jCGse8J0d4+vimra45fjyn
9JEnCl0+A2AMMl9/hcfCj8iSj+VeiCJz35Zmo+BWl0KrY0DHAeEyBEtI7O+z8bFF
9oGZY/xhTVD4IkbOqXs1fatTmybyzxrTBz/I7d9QOnPx7N08rb/g3KspkCPDSptH
h/AnDGg0PDVs7WK0eMwFMsZ8gvEYI76ecf6mAO5x6TbpxVHCPXpbbBTC7ro7usB0
4jVLrALMtsMn8k45JWFGR3OsujPr1D+yGmsJ2Mqde4AtjE6zTs8TurwuDEY0ivYg
HvAKk6C+ZOmdQEMep2kznSovMx0m6FP8Muv0ORX+pMNOIRhUFbEAXT+s7J7YoLlf
Rza/lf4VgsWtTUyUZRTH3G2NTwEgBo4GsV6bM07OhN0GEgMH1hOuGo61C+e2d6PR
NqeRgvlzfmeoTUBwgNv023739hyB2xDVesr5jo/yomikxFiz0wGUBQ4eRZmRZSjD
ZCLoiv+2ymROgWzGqgutRiRD150P45biMs3zW/x3qGP/SiTj35OYyCzMjQb/ZRjS
XgGHEtiiRWv954k5eXRF3DOHxrZ/oxtjyc4+EjlS3VsgtOCjePSzKg/WQa8Zx3ns
MT2BKgtlFwM2eG5V7jHfHOmAuVIuH249iyER5AJDzot/0kAO7ekH/y72kfloDKk=
=3vCq
-----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
@@ -15,6 +15,7 @@ spec:
dependsOn: dependsOn:
- name: cert-manager - name: cert-manager
- name: cert-manager-webhook-ovh - name: cert-manager-webhook-ovh
- name: cert-manager-webhook-porkbun
decryption: decryption:
provider: sops provider: sops
secretRef: secretRef:
@@ -0,0 +1,20 @@
# Flux Kustomization for cert-manager-webhook-porkbun
# Depends on cert-manager being fully operational (CRDs installed)
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: cert-manager-webhook-porkbun
namespace: flux-system
spec:
interval: 10m
prune: true
sourceRef:
kind: GitRepository
name: homeprod
path: ./kubernetes/infrastructure/cert-manager-webhook-porkbun
dependsOn:
- name: cert-manager
decryption:
provider: sops
secretRef:
name: flux-sops
@@ -6,6 +6,7 @@ resources:
- webhook.yaml - webhook.yaml
- cert-manager.yaml - cert-manager.yaml
- cert-manager-webhook-ovh.yaml - cert-manager-webhook-ovh.yaml
- cert-manager-webhook-porkbun.yaml
- cert-manager-issuer.yaml - cert-manager-issuer.yaml
- caddy-certificates.yaml - caddy-certificates.yaml
- stalwart-certificates.yaml - stalwart-certificates.yaml