feat(storage): migrate 38 NFS PVCs to proxmox-lvm (Wave 2)

Add proxmox-lvm PVCs with pvc-autoresizer annotations for all
remaining single-pod app data services. Deployments updated to
use new block storage PVCs. Old NFS modules retained for rollback.

Services: affine, changedetection, diun, excalidraw, f1-stream,
hackmd, isponsorblocktv, matrix, n8n, send, grampsweb, health,
onlyoffice, owntracks, paperless-ngx, privatebin, resume,
speedtest, stirling-pdf, tandoor, rybbit (clickhouse), tor-proxy
(torrserver), whisper+piper, frigate (config), ollama (ui),
servarr (prowlarr/listenarr/qbittorrent), aiostreams, freshrss
(extensions), meshcentral (data+files), openclaw (data+home+
openlobster), technitium, mailserver (data+roundcube html+enigma),
dbaas (pgadmin).

Strategy set to Recreate where needed for RWO volumes.
This commit is contained in:
Viktor Barzin 2026-04-04 19:25:12 +03:00
parent 3dccbca95b
commit cb8a808700
36 changed files with 1166 additions and 50 deletions

View file

@ -153,6 +153,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/affine"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "affine-data-proxmox"
namespace = kubernetes_namespace.affine.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "affine" {
metadata {
name = "affine"
@ -167,6 +189,9 @@ resource "kubernetes_deployment" "affine" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "affine"
@ -294,7 +319,7 @@ resource "kubernetes_deployment" "affine" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -66,6 +66,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/changedetection"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "changedetection-data-proxmox"
namespace = kubernetes_namespace.changedetection.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "changedetection" {
metadata {
name = "changedetection"
@ -162,7 +184,7 @@ resource "kubernetes_deployment" "changedetection" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -208,7 +208,7 @@ resource "helm_release" "mysql_cluster" {
matchExpressions = [{
key = "kubernetes.io/hostname"
operator = "NotIn"
values = ["k8s-node1", "k8s-node2"]
values = ["k8s-node1"]
}]
}]
}
@ -305,6 +305,28 @@ module "nfs_pgadmin" {
nfs_path = "/mnt/main/postgresql/pgadmin"
}
resource "kubernetes_persistent_volume_claim" "pgadmin_proxmox" {
wait_until_bound = false
metadata {
name = "dbaas-pgadmin-proxmox"
namespace = kubernetes_namespace.dbaas.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_postgresql_backup" {
source = "../../../../modules/kubernetes/nfs_volume"
name = "dbaas-postgresql-backup"
@ -988,6 +1010,9 @@ resource "kubernetes_deployment" "pgadmin" {
}
}
spec {
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "pgadmin"
@ -1038,7 +1063,7 @@ resource "kubernetes_deployment" "pgadmin" {
# name = "pgadmin-config"
# }
persistent_volume_claim {
claim_name = module.nfs_pgadmin.claim_name
claim_name = kubernetes_persistent_volume_claim.pgadmin_proxmox.metadata[0].name
}
}
dns_config {
@ -1116,7 +1141,7 @@ resource "kubernetes_cron_job_v1" "postgresql-backup" {
_wb0=$(awk '/^write_bytes/{print $2}' /proc/$$/io 2>/dev/null || echo 0)
export now=$(date +"%Y_%m_%d_%H_%M")
PGPASSWORD=$PGPASSWORD pg_dumpall -h postgresql.dbaas -U postgres | gzip -9 > /backup/dump_$now.sql.gz
PGPASSWORD=$PGPASSWORD pg_dumpall -h pg-cluster-rw.dbaas -U postgres | gzip -9 > /backup/dump_$now.sql.gz
# Rotate 14 day retention
cd /backup

View file

@ -89,6 +89,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/diun"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "diun-data-proxmox"
namespace = kubernetes_namespace.diun.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "diun" {
metadata {
name = "diun"
@ -104,6 +126,9 @@ resource "kubernetes_deployment" "diun" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "diun"
@ -216,7 +241,7 @@ resource "kubernetes_deployment" "diun" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -30,6 +30,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/excalidraw"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "excalidraw-data-proxmox"
namespace = kubernetes_namespace.excalidraw.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "excalidraw" {
metadata {
name = "excalidraw"
@ -41,6 +63,9 @@ resource "kubernetes_deployment" "excalidraw" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "excalidraw"
@ -89,7 +114,7 @@ resource "kubernetes_deployment" "excalidraw" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -51,6 +51,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/f1-stream"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "f1-stream-data-proxmox"
namespace = kubernetes_namespace.f1-stream.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "f1-stream" {
metadata {
name = "f1-stream"
@ -65,6 +87,9 @@ resource "kubernetes_deployment" "f1-stream" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "f1-stream"
@ -114,7 +139,7 @@ resource "kubernetes_deployment" "f1-stream" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -95,6 +95,28 @@ module "nfs_extensions" {
nfs_path = "/mnt/main/freshrss/extensions"
}
resource "kubernetes_persistent_volume_claim" "extensions_proxmox" {
wait_until_bound = false
metadata {
name = "freshrss-extensions-proxmox"
namespace = kubernetes_namespace.immich.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "freshrss" {
metadata {
@ -172,7 +194,7 @@ resource "kubernetes_deployment" "freshrss" {
volume {
name = "extensions"
persistent_volume_claim {
claim_name = module.nfs_extensions.claim_name
claim_name = kubernetes_persistent_volume_claim.extensions_proxmox.metadata[0].name
}
}
}

View file

@ -31,6 +31,28 @@ module "nfs_config" {
nfs_path = "/mnt/main/frigate/config"
}
resource "kubernetes_persistent_volume_claim" "config_proxmox" {
wait_until_bound = false
metadata {
name = "frigate-config-proxmox"
namespace = kubernetes_namespace.frigate.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_media" {
source = "../../modules/kubernetes/nfs_volume"
name = "frigate-media"
@ -172,7 +194,7 @@ for name, det in stats.get('detectors', {}).items():
volume {
name = "config"
persistent_volume_claim {
claim_name = module.nfs_config.claim_name
claim_name = kubernetes_persistent_volume_claim.config_proxmox.metadata[0].name
}
}
volume {

View file

@ -70,6 +70,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/grampsweb"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "grampsweb-data-proxmox"
namespace = kubernetes_namespace.grampsweb.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "random_password" "secret_key" {
length = 64
special = false
@ -157,6 +179,9 @@ resource "kubernetes_deployment" "grampsweb" {
# Disabled: grampsweb uses ~1.8GB actual memory with 3GB limit per replica.
# Not actively used disabled to reduce cluster memory pressure (2026-03-14 node2 OOM incident).
replicas = 0
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "grampsweb"
@ -308,7 +333,7 @@ resource "kubernetes_deployment" "grampsweb" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -28,6 +28,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/hackmd"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "hackmd-data-proxmox"
namespace = kubernetes_namespace.hackmd.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "hackmd" {
metadata {
name = "hackmd"
@ -44,7 +66,7 @@ resource "kubernetes_deployment" "hackmd" {
spec {
replicas = 1
strategy {
type = "RollingUpdate" # DB is external so we can roll
type = "Recreate"
}
selector {
match_labels = {
@ -140,7 +162,7 @@ resource "kubernetes_deployment" "hackmd" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -28,6 +28,28 @@ module "nfs_uploads" {
nfs_path = "/mnt/main/health"
}
resource "kubernetes_persistent_volume_claim" "uploads_proxmox" {
wait_until_bound = false
metadata {
name = "health-uploads-proxmox"
namespace = kubernetes_namespace.health.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "2Gi"
}
}
}
}
resource "kubernetes_deployment" "health" {
metadata {
name = "health"
@ -42,6 +64,9 @@ resource "kubernetes_deployment" "health" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "health"
@ -118,7 +143,7 @@ resource "kubernetes_deployment" "health" {
volume {
name = "uploads"
persistent_volume_claim {
claim_name = module.nfs_uploads.claim_name
claim_name = kubernetes_persistent_volume_claim.uploads_proxmox.metadata[0].name
}
}
}

View file

@ -20,6 +20,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/isponsorblocktv/vermont"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "isponsorblocktv-data-proxmox"
namespace = kubernetes_namespace.isponsorblocktv.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
# Mute and skip ads for vermont smart tv
resource "kubernetes_deployment" "isponsorblocktv-vermont" {
metadata {
@ -32,6 +54,9 @@ resource "kubernetes_deployment" "isponsorblocktv-vermont" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "isponsorblocktv-vermont"
@ -64,7 +89,7 @@ resource "kubernetes_deployment" "isponsorblocktv-vermont" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -170,6 +170,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/mailserver"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "mailserver-data-proxmox"
namespace = kubernetes_namespace.mailserver.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "mailserver" {
metadata {
name = "mailserver"
@ -428,7 +450,7 @@ resource "kubernetes_deployment" "mailserver" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
# iscsi {
# target_portal = "iscsi.viktorbarzin.lan:3260"

View file

@ -46,6 +46,50 @@ module "nfs_roundcube_enigma" {
# }
resource "kubernetes_persistent_volume_claim" "roundcube_html_proxmox" {
wait_until_bound = false
metadata {
name = "roundcubemail-html-proxmox"
namespace = kubernetes_namespace.mailserver.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "roundcube_enigma_proxmox" {
wait_until_bound = false
metadata {
name = "roundcubemail-enigma-proxmox"
namespace = kubernetes_namespace.mailserver.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "roundcubemail" {
metadata {
name = "roundcubemail"
@ -61,7 +105,7 @@ resource "kubernetes_deployment" "roundcubemail" {
spec {
replicas = "1"
strategy {
type = "RollingUpdate"
type = "Recreate"
}
selector {
match_labels = {
@ -176,13 +220,13 @@ resource "kubernetes_deployment" "roundcubemail" {
volume {
name = "html"
persistent_volume_claim {
claim_name = module.nfs_roundcube_html.claim_name
claim_name = kubernetes_persistent_volume_claim.roundcube_html_proxmox.metadata[0].name
}
}
volume {
name = "enigma"
persistent_volume_claim {
claim_name = module.nfs_roundcube_enigma.claim_name
claim_name = kubernetes_persistent_volume_claim.roundcube_enigma_proxmox.metadata[0].name
}
}
dns_config {

View file

@ -29,6 +29,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/matrix"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "matrix-data-proxmox"
namespace = kubernetes_namespace.matrix.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "matrix" {
metadata {
name = "matrix"
@ -40,6 +62,9 @@ resource "kubernetes_deployment" "matrix" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "matrix"
@ -94,7 +119,7 @@ resource "kubernetes_deployment" "matrix" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
volume {

View file

@ -37,6 +37,50 @@ module "nfs_files" {
nfs_path = "/mnt/main/meshcentral/meshcentral-files"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "meshcentral-data-proxmox"
namespace = kubernetes_namespace.meshcentral.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_persistent_volume_claim" "files_proxmox" {
wait_until_bound = false
metadata {
name = "meshcentral-files-proxmox"
namespace = kubernetes_namespace.meshcentral.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_backups" {
source = "../../modules/kubernetes/nfs_volume"
name = "meshcentral-backups"
@ -133,13 +177,13 @@ resource "kubernetes_deployment" "meshcentral" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
volume {
name = "files"
persistent_volume_claim {
claim_name = module.nfs_files.claim_name
claim_name = kubernetes_persistent_volume_claim.files_proxmox.metadata[0].name
}
}
volume {

View file

@ -55,6 +55,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/n8n"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "n8n-data-proxmox"
namespace = kubernetes_namespace.n8n.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
# --- RBAC: Allow n8n to exec into OpenClaw pods for task execution ---
resource "kubernetes_service_account" "n8n" {
@ -112,6 +134,9 @@ resource "kubernetes_deployment" "n8n" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "n8n"
@ -206,7 +231,7 @@ resource "kubernetes_deployment" "n8n" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -76,6 +76,28 @@ module "nfs_ollama_ui_data" {
nfs_path = "/mnt/main/ollama"
}
resource "kubernetes_persistent_volume_claim" "ollama_ui_data_proxmox" {
wait_until_bound = false
metadata {
name = "ollama-ui-data-proxmox"
namespace = kubernetes_namespace.ollama.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
# resource "helm_release" "ollama" {
# namespace = kubernetes_namespace.ollama.metadata[0].name
# name = "ollama"
@ -266,6 +288,9 @@ resource "kubernetes_deployment" "ollama-ui" {
spec {
# Disabled: reduce cluster memory pressure (2026-03-14 OOM incident)
replicas = 0
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "ollama-ui"
@ -310,7 +335,7 @@ resource "kubernetes_deployment" "ollama-ui" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_ollama_ui_data.claim_name
claim_name = kubernetes_persistent_volume_claim.ollama_ui_data_proxmox.metadata[0].name
}
}
}

View file

@ -96,6 +96,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/onlyoffice"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "onlyoffice-data-proxmox"
namespace = kubernetes_namespace.onlyoffice.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "onlyoffice-document-server" {
metadata {
name = "onlyoffice-document-server"
@ -200,7 +222,7 @@ resource "kubernetes_deployment" "onlyoffice-document-server" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -280,6 +280,28 @@ module "nfs_openclaw_home" {
nfs_path = "/mnt/main/openclaw/home"
}
resource "kubernetes_persistent_volume_claim" "home_proxmox" {
wait_until_bound = false
metadata {
name = "openclaw-home-proxmox"
namespace = kubernetes_namespace.openclaw.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_workspace" {
source = "../../modules/kubernetes/nfs_volume"
name = "openclaw-workspace"
@ -296,6 +318,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/openclaw/data"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "openclaw-data-proxmox"
namespace = kubernetes_namespace.openclaw.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
## cc-config NFS volume removed replaced by dotfiles repo clone in init container
## See init_container "install-dotfiles" in the deployment
@ -556,7 +600,7 @@ resource "kubernetes_deployment" "openclaw" {
volume {
name = "openclaw-home"
persistent_volume_claim {
claim_name = module.nfs_openclaw_home.claim_name
claim_name = kubernetes_persistent_volume_claim.home_proxmox.metadata[0].name
}
}
volume {
@ -568,7 +612,7 @@ resource "kubernetes_deployment" "openclaw" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
volume {
@ -1028,6 +1072,28 @@ module "nfs_openlobster_data" {
nfs_path = "/mnt/main/openclaw/openlobster-data"
}
resource "kubernetes_persistent_volume_claim" "openlobster_data_proxmox" {
wait_until_bound = false
metadata {
name = "openlobster-data-proxmox"
namespace = kubernetes_namespace.openclaw.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "random_password" "openlobster_graphql_token" {
length = 32
special = false
@ -1138,7 +1204,7 @@ resource "kubernetes_deployment" "openlobster" {
volume {
name = "openlobster-data"
persistent_volume_claim {
claim_name = module.nfs_openlobster_data.claim_name
claim_name = kubernetes_persistent_volume_claim.openlobster_data_proxmox.metadata[0].name
}
}
}

View file

@ -89,6 +89,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/owntracks"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "owntracks-data-proxmox"
namespace = kubernetes_namespace.owntracks.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "owntracks" {
metadata {
name = "owntracks"
@ -156,7 +178,7 @@ resource "kubernetes_deployment" "owntracks" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -68,6 +68,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/paperless-ngx"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "paperless-ngx-data-proxmox"
namespace = kubernetes_namespace.paperless-ngx.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "paperless-ngx" {
metadata {
@ -178,7 +200,7 @@ resource "kubernetes_deployment" "paperless-ngx" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -29,6 +29,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/privatebin"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "privatebin-data-proxmox"
namespace = kubernetes_namespace.privatebin.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "privatebin" {
metadata {
name = "privatebin"
@ -81,7 +103,7 @@ resource "kubernetes_deployment" "privatebin" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -162,6 +162,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/resume"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "resume-data-proxmox"
namespace = kubernetes_namespace.resume.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
# Reactive Resume app
resource "kubernetes_deployment" "resume" {
metadata {
@ -174,6 +196,9 @@ resource "kubernetes_deployment" "resume" {
}
spec {
replicas = 0 # Scaled down with printer depends on browserless chromium
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "resume"
@ -299,7 +324,7 @@ resource "kubernetes_deployment" "resume" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -70,6 +70,28 @@ module "nfs_clickhouse_data" {
nfs_path = "/mnt/main/clickhouse"
}
resource "kubernetes_persistent_volume_claim" "clickhouse_data_proxmox" {
wait_until_bound = false
metadata {
name = "rybbit-clickhouse-data-proxmox"
namespace = kubernetes_namespace.rybbit.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_config_map" "clickhouse_memory" {
metadata {
name = "clickhouse-memory-config"
@ -176,7 +198,7 @@ resource "kubernetes_deployment" "clickhouse" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_clickhouse_data.claim_name
claim_name = kubernetes_persistent_volume_claim.clickhouse_data_proxmox.metadata[0].name
}
}
volume {

View file

@ -30,6 +30,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/send"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "send-data-proxmox"
namespace = kubernetes_namespace.send.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "send" {
metadata {
name = "send"
@ -44,6 +66,9 @@ resource "kubernetes_deployment" "send" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "send"
@ -113,7 +138,7 @@ resource "kubernetes_deployment" "send" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -24,6 +24,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/servarr/aiostreams"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "aiostreams-data-proxmox"
namespace = kubernetes_namespace.aiostreams.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "aiostreams" {
metadata {
name = "aiostreams"
@ -35,6 +57,9 @@ resource "kubernetes_deployment" "aiostreams" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "aiostreams"
@ -82,7 +107,7 @@ resource "kubernetes_deployment" "aiostreams" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -11,6 +11,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/servarr/listenarr"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "servarr-listenarr-data-proxmox"
namespace = "servarr"
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_downloads" {
source = "../../../modules/kubernetes/nfs_volume"
name = "servarr-listenarr-downloads"
@ -33,6 +55,9 @@ resource "kubernetes_deployment" "listenarr" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "listenarr"
@ -69,7 +94,7 @@ resource "kubernetes_deployment" "listenarr" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
volume {

View file

@ -15,6 +15,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/servarr/prowlarr"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "servarr-prowlarr-data-proxmox"
namespace = "servarr"
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_downloads" {
source = "../../../modules/kubernetes/nfs_volume"
name = "servarr-prowlarr-downloads"
@ -37,6 +59,9 @@ resource "kubernetes_deployment" "prowlarr" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "prowlarr"
@ -93,7 +118,7 @@ resource "kubernetes_deployment" "prowlarr" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
volume {

View file

@ -15,6 +15,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/servarr/qbittorrent"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "servarr-qbittorrent-data-proxmox"
namespace = "servarr"
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
module "nfs_downloads" {
source = "../../../modules/kubernetes/nfs_volume"
name = "servarr-qbittorrent-downloads"
@ -45,6 +67,9 @@ resource "kubernetes_deployment" "qbittorrent" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "qbittorrent"
@ -96,7 +121,7 @@ resource "kubernetes_deployment" "qbittorrent" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
volume {
@ -172,6 +197,192 @@ resource "kubernetes_service" "qbittorrent-torrenting" {
}
resource "kubernetes_cron_job_v1" "qbittorrent_ratio_monitor" {
metadata {
name = "qbittorrent-ratio-monitor"
namespace = "servarr"
}
spec {
concurrency_policy = "Replace"
failed_jobs_history_limit = 3
successful_jobs_history_limit = 3
schedule = "*/5 * * * *"
job_template {
metadata {}
spec {
backoff_limit = 2
ttl_seconds_after_finished = 300
template {
metadata {}
spec {
container {
name = "ratio-monitor"
image = "docker.io/library/python:3.12-alpine"
command = ["/bin/sh", "-c", "set -euo pipefail; pip install -q requests > /dev/null 2>&1; python3 /tmp/monitor.py"]
volume_mount {
name = "script"
mount_path = "/tmp/monitor.py"
sub_path = "monitor.py"
}
resources {
requests = {
memory = "64Mi"
cpu = "10m"
}
limits = {
memory = "128Mi"
}
}
}
volume {
name = "script"
config_map {
name = kubernetes_config_map.ratio_monitor_script.metadata[0].name
}
}
dns_config {
option {
name = "ndots"
value = "2"
}
}
}
}
}
}
}
}
resource "kubernetes_config_map" "ratio_monitor_script" {
metadata {
name = "qbt-ratio-monitor-script"
namespace = "servarr"
}
data = {
"monitor.py" = <<-PYEOF
import requests, json, sys
from collections import defaultdict
from urllib.parse import urlparse
QB_URL = "http://qbittorrent.servarr.svc.cluster.local"
PUSHGW = "http://prometheus-prometheus-pushgateway.monitoring:9091"
try:
torrents = requests.get(f"{QB_URL}/api/v2/torrents/info", timeout=10).json()
except Exception as e:
print(f"ERROR: {e}", file=sys.stderr)
sys.exit(1)
try:
transfer = requests.get(f"{QB_URL}/api/v2/transfer/info", timeout=10).json()
except Exception:
transfer = {}
tracker_stats = defaultdict(lambda: {
"uploaded": 0, "downloaded": 0, "size": 0,
"count": 0, "seeding": 0, "downloading": 0,
"seed_time_total": 0, "unsatisfied": 0
})
for t in torrents:
tracker_url = t.get("tracker", "")
if not tracker_url:
domain = "unknown"
else:
try:
domain = urlparse(tracker_url).hostname or "unknown"
except Exception:
domain = "unknown"
if "myanonamouse" in domain or "mam" in domain.lower():
label = "mam"
elif "audiobookbay" in domain or "abb" in domain.lower():
label = "audiobookbay"
else:
label = domain.replace(".", "_")
s = tracker_stats[label]
s["uploaded"] += t.get("uploaded", 0)
s["downloaded"] += t.get("downloaded", 0)
s["size"] += t.get("size", 0)
s["count"] += 1
s["seed_time_total"] += t.get("seeding_time", 0)
state = t.get("state", "")
if state in ("uploading", "stalledUP", "forcedUP", "queuedUP"):
s["seeding"] += 1
elif state in ("downloading", "stalledDL", "forcedDL", "queuedDL"):
s["downloading"] += 1
if t.get("seeding_time", 0) < 259200 and t.get("progress", 0) >= 1.0:
s["unsatisfied"] += 1
for tracker, stats in tracker_stats.items():
dl = stats["downloaded"]
ul = stats["uploaded"]
ratio = ul / dl if dl > 0 else 0.0
metrics = f"""# HELP qbt_tracker_uploaded_bytes Total bytes uploaded for tracker
# TYPE qbt_tracker_uploaded_bytes gauge
qbt_tracker_uploaded_bytes {ul}
# HELP qbt_tracker_downloaded_bytes Total bytes downloaded for tracker
# TYPE qbt_tracker_downloaded_bytes gauge
qbt_tracker_downloaded_bytes {dl}
# HELP qbt_tracker_ratio Upload/download ratio for tracker
# TYPE qbt_tracker_ratio gauge
qbt_tracker_ratio {ratio:.4f}
# HELP qbt_tracker_torrents_total Total torrents for tracker
# TYPE qbt_tracker_torrents_total gauge
qbt_tracker_torrents_total {stats['count']}
# HELP qbt_tracker_seeding Torrents currently seeding
# TYPE qbt_tracker_seeding gauge
qbt_tracker_seeding {stats['seeding']}
# HELP qbt_tracker_downloading Torrents currently downloading
# TYPE qbt_tracker_downloading gauge
qbt_tracker_downloading {stats['downloading']}
# HELP qbt_tracker_seed_time_total_seconds Total seed time across all torrents
# TYPE qbt_tracker_seed_time_total_seconds gauge
qbt_tracker_seed_time_total_seconds {stats['seed_time_total']}
# HELP qbt_tracker_unsatisfied Torrents not yet seeded 72h
# TYPE qbt_tracker_unsatisfied gauge
qbt_tracker_unsatisfied {stats['unsatisfied']}
# HELP qbt_tracker_size_bytes Total size of all torrents
# TYPE qbt_tracker_size_bytes gauge
qbt_tracker_size_bytes {stats['size']}
"""
resp = requests.post(
f"{PUSHGW}/metrics/job/qbt-ratio-monitor/tracker/{tracker}",
data=metrics, timeout=10
)
print(f"Tracker {tracker}: ratio={ratio:.3f} ul={ul} dl={dl} count={stats['count']} seeding={stats['seeding']} unsatisfied={stats['unsatisfied']} -> {resp.status_code}")
connected = 1 if transfer.get("connection_status") == "connected" else 0
dht = transfer.get("dht_nodes", 0)
dl_speed = transfer.get("dl_info_speed", 0)
ul_speed = transfer.get("up_info_speed", 0)
global_metrics = f"""# HELP qbt_connected Whether qBittorrent is connected
# TYPE qbt_connected gauge
qbt_connected {connected}
# HELP qbt_dht_nodes Number of DHT nodes
# TYPE qbt_dht_nodes gauge
qbt_dht_nodes {dht}
# HELP qbt_dl_speed_bytes Current download speed
# TYPE qbt_dl_speed_bytes gauge
qbt_dl_speed_bytes {dl_speed}
# HELP qbt_ul_speed_bytes Current upload speed
# TYPE qbt_ul_speed_bytes gauge
qbt_ul_speed_bytes {ul_speed}
"""
resp = requests.post(
f"{PUSHGW}/metrics/job/qbt-ratio-monitor/tracker/global",
data=global_metrics, timeout=10
)
print(f"Global: connected={connected} dht={dht} dl_speed={dl_speed} ul_speed={ul_speed} -> {resp.status_code}")
PYEOF
}
}
module "ingress" {
source = "../../../modules/kubernetes/ingress_factory"
namespace = "servarr"

View file

@ -61,6 +61,28 @@ module "nfs_config" {
nfs_path = "/mnt/main/speedtest"
}
resource "kubernetes_persistent_volume_claim" "config_proxmox" {
wait_until_bound = false
metadata {
name = "speedtest-config-proxmox"
namespace = kubernetes_namespace.speedtest.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "speedtest" {
metadata {
name = "speedtest"
@ -75,6 +97,9 @@ resource "kubernetes_deployment" "speedtest" {
}
spec {
replicas = 1
strategy {
type = "Recreate"
}
selector {
match_labels = {
app = "speedtest"
@ -171,7 +196,7 @@ resource "kubernetes_deployment" "speedtest" {
volume {
name = "config"
persistent_volume_claim {
claim_name = module.nfs_config.claim_name
claim_name = kubernetes_persistent_volume_claim.config_proxmox.metadata[0].name
}
}
}

View file

@ -29,6 +29,28 @@ module "nfs_configs" {
nfs_path = "/mnt/main/stirling-pdf"
}
resource "kubernetes_persistent_volume_claim" "configs_proxmox" {
wait_until_bound = false
metadata {
name = "stirling-pdf-configs-proxmox"
namespace = kubernetes_namespace.stirling-pdf.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "stirling-pdf" {
metadata {
name = "stirling-pdf"
@ -79,7 +101,7 @@ resource "kubernetes_deployment" "stirling-pdf" {
volume {
name = "configs"
persistent_volume_claim {
claim_name = module.nfs_configs.claim_name
claim_name = kubernetes_persistent_volume_claim.configs_proxmox.metadata[0].name
}
}
}

View file

@ -62,6 +62,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/tandoor"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "tandoor-data-proxmox"
namespace = kubernetes_namespace.tandoor.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "tandoor" {
metadata {
name = "tandoor"
@ -201,7 +223,7 @@ resource "kubernetes_deployment" "tandoor" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}

View file

@ -92,6 +92,28 @@ module "nfs_config" {
nfs_path = "/mnt/main/technitium"
}
resource "kubernetes_persistent_volume_claim" "config_proxmox" {
wait_until_bound = false
metadata {
name = "technitium-config-proxmox"
namespace = kubernetes_namespace.technitium.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "technitium" {
# resource "kubernetes_daemonset" "technitium" {
metadata {
@ -104,11 +126,7 @@ resource "kubernetes_deployment" "technitium" {
}
spec {
strategy {
type = "RollingUpdate"
rolling_update {
max_unavailable = "0"
max_surge = "1"
}
type = "Recreate"
}
# replicas = 1
selector {
@ -207,7 +225,7 @@ resource "kubernetes_deployment" "technitium" {
volume {
name = "nfs-config"
persistent_volume_claim {
claim_name = module.nfs_config.claim_name
claim_name = kubernetes_persistent_volume_claim.config_proxmox.metadata[0].name
}
}
volume {

View file

@ -137,6 +137,28 @@ module "nfs_torrserver_data" {
nfs_path = "/mnt/main/tor-proxy/torrserver"
}
resource "kubernetes_persistent_volume_claim" "torrserver_data_proxmox" {
wait_until_bound = false
metadata {
name = "tor-proxy-torrserver-data-proxmox"
namespace = kubernetes_namespace.tor-proxy.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "torrserver" {
metadata {
name = "torrserver"
@ -204,7 +226,7 @@ resource "kubernetes_deployment" "torrserver" {
volume {
name = "torrserver-data"
persistent_volume_claim {
claim_name = module.nfs_torrserver_data.claim_name
claim_name = kubernetes_persistent_volume_claim.torrserver_data_proxmox.metadata[0].name
}
}
}

View file

@ -28,6 +28,28 @@ module "nfs_data" {
nfs_path = "/mnt/main/whisper"
}
resource "kubernetes_persistent_volume_claim" "data_proxmox" {
wait_until_bound = false
metadata {
name = "whisper-data-proxmox"
namespace = kubernetes_namespace.whisper.metadata[0].name
annotations = {
"resize.topolvm.io/threshold" = "80%"
"resize.topolvm.io/increase" = "100%"
"resize.topolvm.io/storage_limit" = "5Gi"
}
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "proxmox-lvm"
resources {
requests = {
storage = "1Gi"
}
}
}
}
resource "kubernetes_deployment" "whisper" {
metadata {
name = "whisper"
@ -92,7 +114,7 @@ resource "kubernetes_deployment" "whisper" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}
@ -210,7 +232,7 @@ resource "kubernetes_deployment" "piper" {
volume {
name = "data"
persistent_volume_claim {
claim_name = module.nfs_data.claim_name
claim_name = kubernetes_persistent_volume_claim.data_proxmox.metadata[0].name
}
}
}