Compare commits

...

18 Commits

Author SHA1 Message Date
dependabot[bot] ea95d1fe6e build(deps): bump gramps-project/grampsweb in /docker/personal/gramps
Bumps [gramps-project/grampsweb](https://github.com/gramps-project/gramps-web) from 26.6.2 to 26.7.0.
- [Release notes](https://github.com/gramps-project/gramps-web/releases)
- [Commits](https://github.com/gramps-project/gramps-web/compare/v26.6.2...v26.7.0)

---
updated-dependencies:
- dependency-name: gramps-project/grampsweb
  dependency-version: 26.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-22 00:43:40 +00:00
vhaudiquet 204b675f50 longhorn: tolerate failover node 2026-07-21 22:19:40 +02:00
vhaudiquet ebbea69288 infra/p330: add p330 talos node 2026-07-21 17:56:06 +02:00
vhaudiquet 71ddb95d2f kube: migrate to longhorn by default 2026-07-18 16:22:16 +02:00
vhaudiquet b10ca16816 coredns: move etcd pvc from nfs-csi to longhorn 2026-07-17 11:07:04 +02:00
vhaudiquet ae42ca3a1f longhorn: deploy longhorn to kube 2026-07-11 00:54:08 +02:00
vhaudiquet a513f0dc2e refactor: remove old certificate secret file 2026-07-10 07:13:33 +02:00
vhaudiquet b225fd1057 fix: tryfix secret read permissions 2026-07-10 07:06:52 +02:00
vhaudiquet 97fc11e001 fix: fix ovh webhook solver credentials (clusterissuer) 2026-07-10 06:51:14 +02:00
vhaudiquet abd186b1a1 fix: fix ovh webgook solver values.yaml 2026-07-10 00:31:08 +02:00
vhaudiquet 81d4e5c310 fix: update missing issuer 2026-07-10 00:26:17 +02:00
vhaudiquet 2c43aacf91 fix: update missing kustomization 2026-07-10 00:25:15 +02:00
vhaudiquet c6b706a136 fix: fix semery.fr ovh webhook provider 2026-07-10 00:21:08 +02:00
vhaudiquet ba0df1c484 semery.fr: add OVH-specific webhook solver 2026-07-10 00:12:21 +02:00
vhaudiquet 001d4adbed semery.fr: automatic certificate renewal 2026-07-09 23:17:09 +02:00
vhaudiquet b424f2972f vhaudiquet.fr: update namespace to allow privileged container 2026-07-09 19:54:13 +02:00
vhaudiquet b6541a018f vhaudiquet.fr: update to allow deploying without NFS 2026-07-09 16:43:04 +02:00
vhaudiquet a9178f6209 infra/r740/proxmox: bump kube vm base image 2026-07-09 16:42:52 +02:00
39 changed files with 924 additions and 172 deletions
+2
View File
@@ -55,9 +55,11 @@ updates:
- "/kubernetes/system/blocky"
- "/kubernetes/system/caddy"
- "/kubernetes/system/cert-manager"
- "/kubernetes/system/cert-manager-webhook-ovh"
- "/kubernetes/system/coredns"
- "/kubernetes/system/csi-driver-nfs"
- "/kubernetes/system/external-dns"
- "/kubernetes/system/longhorn"
- "/kubernetes/system/traefik"
- "/kubernetes/tools/dashy"
- "/kubernetes/tools/glance"
+3
View File
@@ -9,3 +9,6 @@ terraform.tfstate.backup
kubeconfig
talosconfig
# Ignore rendered Talos machine configs (may contain cluster secrets)
p330.yaml
+2 -2
View File
@@ -1,7 +1,7 @@
services:
grampsweb:
container_name: grampsweb
image: ghcr.io/gramps-project/grampsweb:26.6.2
image: ghcr.io/gramps-project/grampsweb:26.7.0
restart: always
networks:
- default
@@ -31,7 +31,7 @@ services:
grampsweb_celery:
container_name: grampsweb_celery
image: ghcr.io/gramps-project/grampsweb:26.6.2
image: ghcr.io/gramps-project/grampsweb:26.7.0
restart: always
environment:
- GRAMPSWEB_TREE="Gramps Web" # will create a new tree if not exists
+195
View File
@@ -0,0 +1,195 @@
# Talos node for the P330 — joins the r740 "kube" cluster.
terraform {
required_providers {
talos = {
source = "siderolabs/talos"
version = "0.9.0"
}
null = {
source = "hashicorp/null"
version = "3.2.3"
}
}
}
# Read the r740 kube module state to reuse the cluster secrets & endpoint.
# The r740 module exposes: client_configuration, machine_secrets, cluster_name,
# cluster_endpoint, kube_host.
data "terraform_remote_state" "r740_kube" {
backend = var.r740_backend
config = var.r740_backend == "local" ? {
path = "${var.r740_state_path}/terraform.tfstate"
} : var.r740_backend_config
}
locals {
cluster_name = data.terraform_remote_state.r740_kube.outputs.cluster_name
cluster_endpoint = data.terraform_remote_state.r740_kube.outputs.cluster_endpoint
machine_secrets = data.terraform_remote_state.r740_kube.outputs.machine_secrets
client_config = data.terraform_remote_state.r740_kube.outputs.client_configuration
# kubeconfig produced by the r740 kube module — used to wait for the node and
# apply labels/taints. There is no in-tree kubernetes provider here on
# purpose: managing a `kubernetes_node` resource conflicts with the node
# object that kubelet itself creates, so we use a null_resource with kubectl
# to wait + label + taint idempotently.
kubeconfig_path = "${var.r740_state_path}/kubeconfig"
# Network config: static if node_subnet is provided, otherwise Talos DHCPs.
static_network = var.node_subnet == null ? {} : {
interfaces = [{
interface = var.network_interface
addresses = [var.node_subnet]
routes = var.node_gateway == null ? [] : [{ gateway = var.node_gateway }]
}]
}
network_patch = {
nameservers = var.nameservers
}
network_patch_merged = merge(local.network_patch, local.static_network)
machine_patch = {
install = {
image = var.installer_image
disk = var.install_disk
}
network = merge(local.network_patch_merged, {
# Pin the Kubernetes node name. Talos otherwise auto-generates a hostname
# (e.g. "talos-8ec-vd1"), so the node registers with that random name
# instead of var.p330_node_name — and our label/taint null_resource waits
# for the wrong node. Setting machine.network.hostname fixes the node name.
hostname = var.p330_node_name
})
# Kernel modules required by Longhorn (iSCSI + ext4) — must match the
# control-plane nodes so Longhorn can schedule replicas on the failover node.
kernel = {
modules = [
{ name = "iscsi_tcp" },
{ name = "libiscsi" },
{ name = "scsi_transport_iscsi" },
{ name = "ext4" },
]
}
sysctls = {
"fs.inotify.max_user_instances" = "1024"
"fs.inotify.max_user_watches" = "1048576"
}
kubelet = {
# Keep the failover node from accumulating non-essential DaemonSet pods
# via the regular scheduler; the taint does the heavy lifting, this is
# belt-and-braces.
extraArgs = {
"register-with-taints" = "${var.failover_taint_key}=${var.failover_taint_value}:${var.failover_taint_effect}"
}
}
}
}
# Control-plane machine configuration. machine_type = "controlplane" makes
# Talos generate a join config that runs the apiserver/controller-manager/
# scheduler AND joins the existing etcd cluster as a new member (the cluster
# was already bootstrapped by the r740 module's talos_machine_bootstrap).
data "talos_machine_configuration" "p330" {
cluster_name = local.cluster_name
machine_type = "controlplane"
cluster_endpoint = local.cluster_endpoint
machine_secrets = local.machine_secrets
config_patches = [
yamlencode({
machine = local.machine_patch
})
]
}
# Rendered config is written to disk so it can also be applied manually with
# `talosctl apply-config --nodes <p330_host> --file p330.yaml` if needed.
resource "local_file" "p330_machine_config" {
filename = "${path.module}/p330.yaml"
content = data.talos_machine_configuration.p330.machine_configuration
}
# Apply the machine config to the running (maintenance-mode) node over the
# Talos API. Because the config patch contains a `machine.install` block, when
# Talos receives this config on a node booted from the USB (maintenance) image
# it installs itself to install.disk and reboots into the installed system.
# For a controlplane node it then joins the existing etcd cluster as a new
# member and runs the control-plane components; for a worker it just registers
# via kubelet.
resource "talos_machine_configuration_apply" "p330" {
client_configuration = local.client_config
machine_configuration_input = data.talos_machine_configuration.p330.machine_configuration
node = var.p330_host
depends_on = [local_file.p330_machine_config]
}
# Emit a talosconfig scoped to this node for ad-hoc `talosctl` use.
data "talos_client_configuration" "p330" {
cluster_name = local.cluster_name
client_configuration = local.client_config
nodes = [var.p330_host]
}
resource "local_file" "talosconfig" {
content = data.talos_client_configuration.p330.talos_config
filename = "${path.module}/talosconfig"
depends_on = [data.talos_client_configuration.p330]
}
# Wait for the node to register with Kubernetes (kubelet creates the Node
# object after Talos installs and reboots), then label it and (re)apply the
# failover taint. This is idempotent: kubectl exits 0 if the label/taint already
# exists. The taint is also set via kubelet `register-with-taints`, so this
# null_resource is a safety net for manual edits / drift.
resource "null_resource" "p330_node_label_and_taint" {
triggers = {
node = var.p330_node_name
key = var.failover_taint_key
value = var.failover_taint_value
effect = var.failover_taint_effect
kubeconfig = local.kubeconfig_path
}
provisioner "local-exec" {
# Wait for the node to show up, then label + taint. The wait loop is bounded
# by kubectl --timeout; tune it via TF_LOG / re-run if the node is slow to
# join (a controlplane node must first complete the etcd join handshake).
command = <<-EOT
set -euo pipefail
KUBECONFIG="${local.kubeconfig_path}"
export KUBECONFIG
NODE="${var.p330_node_name}"
echo "Waiting for node $NODE to be registered (kubelet creates the Node object once Talos has installed, rebooted and joined etcd)..."
# kubectl wait --for=condition=Ready fails instantly with NotFound if the
# node object doesn't exist yet, so poll for existence first.
# /bin/sh (dash) has no $SECONDS, so count iterations with a bounded loop.
tries=240 # 240 * 5s = 20 minutes max
until kubectl get node "$NODE" >/dev/null 2>&1; do
tries=$((tries - 1))
if [ "$tries" -le 0 ]; then
echo "Timed out waiting for node $NODE to register." >&2
exit 1
fi
sleep 5
done
echo "Node $NODE registered. Waiting for it to become Ready..."
# Now wait for Ready (a controlplane node needs etcd joined + apiserver up).
kubectl wait --for=condition=Ready "node/$NODE" --timeout=20m || \
kubectl wait --for=jsonpath='{.status.conditions[?(@.reason=="KubeletReady")].status}'=True "node/$NODE" --timeout=20m
# Failover marker + taint (applied to both controlplane and worker nodes).
kubectl label --overwrite node "$NODE" homeprod.io/failover=true
# Apply the taint idempotently (kubectl taint --overwrite is a no-op if it exists).
kubectl taint --overwrite node "$NODE" \
"${var.failover_taint_key}=${var.failover_taint_value}:${var.failover_taint_effect}"
echo "Node $NODE ready, labeled and tainted for failover-only scheduling."
EOT
}
depends_on = [talos_machine_configuration_apply.p330]
}
+118
View File
@@ -0,0 +1,118 @@
# Variables for the P330 Talos worker node that joins the r740 cluster.
variable "p330_host" {
description = "Reachable IP/hostname of the P330 Talos node (for Talos API access)."
type = string
}
variable "p330_node_name" {
description = "Kubernetes/Talos node name for the P330 (e.g. p330)."
type = string
default = "p330"
}
variable "r740_state_path" {
description = <<EOT
Path to the Terraform state of the r740 kube module, used by terraform_remote_state
to read the cluster secrets and endpoint so this node can join the existing cluster.
Path is resolved by terraform_remote_state relative to the working directory where
terraform runs (this module dir). The default points two levels up to the repo
root and back down to the r740 kube module.
EOT
type = string
default = "../../r740/kube"
}
variable "r740_backend" {
description = <<EOT
Terraform backend type used by the r740 kube module.
Set to "local" (default) when r740 uses a local tfstate file in its own directory,
or the matching remote backend name ("s3", "remote", ...) if the r740 module uses
a configured backend.
EOT
type = string
default = "local"
}
variable "r740_backend_config" {
description = <<EOT
Backend configuration map passed to terraform_remote_state when r740_backend is
not "local". For a local backend this is ignored.
EOT
type = map(string)
default = {}
}
variable "installer_image" {
description = <<EOT
Talos installer image to use on the P330 (bare metal).
Must be a **metal** Image Factory build that includes ixgbe.allow_unsupported_sfp=1
in the kernel command line (sd-boot/UKI ignores machine.install.extraKernelArgs, so
the param must be baked into the image). The default is a custom factory build
(a18165114...).
EOT
type = string
default = "factory.talos.dev/installer/a18165114f80c28601d05bc4ff1f6ea6d6b214882c5b9af7928aaf4d09741beb:v1.13.6"
}
variable "install_disk" {
description = "Block device path to install Talos on (e.g. /dev/sda, /dev/nvme0n1)."
type = string
default = "/dev/nvme0n1"
}
variable "node_subnet" {
description = <<EOT
Static IPv4 address in CIDR notation for the P330 node (e.g. 10.1.2.132/24).
Set to null to use DHCP. A static address is recommended for a failover node so
DNS/affinity rules stay stable.
EOT
type = string
default = "10.1.2.132/24"
}
variable "node_gateway" {
description = "IPv4 gateway for the P330 node. Ignored when node_subnet is null."
type = string
default = "10.1.2.1"
}
variable "network_interface" {
description = <<EOT
Primary network interface name on the P330. Defaults to enp3s0f1 (the 10G Intel
X520 NIC), which must be on the same L2/subnet as the r740 control plane so etcd
peer traffic (TLS-verified against the r740's etcd cert SANs) doesn't cross a
router. eno1 (1G) is left unconfigured.
EOT
type = string
default = "enp3s0f1"
}
variable "nameservers" {
description = "DNS nameservers configured on the node (must work independently of kube)."
type = list(string)
default = ["10.1.2.148", "1.1.1.1"]
}
variable "failover_taint_key" {
description = "Taint key applied to the node to reserve it for failover workloads."
type = string
default = "dedicated"
}
variable "failover_taint_value" {
description = "Taint value applied to the node."
type = string
default = "failover"
}
variable "failover_taint_effect" {
description = "Taint effect applied to the node (NoSchedule / NoExecute)."
type = string
default = "NoSchedule"
validation {
condition = contains(["NoSchedule", "PreferNoSchedule", "NoExecute"], var.failover_taint_effect)
error_message = "failover_taint_effect must be NoSchedule, PreferNoSchedule or NoExecute."
}
}
+52 -1
View File
@@ -40,7 +40,9 @@ data "talos_machine_configuration" "kube" {
yamlencode({
machine = {
install = {
image = "factory.talos.dev/installer/ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515:v1.11.5"
# Image Factory image with iSCSI extension for Longhorn.
# Generated at https://factory.talos.dev — siderolabs/iscsi-tools + qemu-guest-agent
image = "factory.talos.dev/installer/dc7b152cb3ea99b821fcb7340ce7168313ce393d663740b791c36f6e95fc8586:v1.13.6"
}
network = {
nameservers = [
@@ -53,6 +55,28 @@ data "talos_machine_configuration" "kube" {
certSANs = [
"${var.kube_host}", "${var.kube_hostname}"
]
# Kernel modules required by Longhorn (iSCSI + ext4)
kernel = {
modules = [
{
name = "iscsi_tcp"
},
{
name = "libiscsi"
},
{
name = "scsi_transport_iscsi"
},
{
name = "ext4"
},
]
}
# Sysctls for Longhorn
sysctls = {
"fs.inotify.max_user_instances" = "1024"
"fs.inotify.max_user_watches" = "1048576"
}
}
cluster = {
clusterName = "kube-${var.physical_hostname}"
@@ -106,6 +130,33 @@ output "kubeconfig" {
value = talos_cluster_kubeconfig.kube.kubeconfig_raw
}
output "client_configuration" {
description = "Talos client configuration (sensitive) used to manage nodes."
sensitive = true
value = talos_machine_secrets.kube.client_configuration
}
output "machine_secrets" {
description = "Talos machine secrets (sensitive) used to generate node configs."
sensitive = true
value = talos_machine_secrets.kube.machine_secrets
}
output "cluster_name" {
description = "Name of the Talos cluster the worker joins."
value = "kube-${var.physical_hostname}"
}
output "cluster_endpoint" {
description = "Endpoint (host:port) of the Talos/Kubernetes API on the cluster."
value = "https://${var.kube_host}:6443"
}
output "kube_host" {
description = "Reachable IP/hostname of the control-plane node."
value = var.kube_host
}
resource "local_file" "kubeconfig" {
content = "${talos_cluster_kubeconfig.kube.kubeconfig_raw}"
filename = "${path.module}/kubeconfig"
+2 -2
View File
@@ -1,9 +1,9 @@
resource "proxmox_virtual_environment_download_file" "talos-cloudimg" {
content_type = "iso"
datastore_id = "local"
file_name = "talos-v1.11.1-nocloud-amd64.iso"
file_name = "talos-v1.13.6-nocloud-amd64.iso"
node_name = var.proxmox_node_name
url = "https://factory.talos.dev/image/ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515/v1.11.5/nocloud-amd64.iso"
url = "https://factory.talos.dev/image/5a697fd6e91537a2c9c45929d004d82af180bb5d4e989dd8494e25fedca005bd/v1.13.6/nocloud-amd64.iso"
}
resource "proxmox_virtual_environment_vm" "kube" {
@@ -19,9 +19,9 @@ pushShard: ""
# with these credentials on every cert-manager renewal.
recoveryAdmin:
enabled: true
username: ENC[AES256_GCM,data:83oORcE=,iv:X07gQXkAx2wdqEcOPi5mGTVoFkJjDHBKMCYUjpg3qv4=,tag:qvspLaPSsrld4UV/qXb0cw==,type:str]
username: ENC[AES256_GCM,data:kpf88Vc=,iv:k2kGcGlH0jQkLmb35V4+IIrBpDM93PaG6atcO/SLDB4=,tag:qZIR2LZlv1g0XBkEh0y8qA==,type:str]
password: ""
existingSecret: ENC[AES256_GCM,data:KuZYrQk+YQhciNRTHqOlZdqZWJ3o15I=,iv:x/cm4USFZqWE5xuuF7tUPm593NqX1kbmeKv0x2wzk8s=,tag:G9FRYYaJhWovN+LB/gLaoQ==,type:str]
existingSecret: ENC[AES256_GCM,data:DnjFoj8VNeqHmwM/KVebjOOHvYHPgZQ=,iv:JWBs6OeZzsa+8uJt/FjptI6t+tf+CRQDKA7149rBg1o=,tag:M4CXA2k8M65mbSUF0mnGvQ==,type:str]
usernameKey: username
passwordKey: password
# Recovery mode suspends mail services and exposes only the management listener.
@@ -40,7 +40,7 @@ bootstrap:
# certificate.yaml (letsencrypt-production, Cloudflare DNS-01).
mailTls:
enabled: true
existingSecret: ENC[AES256_GCM,data:Y+LfFx7nuCSMGqo2o3QoHG1Br+MYlQ==,iv:dLJDYmK2gEmNq5VnbpEJWFM1xLLT5jXqxB2WQQ4dr3E=,tag:Ya2cTf/ZpJdzFnwH53iZZQ==,type:str]
existingSecret: ENC[AES256_GCM,data:e8rzv2mvlpoZR/vMfd5sgNuYLDvptQ==,iv:qIQfpHxAOameSdDzOHh89n+RIOd9CcJcl0oRumSHAQQ=,tag:xwbQR5Jabvz+lEju5zuW2g==,type:str]
certKey: tls.crt
privateKeyKey: tls.key
mountPath: /etc/stalwart/tls/ingress
@@ -96,7 +96,7 @@ ingress:
persistence:
enabled: true
accessMode: ReadWriteOnce
storageClass: ""
storageClass: longhorn
size: 50Gi
resources:
requests:
@@ -120,27 +120,27 @@ podSecurityContext:
type: RuntimeDefault
containerSecurityContext: {}
sops:
lastmodified: "2026-07-03T13:00:45Z"
mac: ENC[AES256_GCM,data:qoGDDt03xtJbPH+I3edSsFJagZSlCcMk4XoFc/I2QZEm+45DjsCWe9Q7e9zhn5kF3HBNBwNCgEzJmq2Fn/vemMWHwI4+QZW6nkk5cYTb3r8+WysSeUyt2+Y7EjyQGwI6+2LrCBlJIqmKfpPtT7Y8ZbwRBedoVqFtnNVH5441FMY=,iv:fvfnedCEGXyPw4yRLCtKoAnzz8h3jyJOwpqA33NNJOI=,tag:fPd7RJAMMounXVkIoKrptQ==,type:str]
lastmodified: "2026-07-18T14:22:17Z"
mac: ENC[AES256_GCM,data:JjN4ziOnd65U8AzI9ZnMiPUBiYFGqjGjM3HJ7XoSJuJ+fgYjOH+WX/U2IAfSeqEIMkzvP435BxKGoylrwEVM1k5v07slul5zEclPZglphDjiX+md403lVDtYEXdCSo0+3nqv1DFEQDkKItEEEz882sZBbhMotBHhgcd41RSA1aY=,iv:MaSmisJoj3aobpMw1HGgEOktegX2LtOaXLh3601xgvc=,tag:acWtTiu4ub7GDNp8nM/yVA==,type:str]
pgp:
- created_at: "2026-07-03T13:00:45Z"
- created_at: "2026-07-18T14:22:17Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//WA7P2WeKV6QFKotw5UP1MXcdI9THypFFly4sweJ5MC+e
Lzy/zCidGCM3Cu+dJaaPJNKtfPfagQJ9FzHrnvRcHoCbKS7sTAqugdwt4uyplem9
l03kQWZfDj8R8MHQnAKWNmJDiJkjCoqHdR5f2JtS+n7MngI53SecY2fsFOXRbYJI
hfH1BR+agLjIHc+gOF340GJp4UT+Q6BZOKg8K5O4PYk1Xwj3pi6YFuhiedKHSybF
Ij9OWdTqpofeG3fhwd3jHLW+0WYiFNrVlchfClEDWMMc0UfS6Bfo96IL0JIoYlHD
4Zt8EEyjvAJ5478RTKTobMlsSUC5U51Wn6paapZ5zicCHDzdP2yTtwtSKK0Mdp3W
qt/pZoR4EyM+I2XCKp+z7N5FtH8cahtfZiUOBwQ4NK9Fz+2UBxtP2QzGj8YpJmWu
OkbGoSgwn+8bcNnRwnADTzdiTWf/a56WErp1NvuqF8VqdGzsJR9EgyYwENl+m+U8
fbTY58iAJDDpY5ipPL5v+lo0Fw5DrnQ0NPAm1ORi+rMJy0KUjgAzdS6lL5oWGfAC
rzbzThGpRt0E7O296pht8TCBFHqiKbiOdGEBXO3+w9NrvOgULno4+s88vu6KMvFL
s3MHz7oIgfwel7V6bVc/ZQvHYS3YHjG41fwn00cpKI/WRN8z5MnSwwkegD2Wv8fS
XgEqL6kQPgk97779c0jo9CJA8O6QaSvGyd1j680tN1NN9V64rJOaj/818SgwFLrA
XWaqrOnz8FIspqO836t6OaLq5WwzOtOR6zs7cUk6h1RHgwlFQ+0n1o6qYf6Q+CA=
=HnWo
hQIMA7uy4qQr71wiAQ/9G7UtHO7Ux0YNAPlnkVmU5BI+crzwbWPhdaUZFf5dmCkg
r67EAi/DjqFHR9Ew1Dhpn0InTA/Ld+mGZAAbWeP7xhIEQ+AqACmm/Oxgf3IkHKzE
P7dvco6lQO50W/m3fiU0Pv4A7w3Oq+AdFHcPr3UBi8YGYLgkCbzLs2r9JNviCJsl
uuvz438g92aXfa5JcyUjzxtxKFjzHrZ8seDx38X4fveS/mROpRqiw+G8aQ0BlXDM
9wfiQtiM9CcuahPUWopv4RCOjuqrSc14sxv9xRGsYt1YZFxZ/4Q7rqM+HXBsFp4u
8r4MgE+EflrhKp1aWPGnSn2kalDy3o+yFuk7IhWsrSKsNIU4j1J5xCfhliey+kNJ
387cVf7Bjw+iqoy+qiV7Q7XGip6NgF8WwSudZhznv/pS6LL5H5yHaKxjz5rny/TQ
0upK///2YGuiE66sBb8h2sqzIgr6hZecvb2VdY7BQX4FCo2uAmxTEh+h1fHlervc
i/03B9kNSjP5fSufhE9lsLl0oZgaFIKSpkzLlPdy6z0X5vDEXJGSL+qFudo9RKtf
aaEwaQ+I+snmhWyBeeywxpdyRE5g3xhRwuwaxp7zzVt5ykCnyrZIPvzaSxu/QjaF
jCUmvPp0ZLzAB2xY9AMwOHIrym9lPmcBEEqCiHywCauOQzsGJE3vLF8x3/nzZnvS
XgEE9z1NxK8o0ntL+JZO3+GYvm28Hyw0eXgDJbjJ+tlBYeWH8lfBUOsk2V485OJZ
4SDNvxzxpyF/4RJY4P4KR7HgwDC8gOCsDgqcyn1s4KzECXyQlqmrXxOrL8cFRhY=
=aeJw
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
+1
View File
@@ -11,6 +11,7 @@ resources:
- system/caddy
- system/coredns
- system/csi-driver-nfs
- system/longhorn
- system/external-dns
- system/flux
- system/traefik
+23 -23
View File
@@ -18,46 +18,46 @@ configuration:
disableNewSSOUsers: false
PublicCredentialsEnabled: false
authURL: http://linkwarden.lan/api/v1/auth
authSecret: ENC[AES256_GCM,data:UUZagqAY6+9AM4gMv9WFsWFSzjLxAALUz2iGg3dBIrpP+JCdJWVbXIRpZ8bZPJxvwnTcZSPOsLHlqzeqJRHubA==,iv:xgPnCNp2dpy8UG/fjEHPUxdXYXEQzFn3K/EX9lfjpWo=,tag:1uFZDdgGUvMvyKHj93z4yw==,type:str]
authSecret: ENC[AES256_GCM,data:Qaxb9o3xtrDo9rsxHFpm6tkRd7OWPDyjiIyoPvc1SiIQIthOwXyHQ0b7YAW8rGg1vKBg2fDCIUK4Kgoyr26qUw==,iv:KFt4KqTUwB830flAmxfw7tQrLktacTtWmYDjBAiugk4=,tag:IAi0x3AlCdCTXz7MBryg8A==,type:str]
sso:
enabled: true
authentik:
enabled: true
clientId: ENC[AES256_GCM,data:6XqAMjwywGgZK23ywm1GKWpIhIrXNa28Z52+0J1yhocBxLXoJAiocw==,iv:DiIpcD0H6wnIkXCMPmhLEHTzE6qKQrotGZ7q7Lv2iME=,tag:Kx80RoPf7BFMWEO1lZ4wCQ==,type:str]
clientSecret: ENC[AES256_GCM,data:OO8vjjWVxzUNuY/Jhk348RykWnVRQ/xthunOyI4XVzCmT0WXAH/uWSupljfWQW8aj4WzUUHMpJOvFpd3iYTExFn6QqyBisOgVzS9jy4sP4qdhnSpu9jXzEUNmKyjQncl3QTQCcPZMjlGGf0oJzZgHivVWl6rFbnYQOJHDlu3r48=,iv:H2OvOpH2yxUivH8RTvSnM9k86i9jUJKcUmNPpSSos6g=,tag:XXTyOC+Hj7BvgZJ7qxEZyA==,type:str]
clientId: ENC[AES256_GCM,data:1u8Xe9ZMosAJWwPGZCloAFEQE6n0eTtBzaw149zsuL/yrVoiU8s7Pg==,iv:uxfiXfpocKbiFIu0dPq0So6Kdfr3iMFUM4hRJm3eQPQ=,tag:BxgV/Wl2ZE80+08uaDnsDw==,type:str]
clientSecret: ENC[AES256_GCM,data:LBIh0Jc2MtS5pvOhmFbWSrQaOMiM05e2i5aeMbDJJGNArQ7PGK+okbltWnZHonIwGU/sriFm/x4BMz+snrd+NgTUR2aPPXnomK6f9dEmSXNjLxgnVFUmgcT2P7zqlKUBjMT+SKjZLELfYGzysKTRkXHOCrOoGX8ZobEgOXGflpQ=,iv:iADfUCL30NrwPPof7r/ppO3Rt7ap4RoOkKpBuzyoO8A=,tag:lrt50iqFsZcEdBx25BY0PA==,type:str]
customName: Authentik
issuer: https://authentik.vhaudiquet.fr/application/o/linkwarden
persistence:
enabled: true
storageClass: nfs-csi
storageClass: longhorn
postgres:
enabled: true
host: linkwarden-postgresql.linkwarden.svc.kube-talos.lan
username: ENC[AES256_GCM,data:N+ozpU6TgAZSLA==,iv:XJT1fUe2XqSxpuuPfmzbyrJUUInUEhLyNddOX0jogZQ=,tag:z9rCjOKISMT+wpfwUzFd1Q==,type:str]
password: ENC[AES256_GCM,data:G7dF3Oo+1wzL9g==,iv:yAjh22rwaBhKtHgYAmQEjFSMFspOpG2hThwwjAo2KJk=,tag:DdXlyNk+TfR0IuSpQG3+Zg==,type:str]
username: ENC[AES256_GCM,data:eUTE15OnJZ4dBQ==,iv:bN7y9EwD9rzzH3pm6JJvFkSHmdXkCunui2tyerb3z98=,tag:apU0hdiJbp5fgKjesLfdrw==,type:str]
password: ENC[AES256_GCM,data:qA/FQZdMQG3vdQ==,iv:S0fBAfNiNUi1t7coaKFLloaXolv7l//tUVnSui0Tmo0=,tag:SbW/QBMoNqUSENkSCR83AQ==,type:str]
database: linkwarden
sops:
lastmodified: "2025-09-15T21:48:06Z"
mac: ENC[AES256_GCM,data:i9Mg17Z72cBJOSvmOlHkl0x0/FqhpCqS8iTGTYKlXacXi9E0nYYZr/y74qVjhubEaI1y6cRYXgaePI47lkyfvTzB3VGEpEs/y5fiL+PfiuV8Z18J9244+TyoasYR/a2sdRuJcY5jm6PSTKoGiwGnyZEthVwt1T38yr5msW3D79A=,iv:yj7uCySaoZcnO+7XsgB1EMfZOMwHSA0mtJXUq66MUgQ=,tag:YRvUG0/hj8Bjp+pMdJvePQ==,type:str]
lastmodified: "2026-07-18T14:22:17Z"
mac: ENC[AES256_GCM,data:DoHEvtWEetZGb/lCzQalLAMUlAZ7OVG66bDSaGY7s0i8mhDzRxrkvPq7FL07rnDQoLSW+SFSq6h7LB1PV1HodW35b4rmDzpCCHQ/S7Gj8WW/sX0t6dFpF1GlYeseqAMtNMPeMf095Q9LIHmQlILmjPAKbAuOg6shQ9oIesBzSDw=,iv:3D+wZjBHp0gZRDOvmVHaTIyZlC9IzMupvXfbvYYZVm4=,tag:ui9jt5/F/9NJ08P7MD+7AQ==,type:str]
pgp:
- created_at: "2025-09-15T21:48:06Z"
- created_at: "2026-07-18T14:22:16Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//dICUFaREdeVKhKkK7iPji73IRFZEnwoZwEnR0vtCBL3d
HXFfdXUMOVcXOvkkuF9zG52flUZBpVgilQz2W8Y7xI3tU8xX6wxmuz8LjegidCHk
R2xKAJ5iCEWZTIouFwg4fM399Mm9xhiIPuM4+25DAZnSJJAc7fQ2NaNaA8vjbJQ7
YUnqkmE+QPGbyeykudlTFfl/zZzrgKbQqWuUmD/vq1XckUaPxM5cdeFDsg87AZCs
o51lQ39b+CpWmdbDbJDF5nMWUrCzIz9okptoNfHM/5E0Jg53JBsXBvsqwWTOI5vo
djilDfsyu5nQj7UDstaax839T7P5gm5ass2/YtIjgrJUczyRt6vS97zuXLsbEGpH
6hXHan7OormqbmISnFrL68Q4w6JUZev43bdzqtX0EnYHNZVLXH3qAxD5EnuL/i20
oY/oMEteFh86Smw/LXwtWjVfPKYzNQ6GTkTCzM3hVcfMOzdFVPgYDM+5EXF+/oAB
+BGqZvWW4G3G9sbPTRSJ1k+toWuC/erY41r+g3+KHbW73YdqIVwBsTDAFhPPNbe5
hnr1JFLQ75GHdDRnKRl3nZSPc2j9JMUtMhX+rKwLb/0DoVjNz0lFut/Tj+6xiG/1
SqHTpROU1tkip+rP0shzdu218+hjrzj+cDKkawoqmpD9gOm83P7YEqrIwcBj+TPS
XgE3UHtwHdJM38kfPm1fkTuCejlAQ3Hsz6W4PSbXJfY8w1gO241dEzy+b0At9Rv2
6IklhRBAs4ioH/hD653yz0mkCYRpOLYDJU2iMWZdv61YLXb4rsnAwr6xLbDHDXM=
=69Pc
hQIMA7uy4qQr71wiAQ/+LxkvBdTDic8D31VBAtMiKJJ4nHAIpxja6gHsyVCmS+LP
VOqnEvvEBxf3ifXqwlYh/rY7ywjMyuQAW03zIlNq+9Ufv5QV9Py+UTiQV1mfmRoa
73kINswzbUGvH+HXVkcRGjusS/StPMWKC6jwyrov09gtTF1rJUfcfenqy2waHZOk
JhwcxhrPUnHGOsv4f1+91CCjKHux3/FVagpxJcEvxckMJweuZWm59z77dbwF1lQ3
ws4VMLKzt2wiYSULCDr5KM2YlYWkvzheqhwnOVKXk11ewM+6n8RHIvsE03nvkfRf
tJduJYmXnz249SM4hq3GvyMq+j3qShIMvvKRMv6+aYMZ3SFzAIxtV0dA3lCoA9oy
mGWvImrA7JX4GsG44tEzu0ECvoFV8lEb39QKBXBf8fN6UExasF4pSm276ZGG4Eom
IpfpuaB9oYL4TOEH0/56IEc2BRlvAm62ibra5jNCVLnLB0pzE3KdN7ZYMQyXooZi
dOa56z4KidI4N5oDTc63Hkg0tApdV0x+Rtm7qgdhEp/1i4zqciQqb8//yN6CAb7I
DkyPilrvNkZw95iGqpKVLrAp57BaFHLYNr0O7+WS9urCIUQl3Q37Nz2HyNLJt0Ej
i3VgiJUIoy5NcAIBIFvuAJDsXB+FQxzg+7XUZL44xxsSvA248Shz1CYH9CgwbszS
XgHdJTIcrq3ReybtFVDPtqMkLyItA1fbJzpCr4Fwk922hmEpqBeMHx1Upy81MZJj
T+4v8xBo7KR/6sx3U9kO/TjV7AhdTJPRlgG0WfnfLMncCkrvg4cQWxEIkySShFo=
=XPzS
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
@@ -2,3 +2,7 @@ apiVersion: v1
kind: Namespace
metadata:
name: vhaudiquet-fr
labels:
pod-security.kubernetes.io/enforce: privileged
pod-security.kubernetes.io/audit: privileged
pod-security.kubernetes.io/warn: privileged
+19 -17
View File
@@ -39,28 +39,30 @@ nfs:
storageSize: 10Gi
# Storage class name (leave empty for default)
storageClassName: ""
# Allow the pod to start even when NFS is unreachable (uses emptyDir + initContainer)
softFail: true
sops:
lastmodified: "2026-05-14T09:33:46Z"
mac: ENC[AES256_GCM,data:R5ular4bAyV0cFPGUGYg4NWCGI64rWTax6ObBnCadORwSTh5/VQN3bsDDPFC3dep/7nKzY71d2X4qAcVU3RkWa9eMP+e9dhaGV9/8gvY/qDXZiNEuAXsmpaSATgUo6mUwqrwl5tn4ono4ID8gr7FRVpneTbYX/HpiWDbBa9l1Xk=,iv:wQ552gswkX5aOy/Cht1zY56camnb8EhEwy711osyf4c=,tag:t+U/1wRD7/z39KY9zjNcMQ==,type:str]
lastmodified: "2026-07-09T14:38:39Z"
mac: ENC[AES256_GCM,data:CTnqJl6YPYCt3E0A4QAyt5guqgqiNfFk1xJPAvNM1/kv4HbEVeQxG349AaRSc8bQXcMBIVMf022L4+r0DnTEnyy71vMJwWAJTpnEKBQNaDZNCBraGcznSpOP3t7xibjsQ+pqx6d8xXUm9mDfIJU8Nmqvq+iGEUM1PYsKYfDwhQc=,iv:yBZlb8SujF8nv796elcBMQWbyBg+CQ388UzjVqUUyt4=,tag:P9rW9vl5vkuVFv/RM3gGcA==,type:str]
pgp:
- created_at: "2026-05-14T09:33:46Z"
- created_at: "2026-07-09T14:38:39Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/+JAzu9u2Dgn+lA58pIhRbM1064juEOvebtBK0FdJCi7AG
/Up2oooBmLMxybk16q0800kZHgOAcqTWkRcDq3QhC7nK+xcs03plTLLAlqfnh2x0
XyqQVk4du9caRdgvgN96tG+oWUJcuUJ/uFunXAzRvPnNysS5sGXVKJmbVVKfTjqk
UPyA5sBbCIxW10kPZJjprR1HaRl2dkgz7jZI/q2RXhFjCOhthMErBFr4f6xD3LnN
H5XVtixNcVmIinsGUIgvPW+qknjrf17ammgEtOqjtuu4PUevQFt4zkVyjU0Y/ASj
HAyYgSNIAXanb3u9ulL6CCg/CXJSofTrexw5RPM9eTQQ7S1KqHm/Ns6jjl/jXtEW
cIQZ5bQJPTJu7W9gxGpgaLmWwGfoDWvmT2rIFYC9tf+61F4EbRvY6KepKET9NYTJ
EnyDoxRsfVgxwQjyqpIpmNewWpgWwcLbD8INoJUVx/Yr284F9pBCgKqKRmeNH/Sy
kEt3QD1ElohuwTx7XLkYf6LuDFy8kA5wFUPKUgxmoFsGZhMhmi8ysUkUxtYPPMD8
YLVOK8UX3sYUDdY7tQjlgz6nhMqGL7ekqxyA5PSCGlhg5siKIhltz1CzadNOrsqF
jHkiUCrDNu1ToRPllOw4WMwSzII/sf2oP3FJyE+/Rsl49rVjELLfC8eWPhG0yhXS
XgGHbmvrm1QPl70dF+896QE/XtSydiqLUynCeIAvh61//ipS9lSZXpdDKEP5Q7ZD
/lTbPRH7Y7EZUgarjBtc2wYg3iaBkELtS5lnQeJawHQ8/M3TxdWmgEeBim/qr+A=
=K+50
hQIMA7uy4qQr71wiAQ/+PV8hvPHvkmAg1BLaMWbpkMD0Y5/+uQbnnEfIaJdiE4VG
bxtqfBeB/f5kfLDoeVZOCO64tuLtljiZhGjFMA7qESLw0qAvRaDJhXZ9qD1cWSgG
DgVhp/4lb+yo37lLUYaqfeRDD5GTXOpKSZOf5WFPr5tsiL9YcfWVVWaf6uSjUl7I
OZkDwi3sDfypuen12I9BM580QRamQzsp6gCynQdE/4PjzND9vAvhEBtftZPLmd2/
5O4XgjaiJXo2PstAD3VD7c7vGbtEUfvn0vmd79yHz1YBtHRYtDfmnWwHJjeOpxP5
ooFW3uJuwL3N9/IaFTmgGHynjhQAqVdC79PL4XSVkSMoqdW8YDHBgErH9WI4Lsbz
vl2Wp9eIeopiyIzGXHsUvv/nP3ayp9pS16fV9xJGVczSi5c5YqFRYGtX7QIyXtqA
syQlnzoVr4MeT2A2MNdJEWKtfBRQoQR1Qc7ZX/XwfR4b5/58ci9HwBL2eLu0GzRg
e8LDnZsGQCozI7h7x332+Wu/9Mbs0wJ1TslQbXt2vRhbve0IvPjNSi54RKI4r8uV
/iFnRqPp2ow030nvW+LYt5jcqyKK9poC9nVoytUU57Pc3VmyppOJxc8/AfIezo95
LFFWj2CjWr47UspHcqgk84cBP13LmUhK7IeHNBzoWl6LPztuVCczoy7wxn8fGCfS
XgFm8RoiId9S5XLhCZ7qV70HhWOZemd0PksBP054xuWvlDMe/HqxvxUmqDbH/vGv
49o6a/FJyF2ncU01j72KMyn/ZbYevniX+QG+U7vWuhVRH9tRYYQUrgC0QnPqFKc=
=duXn
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
+1 -1
View File
@@ -2,7 +2,7 @@
# This file contains all route definitions, imported by the main Caddyfile.
# Edit this file to add/modify routes.
#
# Certificate files are mounted from the caddy-certificates Secret
# Certificate files are mounted from cert-manager-managed TLS Secrets
# at /etc/caddy/certs/
apiVersion: v1
File diff suppressed because one or more lines are too long
+31 -2
View File
@@ -32,8 +32,37 @@ spec:
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
# semery.fr certificates are managed manually in certificates-secret.yaml
# until OVH DNS API credentials are added for DNS-01 challenges
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: semery-fr
namespace: caddy
spec:
secretName: semery-fr-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: semery.fr
dnsNames:
- semery.fr
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-semery-fr
namespace: caddy
spec:
secretName: wildcard-semery-fr-tls
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: "*.semery.fr"
dnsNames:
- "*.semery.fr"
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiry
---
apiVersion: cert-manager.io/v1
kind: Certificate
@@ -6,7 +6,6 @@ resources:
- repository.yaml
- release.yaml
- certificates.yaml
- certificates-secret.yaml
- caddyfile.yaml
secretGenerator:
- name: caddy-values
+28 -38
View File
@@ -35,35 +35,25 @@ health:
volumes:
- name: vhaudiquet-fr-tls
secret:
secretName: ENC[AES256_GCM,data:vc6kDDdxbluL/BmJb4w9TKs=,iv:FLsFMqUQWs3vzuH6fO64qikNpSx/RGneZyow8WYXlo0=,tag:TVsfs/pUmiA6mYYwHgxDLw==,type:str]
optional: ENC[AES256_GCM,data:I1ftGg==,iv:P/KwiMPHM+YYUPJ+M5GBcgZGRTrIskbCir4fQH1XUug=,tag:hbqOTv6BrmkkQ/kE3bCx+A==,type:bool]
secretName: ENC[AES256_GCM,data:mdTS+RBfbQiY0c5aezbTURE=,iv:gQRWoRmGujhptSXm16JhX6VSHbB4yMdC3T7tPH1vfJs=,tag:DViHZOwOIPmHJQWTPUO8cw==,type:str]
optional: ENC[AES256_GCM,data:apLSVg==,iv:4ZZa85zmTuYb7D/p4mLZO++esFrPQyQ5xHCtT+aghS4=,tag:wWAEf3XWYKvsjwpfpyCb7w==,type:bool]
- name: wildcard-vhaudiquet-fr-tls
secret:
secretName: ENC[AES256_GCM,data:KSaPirEmnfOHqtwNr3SoK1IsCZ6HalzH2tw=,iv:TL9/VqSq2fW+2se9GK+bopfbcHu/lgpjlD4dHLKf7s0=,tag:SKgvfnPvca9o3bXxILLX9A==,type:str]
optional: ENC[AES256_GCM,data:65Ht9Q==,iv:EM0rH3i8MVVDXXrARxL6djISin8ScCEdZ/J43WL7A0I=,tag:rOcLiIOaDAqW4C5j6Zv+tA==,type:bool]
# semery.fr certs from manual secret (until OVH DNS API is configured)
secretName: ENC[AES256_GCM,data:Ww5/viWqr5mI51FqHizTRerAZnEyQONqdEg=,iv:VAMLvZ9yJxUCh7Kjf43J+M+ellkm5Xi3ZD5AlO95Rm4=,tag:F6H8LBi9kL9rrXJgVSbAmA==,type:str]
optional: ENC[AES256_GCM,data:LQEFAA==,iv:JkudOsHgn8qLEwqWhsuWnXjpCLJ3XrEexXtzjmOD+/Y=,tag:amUBIkXQIZnGQtxAAQ5mcw==,type:bool]
# semery.fr certs from cert-manager (OVH DNS-01)
- name: semery-fr-tls
secret:
secretName: ENC[AES256_GCM,data:kDiP6Hg4nLMM4FY6/C21YnFn,iv:bFgsIMkgHfSy8ZsK3NLc9cZ/5TRV3B2WzWkCFBGl5uc=,tag:atz2qInNTSX3u9b5N4fPnQ==,type:str]
optional: ENC[AES256_GCM,data:vfjgpQ==,iv:XZBZyekKMQQzrFE05vG2w6Pwd2ZQ+RerjF/T8FKbuc4=,tag:SVRfxbOLG7z8fWyxclrvzQ==,type:bool]
items:
- key: ENC[AES256_GCM,data:UumzQqzt/iy7oS7P+Q==,iv:3zV2rTEpHclFVRYRACzrs4+IXLOIw8HMSgWLyQ6fLp0=,tag:rOlhuN2qIN0vtwgahtvKvQ==,type:str]
path: ENC[AES256_GCM,data:QfXoPe/t8Q==,iv:Cj/4ngLtDha5fd5d7gn6OONGNdAjoEwq1zJc+xxYJTM=,tag:9q1DbomT9p4DonVsu3OBEw==,type:str]
- key: ENC[AES256_GCM,data:m72H1Se5snCNyNpe9w==,iv:ybvgDs1PNalk3i50mkIbph5KWEUefaDyoVUvKjqoJP0=,tag:+0c/3vDxjbOp6qn5VXvPxg==,type:str]
path: ENC[AES256_GCM,data:DJT6fW8uZQ==,iv:ImJQ19fJ2PBwil64M/vUu2TAhVjTYK14rfiTojK2E7A=,tag:2OkaIF6u7hCqsS2Bkp9v9w==,type:str]
secretName: ENC[AES256_GCM,data:dmLfoVbH9QKPMXPZZw==,iv:l9BKz66sdl9SssNzaz8yWoQ84ewDQprMv3rcHJQZhRA=,tag:NudQDM8eKC5aF6vX2ZQVVg==,type:str]
optional: ENC[AES256_GCM,data:Xc2tmw==,iv:xSa/xz/WibDqExKXjKSwLm5w8DOw9aZY44O1TZalfO8=,tag:Mpqi2ipn82+eWv8T2YvSng==,type:bool]
- name: wildcard-semery-fr-tls
secret:
secretName: ENC[AES256_GCM,data:AZVY6PS2tzVnU5mSVlbH621e,iv:HToh6ymWjFGK+xw1+MKAP2RGKJd+PuFC4My7erFeAOc=,tag:W2pksdZFrEFKzPrGwJ+d8g==,type:str]
optional: ENC[AES256_GCM,data:LbarYQ==,iv:FUiIoSlbc/5Tj1t2LIxEPC6Ey7DgSaezrr2+lTr8roY=,tag:dlqb5SFpm1JDwn9qwaTP8A==,type:bool]
items:
- key: ENC[AES256_GCM,data:8xY5dDL5KSNDAk1mTB58WtriIRNeFw==,iv:Ng7twP5cr/TfKpENug7kgZ1Pa24vhV0/wFtxCelRLZU=,tag:powPtyjVogU/NO4LSyT2pA==,type:str]
path: ENC[AES256_GCM,data:AIvmIcXtDQ==,iv:JshIK8HzTkMlZsDcdX0AIsrkyLST3qUdtLkEP29E/O8=,tag:njYcODU/bWN7XXDwsHV9Uw==,type:str]
- key: ENC[AES256_GCM,data:NqW+4UFJx3AjfS9BFoG3dhOsbHoy4g==,iv:TMMd96OebuBwBT80BzXDYHD/38l+cSDQ9q067/Dqkk0=,tag:IOL89DD3vDjbNm/qYbSUig==,type:str]
path: ENC[AES256_GCM,data:f5PVx/WfxQ==,iv:4aFgPWiyp0lnQFboQCprI9lAGCkSfrO03TlD/Pvx0do=,tag:aIvncQKaqtNu15jnpVSSww==,type:str]
secretName: ENC[AES256_GCM,data:jwwNceE6ZAD0bdUFceBBG+HQPjmLSQ==,iv:15rvS8NjtKszT8LFS9Z3DLCVMBwQ0GnY+o3DSr+G3jA=,tag:GMZ68i+1XmcvIJrOZxBo1w==,type:str]
optional: ENC[AES256_GCM,data:8p7hYQ==,iv:a3Al2ph6xuJCXkLaFW6K7WSJss51/d9kVrX3Xuh/5e4=,tag:JYUYRsmEN7brNrENFPe/DA==,type:bool]
- name: buildpath-win-tls
secret:
secretName: ENC[AES256_GCM,data:nUF53gg1cNg5fEWLsXmEh1Q=,iv:XUxXBDMrddGey7eoIebW/myOD0P/UDhY6bX4QSzT3X0=,tag:foE8OG/JcknTRzsxiKKzuA==,type:str]
optional: ENC[AES256_GCM,data:tCGcgw==,iv:LxIjr/EsHifL36wFkc1rb1irfk9fyWAoBxGaf+ksu1U=,tag:A96i+w6cTAk7NTxumcXzGw==,type:bool]
secretName: ENC[AES256_GCM,data:kTI0dBzdTAYXuvSZwZC9REg=,iv:xf4pQABQGiuv3IJtiZhNMsLeDPVef2awVW1DmDThOHI=,tag:74IqPca8TuCFuIpJ8RpQ2Q==,type:str]
optional: ENC[AES256_GCM,data:mxxqOA==,iv:p1omSzhLh4yYs303OZCE5DfCNrzjAxEo+TOfezw/oCo=,tag:4ye1QalWmtW98B37DtkcuQ==,type:bool]
- name: routes
configMap:
name: caddy-routes
@@ -111,27 +101,27 @@ affinity:
app.kubernetes.io/name: caddy
topologyKey: kubernetes.io/hostname
sops:
lastmodified: "2026-06-16T10:08:07Z"
mac: ENC[AES256_GCM,data:HeWRLHO8x7tJ3fGpSW0Pz6tkuYgQh6QJHF3q9KZD8EgCyuxxrnRh74sEOF9e/KjtmaNKF2ak6QkR2Taa9qD3yblMJp9Zjc3ivC2aMEKxtdJN8B3bxRr1Ln1Na2kSny3+X/c1nC1swWyNNgeQJvKQlvhXjK5S56Y5NG/n/PBT3Q4=,iv:HyiLtk4ueORKezmpmY/I4vXPBwEudqkwNpk4fgDheeY=,tag:2W46a3geF4Fi8jDsSCPNjA==,type:str]
lastmodified: "2026-07-09T21:17:10Z"
mac: ENC[AES256_GCM,data:5APgoOMa+m5xjn+wurqyOtBoohpV271AnW1Ic4Thcg88bXryhr4Xn86Yo7fMbE+N3YqJMCaeaH6hm4iY8IIhCHgO2ybgMq50Bo8AqWxr6MKEpTJDQS5vSSWPq/Y5qr7B3f5/gOyxwIGslF4isVRaQzlcjoKzfvHsZX8SPdFhXT8=,iv:ZuareabZmxIyhh8kZs+eHGeUI7NZhzxER6KJE1/EiWE=,tag:zQuTYSrU76YEf1u2312ruw==,type:str]
pgp:
- created_at: "2026-06-16T10:08:07Z"
- created_at: "2026-07-09T21:17:10Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiARAAhoTczAWaCpuZbHq+NrssLQG4Ys0yYNYM9nflFEOkD1Sa
rTEAhJACKNFYKJ6P2V4rBQtKHRdqMdVfrtaumgSvuKBX4wJW+nG/LUSXENJV/UD9
VqxiujfWKgps4XfNfuM/a7w9IbU7rk+mh+LBwwRpQeqEs7j1eZnJjQCBW4zGFeav
XWYx2VmqfwQ/XhVaiSCvJjeJJk/U54Dot9W2ZoKCX+5zyZ+dWsX2ggXQWsoQCfOK
uSTjjVKw80VvrDMX/TfbvNQDHNsljOSSeScA+lx6HElbDcAyUHxE99UAi6RVQazm
EjEHsVHvyR0Y/7hvVlo8FY7XS/81pXGLN22AcWbd1fIZlitRa9YbHZH1YWzWRzr5
JB2S+UMEOigw8WPg/1BAiFj3bCRn8aDyAMdUEKlbcXCYwoLynG6zVbgeuntYq0Zl
Y4zAi4+G+fHvdAqQz44p+AyP9hgS/qMBQwsUnAxGfltfVBEew2I/Vz5OugtDyLIW
UYrk+5LR+7cfJNCyCHQEyJL/YPsL1GDR1SP5YCrsDnuXPCEgwyRRLHFW8j2KCtLu
YX59FbVLqo2xzT5nEaIYbLLhEq3+5KaVIBqzGWAwSBbu7bXru6jIG6prVwofJQxx
HCz2leboRZ3ZrC4Y4itHHuMfmSCtiildRhgPtVnvUdiQz0dS+RLNesH4hRvvxBPS
XgF9gp+9JE/5XMxUmNNf0yUC1mlQuUHbC7JqLLpLBNAtQwljDLMIgPG0y5n2r0C3
zokdaebVj2XV9r7X25SQMyLzTdoXYqgGsoPBFnqQNpycg2HpmBX9isvqjbZ6x/g=
=AqxW
hQIMA7uy4qQr71wiAQ//eR5eIclcLkl8wtERUoVHXL5KGKzEaxyVv9D5gHz51C31
kmAfrAnjT9G5UeeoJlW8XLkh1IWNhArNBMtoiCNUPAtfVDxszs5IwPWul+s3wJhc
X7sDq7EnIgaJr2IszIOTJ4PYxZ/uhyMdqmvRTZXMaz43F96cuDLctV4CFaiig4aJ
IcNlPIyYyS4tuaGB+ScLtbcDDhNc/8VRWn09SRtpTop+PV4KRX6AqLmhGOc9Jf9l
Dg3Gqdkaxl3OuqIvcrTmEPBe3sjnjIIdtJeG4SAbMUzj1xoKupXeDBZDnfmS5nku
42WR5H4RInzusj5NXP50C7AeLD4qavB9hl5CaxzA6TVG1X7LcpmcqBsVVuFcSjZj
T80iKklV6Ct0MLlmbxlKFTJm8fSKevhS/hdfrkUNcqc4N6eBb8tx93x+FcDn0A6P
c1zPSKj1vs326nJSHw87wvooQWn/f9j+Om1KLOR/MiUWmoEAbgkIHi3+k2wpzFb/
faKpshye0/XA/CZHFePv/U7sw8nKhfPhJCuO/IRrHKYzx0u/aqgOtPCURh5hS/fU
8dPQkbywgN67IRRKVz70cxn367cP1vn7L1AmzJfBd56NnViXXlS/DuitpnyTQpnP
tLG6qelq3Ul2A1J3BB1pfHR27IpKzd1UPD7HMhvvgSA7ErLq/VhF/kT1dx6s1fXS
XgFZ5XcyJQRc4Uxh2eFeEPOdWMAFRps6scfBsQuWR8m3cQvLatzcku1S/YDp56Kn
oUZmfvdQGpUuxsumVYCqk1+mQn02lkA1p2Y4ztrpLDCbhZXZ/fIT6Y1uYX+c0ew=
=0kw6
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
@@ -22,3 +22,23 @@ spec:
dnsZones:
- vhaudiquet.fr
- buildpath.win
# OVH solver for semery.fr (via cert-manager-webhook-ovh)
- dns01:
webhook:
groupName: acme.aureq.com
solverName: ovh
config:
endpoint: ovh-eu
authenticationMethod: application
applicationKeyRef:
name: ovh-credentials
key: applicationKey
applicationSecretRef:
name: ovh-credentials
key: applicationSecret
applicationConsumerKeyRef:
name: ovh-credentials
key: consumerKey
selector:
dnsZones:
- semery.fr
@@ -3,3 +3,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- clusterissuer.yaml
- ovh-credentials-secret.yaml
- ovh-secret-reader-rbac.yaml
@@ -0,0 +1,50 @@
# OVH API Credentials for DNS-01 Challenges
#
# OVH API credentials with the following permissions:
# - GET, POST, PUT, DELETE on /domain/zone/*
#
# The secret MUST live in the cert-manager-webhook-ovh namespace (cert-manager),
# because for a ClusterIssuer cert-manager sets the webhook's ResourceNamespace
# to the webhook's own namespace, and the webhook looks up credential secrets
# there (see ch.ResourceNamespace in the webhook's ovhClient() function).
#
# SOPS will encrypt the stringData fields on pre-commit.
apiVersion: v1
kind: Secret
metadata:
name: ovh-credentials
namespace: cert-manager
labels:
app.kubernetes.io/name: cert-manager-webhook-ovh
app.kubernetes.io/component: ovh-credentials
type: Opaque
stringData:
applicationKey: ENC[AES256_GCM,data:0+y+m8n/eup5lY/vGW5ASQ==,iv:VSIhfNAvSNOLq92TVcaW54ygU1wgAv+u35HZ0cbP6UU=,tag:KD+cyIesTQgqEzGMro8xyA==,type:str]
applicationSecret: ENC[AES256_GCM,data:sP0febHRFF/atAFlRM6sYXoM+Lp6Rnf7d0IQKcsa0vY=,iv:nHYMHSsOclkZmQJSjcz2oXMHsDTct5hTmJz1L7xgvpA=,tag:oCGoRP7R0W+PTNRCeLFvyg==,type:str]
consumerKey: ENC[AES256_GCM,data:vw/Q39CpSc5o1ntPDMT3844aLbTHQrSYH8RhoZFFZrQ=,iv:6B0F9Zq56inpW7AS8okbpqJkRK3WkBjX6sIqclOP9Hs=,tag:nnbgwBMBM4JZg/IEYzRvVw==,type:str]
sops:
lastmodified: "2026-07-10T05:06:52Z"
mac: ENC[AES256_GCM,data:0/VEDE1ZuIyzkaleosS/KHYX44762TbScrJGJylwV21d7U6YgpwRMOXvU9xn3rHsDXnh5IAmAtrXQTYJFN1vcF1DNw5O9+TQKVoO6B5rsel/YyKRU4s7aYcfDgbW9dO1wn33K65KFtM+0Qv187DzEn1by449TgWIWP/M5U40PE4=,iv:hIGzMwsas8VxC4941ABeoocYWSlVSz9KW7a5tTAoRXI=,tag:n/EJEkEBL20carqVesMBsw==,type:str]
pgp:
- created_at: "2026-07-10T05:06:52Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiARAAu0va03SPYOU23iUjoTMiXJ6+nMhIX8lsurvmCvi+wIqk
c7qu0lTfXv62IjkY6fIKtOE7TN9TiipjzXG2QJaK94QeiFpe9M90qNo09qEIje9m
DepTrLfyINFT0SY2eihl+nXhBXuEDSiD5K60OsXGPN92hJMwCad5jJuB7xpmrX0m
X0A1Bl9orce/do/YJoy5hq0persB/VSeCKlptNzqpmpRIA3J6AdCDKXQOMqAymXN
FXAxbjEQNcXhfU12Y/cVpa1hS7ap5OJCnWOPkFEA8y1ESVnPpryuTIfVlFUhW3/Z
Dhpb9OXKdi2IVYdbaY8+3UfSsXxTVOge7jCMbJq3aa7ZvGt5fTjXG4zc9A6RqSGh
ASOPSkRRSZB0d97NhUQJGgfcaWFvsfkaTAUVB2Ip/+Udnt/tGIE99RGJizxSVO9N
2aVJIukqng8aNPfth8mgWYJpCETMb4piLmVg2ptDqelCqXlUAskxWzMWtAhyzOgw
lZ2dcAn7aj9YtLaKAW9rjV8EqHEqQg0ychRNMeyRiN/CnNJp6Q2wl1/EyQUpzb0a
1I/ifFAW8FbWTVIbZv6njkl1XNaoav54qEn1qSABcljM0h1Ulb9WKMJiXH4368jf
Yhl38JDAn5NZBEzxpuaih1XK5yVri0/1ascpuMvfOxLKniUR9tla8+WEL97+aejS
XgGsrH+/uzRVSAT+44rExi43MWCAwNRUaVrX8UiGjA/z8qPVdwBVih4CMKgfQ8VW
1KewStOY217BXuVrDbvHEAkuOotEP0Jnan0epoWs47DSasNgzAcWrBgom0l/avI=
=Gdou
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(data|stringData|.*.key|.*.crt)$
version: 3.10.2
@@ -0,0 +1,41 @@
# RBAC granting the cert-manager-webhook-ovh service account read access to the
# OVH credentials secret.
#
# The cert-manager-webhook-ovh chart only auto-creates this secret-reader Role
# when using its built-in `issuers[]` mechanism. Since we manage the
# ClusterIssuer and the credentials secret manually, we declare the RBAC here.
#
# The webhook runs in the cert-manager namespace under the
# `cert-manager-webhook-ovh` service account (created by the Helm release).
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: cert-manager-webhook-ovh:ovh-secret-reader
namespace: cert-manager
labels:
app.kubernetes.io/name: cert-manager-webhook-ovh
app.kubernetes.io/component: ovh-secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch"]
resourceNames:
- ovh-credentials
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cert-manager-webhook-ovh:ovh-secret-reader
namespace: cert-manager
labels:
app.kubernetes.io/name: cert-manager-webhook-ovh
app.kubernetes.io/component: ovh-secret-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: cert-manager-webhook-ovh:ovh-secret-reader
subjects:
- apiGroup: ""
kind: ServiceAccount
name: cert-manager-webhook-ovh
namespace: cert-manager
@@ -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-ovh-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-ovh
namespace: cert-manager
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: cert-manager-webhook-ovh
namespace: cert-manager
chart: cert-manager-webhook-ovh
version: "v0.9.13"
interval: 1m
valuesFrom:
- kind: Secret
name: cert-manager-webhook-ovh-values
@@ -0,0 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: cert-manager-webhook-ovh
namespace: cert-manager
spec:
interval: 1m
url: https://aureq.github.io/cert-manager-webhook-ovh
@@ -0,0 +1,45 @@
# cert-manager-webhook-ovh Values
# groupName must match the ClusterIssuer webhook stanza
groupName: acme.aureq.com
# cert-manager deployment configuration for RBAC
# The webhook creates ClusterRole/RoleBinding so cert-manager's
# service account can create the "ovh" ChallengePayload resources
certManager:
namespace: cert-manager
serviceAccountName: cert-manager
# Pod configuration
pod:
replicas: 1
resources:
requests:
cpu: 10m
memory: 32Mi
limits:
cpu: 100m
memory: 128Mi
sops:
lastmodified: "2026-07-09T22:31:08Z"
mac: ENC[AES256_GCM,data:QjrNj355tJVZRsYQdkM73Ld7X8EvMM7O/1vF3QnTYJ9vWbh78irLocbtnyBeaR9o3g0mxO6Ugjlukj+S0HhIX/WS1XHEfs/3n3rE0zS/fxGJ0D3Alam/n/WPOsYHUiCBD86JtU83AjgncISY4yp/VheV3kRgSdl+ye4AGAjhq7A=,iv:p8yqNCcskTfDfEGbM5Qyb60C4pFv4BOuLpEApEzHLFY=,tag:KntExeQwJbBREaz2nY+1uQ==,type:str]
pgp:
- created_at: "2026-07-09T22:31:08Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ/8Dn4nEIbQXuETxE6RUBkNTO/eN5pHh47lqSwBBbYDSi8C
8rcJmdq8P+v00geLdMlM35OcjHFb9UCVeHFsAEYt6Q2jL4QNa2aOEDOqGnhKP+zx
KKtW2Ngx76Ow9N2C5JN9DXk9n+PC/qWdPLNJY+GiW/KbPmVxAulJpmYlJHfs1EOh
0mSRSS+7sgGLHWmgU362zC508lkKxh8HKxmq1+1lf+fWIe8N7Sl0fx55kq168hae
NcdogRpoVT555hRils7eqzj0C/KTVOi7CR4pS7VJyiNy2fu2OASmmcM6UEqCyJfV
NTUdMpnjb05UwfbuUnIg6j/FoqS49ufGxKPrM9t7JrFSuyGqduF7P/ifv5zwMuIZ
SNeR/X8xUksK6R4/uTmUx5sgF+Jv7tCRvcp+DhsDe1mMmO8czXC5Mt3cR+uwYoms
hN+9/oYEZr13qn5Ek0dy9NESkZIzYPCXYXZrx8GLqaHCJEQbpIZCAN+llOyQaQzU
jcvPAYbTewBw4ewKUS0KcvLd1pfzvYyvtzwHuMIVJwrf7x5bzhzxAgVOGkEVlVq/
7pGO9TYXGl3kD7tf25oCGzAerVC+EVcL11sq4zawvL4PovEZFP9mzhR7EfY3t/3C
vGVu6vPmCJOwdis9+Kdr3PKubnMqWGn5KCCX1x13qhsHc239N7cVKkyx3dTBaArS
XAG6KxKe/cQicIVC8/N1Cna9uQnTF5ZnFVfJNW1nkYyF1E+ofW6kKDr3ITotKLDP
hXXPT+vsB2fL3faBG4xb6owrMuQ1S0DmB3mqjSCXtpS7q0FDg22Tq9BtaEni
=x1th
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
version: 3.10.2
+1
View File
@@ -54,6 +54,7 @@ spec:
- metadata:
name: etcd-data
spec:
storageClassName: longhorn
accessModes: ["ReadWriteOnce"]
resources:
requests:
@@ -30,6 +30,9 @@ data:
docker-r740 IN A 10.1.2.212
truenas IN A 10.1.2.139
; P330
p330 IN A 10.1.2.132
; PVE
pve IN A 10.1.2.10
docker-homeprod IN A 10.1.2.12
+1 -1
View File
@@ -2,7 +2,7 @@ storageClass:
create: true
name: nfs-csi
annotations:
storageclass.kubernetes.io/is-default-class: "true"
storageclass.kubernetes.io/is-default-class: "false"
parameters:
server: truenas.lan
share: /mnt/fast_app_data/kube/
@@ -14,6 +14,7 @@ spec:
path: ./kubernetes/system/cert-manager-issuer
dependsOn:
- name: cert-manager
- name: cert-manager-webhook-ovh
decryption:
provider: sops
secretRef:
@@ -0,0 +1,20 @@
# Flux Kustomization for cert-manager-webhook-ovh
# Depends on cert-manager being fully operational (CRDs installed)
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: cert-manager-webhook-ovh
namespace: flux-system
spec:
interval: 10m
prune: true
sourceRef:
kind: GitRepository
name: homeprod
path: ./kubernetes/system/cert-manager-webhook-ovh
dependsOn:
- name: cert-manager
decryption:
provider: sops
secretRef:
name: flux-sops
@@ -5,4 +5,5 @@ kind: Kustomization
resources:
- webhook.yaml
- cert-manager.yaml
- cert-manager-webhook-ovh.yaml
- cert-manager-issuer.yaml
@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: longhorn-system
resources:
- namespace.yaml
- repository.yaml
- release.yaml
secretGenerator:
- name: longhorn-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,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: longhorn-system
labels:
pod-security.kubernetes.io/enforce: privileged
+19
View File
@@ -0,0 +1,19 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: longhorn
namespace: longhorn-system
spec:
interval: 1m
chart:
spec:
sourceRef:
kind: HelmRepository
name: longhorn
namespace: longhorn-system
chart: longhorn
version: '1.12.0'
interval: 1m
valuesFrom:
- kind: Secret
name: longhorn-values
@@ -0,0 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: longhorn
namespace: longhorn-system
spec:
interval: 1m
url: https://charts.longhorn.io
+99
View File
@@ -0,0 +1,99 @@
# Longhorn Helm Values
# Single-node R740 cluster, backup target on TrueNAS NFS
defaultSettings:
# Single node — only 1 replica needed
defaultReplicaCount: 1
# NFS backup target on TrueNAS
backupTarget: nfs://truenas.lan:/mnt/fast_app_data/longhorn-backup
# Allow full disk usage on single-node
storageOverProvisioningPercentage: 100
storageMinimalAvailablePercentage: 10
# Auto-salvage on node reboot (single-node)
autoSalvage: true
# Disable strict flushing for better single-node performance
strictSyncReplicas: false
persistence:
defaultClass: true
defaultClassReplicaCount: 1
# Retain volumes on PVC delete — safer during migration
reclaimPolicy: Retain
# Mount options for ext4
fstype: ext4
longhorn-ui:
replicas: 1
longhorn-manager:
tolerations:
- key: ENC[AES256_GCM,data:yWX0dGIIpvCVOeZbvY7Jjbr/t8mcyLiLmzHrCz0bwXIBRgG0Ig==,iv:m1wOItluKgql41BzKoBvgyjBaG7Fplz1c4ScONjZ/c8=,tag:g+7730DA8KzK/7ApgumDcQ==,type:str]
operator: Exists
effect: NoSchedule
# Tolerate failover nodes so longhorn-manager runs there
- key: ENC[AES256_GCM,data:PksAIja6KV8+,iv:oDJ47xFoCKysl8yf9EQVJp9PGLKJQMWUOsIAcirjzJM=,tag:n9HVtUsERVmlQqeXpObvWQ==,type:str]
value: ENC[AES256_GCM,data:JDsyDMHMh0k=,iv:D3oVkD3tsxVE1hvcMcCYogoD7IVetrAbMzp6VCTOF6s=,tag:/cx/tQuGf1ImsVTZkwwt6A==,type:str]
operator: Equal
effect: NoSchedule
longhorn-driver-deployer:
tolerations:
- key: ENC[AES256_GCM,data:lv255SLl898RJh8gx569wM+lL/YF8AUXhKuwEY5RUmw84z96Vg==,iv:3gY3OSeoVitIZd4rMgZK18bI9xtcsk1T0U0PphLZSZw=,tag:TMZLWxRTZB9fwNIThytnxw==,type:str]
operator: Exists
effect: NoSchedule
- key: ENC[AES256_GCM,data:dI3C6OPdnAW0,iv:G5vU4nypD3s/vffdQneasxHzUUXHsgUThjUtYKRfk7U=,tag:SD08w8Gz1WDaee/cM89hZA==,type:str]
value: ENC[AES256_GCM,data:GsbeabJMKjQ=,iv:qA+wC10BjpzMprPgoLeiBKAU1RcSef/yMfDzWbgAJ/s=,tag:9qS5tquOU7EkZ7hrd+VZhw==,type:str]
operator: Equal
effect: NoSchedule
# instance-manager is a DaemonSet that places engine/replica pods on storage
# nodes — it must tolerate the failover taint
longhorn-instance-manager:
tolerations:
- key: ENC[AES256_GCM,data:3EHDHYKTaDyk,iv:D6z907ohAGqkoytBZ7s1aWJI6tRPsF7N798MwF9um+Q=,tag:zvEM2dzoWx4kLbIrbVW45Q==,type:str]
value: ENC[AES256_GCM,data:D9mG3tOtQas=,iv:JpbQDYKMZvNQSkoxw+1zwTeIrdrIr09oa7v8tZupSb0=,tag:5ypuOjneHKzSsJEXE4enxA==,type:str]
operator: Equal
effect: NoSchedule
# Disable ingress for now
ingress:
enabled: false
# Recurring backup and snapshot schedules
# - Daily snapshots: fast local recovery from accidental deletes
# - Daily NFS backups: DR if node is lost
recurringJobs:
enable: true
jobs:
- name: daily-snapshot
task: snapshot
cron: 0 2 * * *
retain: 7
concurrency: 2
labels:
type: snapshot
- name: daily-backup
task: backup
cron: 0 3 * * *
retain: 7
concurrency: 2
labels:
type: backup
sops:
lastmodified: "2026-07-21T20:19:40Z"
mac: ENC[AES256_GCM,data:AxrJFHyOjoP5c/1uFhlSIwe0E/oIesu52EU7zIxwLVQ8p5r4Fa7/NpSbeK+K3lAuYTrUiXvjWdbmVO5IQhvd+PNj6nXPDxBO92eoxzMtit9m8mnAiEGGYayeJMU9DaKPlGEs3CUaYzAizP1Ub0n9g2iq8CRcHVO9zOQ/DfUk/tA=,iv:bQN9v/n0/Z1Sm/2Im1SGskjqnxJhAbBT19IC6HDSufA=,tag:qLxMS7HovkykXHqsvinLDQ==,type:str]
pgp:
- created_at: "2026-07-21T20:19:40Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiARAAoYpVy7elPl0SzogH1900DzVQsGV0SylAh4h40+YOmezu
k4y501ZRIRv/r0RiPp7pJ7o9zynVQdcsRos0h0GBy7BbzIXMJpjRrpqXIvSeqtgt
S5FJIUTkVraKo8kKtDvtbiN6rz7qwXkBsppF1euZRVVj33hCX8vqL6EvhP9FBOBO
354Q9h92F+D94+JQt3K8n3hW/qaQIcDhJ4AgC7I9NPrA+rb6alUWQPKfFDSlYUkb
mxrLz4DE5GOVwMhaE/PrKLYeV5+KLRdsK0zzQadxG4AUSwpK7ZwLIIcQ1L0zQ7ST
SxruIi5EahUsDxNKTZvv5NnUFZpncqKCFfnxF69xIlXTAXujdOfY/21HZ+mmCmKJ
kTmsNtlKE1ltDwzHiowdLFqzHlME83bdRtYPuMcvhAFSv7yuVd9zfXIjQNjPFmYc
55EedJBrvFbxWU9QP1dEUpcELGXroiOowjGM4cushYgeBZzXJkTMg7JmoB+HNiWY
Ld9XaJOOiJ87BI1zbhkMPo+L9NSF5zbtYkBiulSyb58gTuixTESnYxPxWC71EZLV
BxFEkapXY0Y89h6uFH7FKz0MiniojA4zvNFt2LQYICWXdUAJqqpeIRv88iUJkKDv
THVf7+wltQ4EHTuu4E0rCsg+3GeOIIYkBrLESjEsaSvQ/B+Iz9JgUFRkRr7lVvzS
XgFL/2+26cLT81wCUson9XW5X2GZV8SgfWTFAXCbaaTxluJU1l1jIyWUoWnTFF2S
tKqNQBSsUmYlXIyize8d+ueVQcldN91bwpOXVmVIbghFX2Cp3H+4R5qfJxpH6yA=
=03zX
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
version: 3.10.2
+36 -9
View File
@@ -1,11 +1,38 @@
ingress:
main:
enabled: true
hosts:
- host: dashy.lan
paths:
- path: /
pathType: ImplementationSpecific
main:
enabled: true
hosts:
- host: dashy.lan
paths:
- path: /
pathType: ImplementationSpecific
persistence:
data:
enabled: true
data:
enabled: true
storageClass: longhorn
sops:
lastmodified: "2026-07-18T14:22:16Z"
mac: ENC[AES256_GCM,data:Svz0vne+sbEj5wlL4FHUrTPMHlprWnZqR/X3tEmpDIxKBD0C/C9G1LgPYBiHviHEiiD/XbxxgH9nGcJIo4blbWc6xRNyUjnhGoLPIPJlG9LclXVh7dm4w4bETq4VfQZjLpY6bhv0q2d5GgxI6i+Hp16FSk8Y4kReErmQdg/Vh9I=,iv:zt3Rjt9KapI7LMMlpA/MPWK8EgGVFRpLJ4d2r4P74eY=,tag:fo2CgvaoT6bz1xmYA9DvGg==,type:str]
pgp:
- created_at: "2026-07-18T14:22:16Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7uy4qQr71wiAQ//RB59ULu3tagTsLKGU+2azz+yTgnRKUsauEhC2trzbpRO
Au0RYwQMyDmYwTAvIIRM5gWUGlIFpsiftpK6rZbvJiwb8npYVSF7/shqKzlqYiSi
+BHJCSqfk+emN9ULivxmq3i+t4YZ97Ap7uo+pUyBmpz4jis0vdiIDIszLwtJ3U0J
t6s2gVl4KE2STyVH+ShERG3yjSBuzvFpJVwSdAfGKeA8K6Umr1LQH/2JSlq8/2fV
Zubfu6aGXg564rsbZNs+P9/b5M4FmpSlSOlp6OLWnIosl9CfRVDynnRyLImvQ/8p
2Asf6vrAQZJVXHraGMfePNNA9sRxhMa8f1qgHDWGfHh8D8/7JwK5xoFWrNoO7Gb6
aex15qielE0N4jpiEC3t+jjRUQLdjMuSlRET/0RVrZRhZ4lUTOOINnw8eUic0vRz
OjPj/ffVI4+zqfq7GnopISWBtfMdc23Y+7IhL/8LWRJGLRSqB0fNQxWeS7dtze2o
2BWk+DsHiG/1bz2hdezuR+KTRoj7qPDI/eKPc1BpyHfVm8k1y3pFmwWY3rwGAGA0
6bB1VSBriE3pcvUiJw4N+Ja/C7gLcUVAtNKGLqxuWr+2bm/ExWItAbnZ/3cZzKtC
bULu5ic/zN3O3rRWCS5nFU+nD37pq1Iq3eHXOWygwNOJJcGGHl9+3j01y2iXUl3S
XgGKWMKthF+9AD1bASp8tZ1lfNuqyxjbdVyWb7xqRGa2jzWgAcVUaCWWaJU6yASF
LdXY6xVKr1DgBs666nv4xAESsgvZ9xP6e+YaxAr3piRuDhzoNFeveOD99tsgZOg=
=zi2x
-----END PGP MESSAGE-----
fp: DC6910268E657FF70BA7EC289974494E76938DDC
encrypted_regex: ^(password|value|ssh-key|api-key|user|username|privateKey|clientSecret|clientId|apiKey|extraArgs.*|.*Secret.*|extraEnvVars|.*SECRET.*|.*secret.*|key|.*Password|.*\.ya?ml)$
version: 3.10.2