[ci skip] Phase 1: PostgreSQL migrated to CNPG on local disk

Major milestone - shared PostgreSQL moved from NFS to CloudNativePG:
- CNPG cluster (pg-cluster) running in dbaas namespace on local-path storage
- PostGIS image (ghcr.io/cloudnative-pg/postgis:16) for dawarich compatibility
- All 20 databases and 19 roles restored from pg_dumpall backup
- postgresql.dbaas Service patched to point at CNPG primary
- Old PG deployment scaled to 0 (NFS data intact for rollback)
- All 12+ dependent services verified running:
  authentik, n8n, dawarich, tandoor, linkwarden, netbox, woodpecker,
  rybbit, affine, health, resume, trading-bot, atuin
- Authentik PgBouncer working through the switched endpoint

TODO: codify CNPG cluster in Terraform, add 2nd replica, update backup CronJob
This commit is contained in:
Viktor Barzin 2026-02-28 19:08:06 +00:00
parent 7724214054
commit 9d9c8fdc12
No known key found for this signature in database
GPG key ID: 0EB088298288D958
26 changed files with 733 additions and 7 deletions

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

148
stacks/atuin/main.tf Normal file
View file

@ -0,0 +1,148 @@
variable "tls_secret_name" { type = string }
variable "nfs_server" { type = string }
variable "postgresql_host" { type = string }
variable "atuin_postgresql_password" { type = string }
resource "kubernetes_namespace" "atuin" {
metadata {
name = "atuin"
labels = {
tier = local.tiers.aux
}
}
}
module "tls_secret" {
source = "../../modules/kubernetes/setup_tls_secret"
namespace = kubernetes_namespace.atuin.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "atuin" {
wait_for_rollout = false
metadata {
name = "atuin"
namespace = kubernetes_namespace.atuin.metadata[0].name
labels = {
app = "atuin"
tier = local.tiers.aux
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "atuin"
}
}
template {
metadata {
labels = {
app = "atuin"
}
}
spec {
container {
name = "atuin"
image = "ghcr.io/atuinsh/atuin:3f775df"
args = ["start"]
port {
container_port = 8888
}
env {
name = "ATUIN_HOST"
value = "0.0.0.0"
}
env {
name = "ATUIN_PORT"
value = "8888"
}
env {
name = "ATUIN_OPEN_REGISTRATION"
value = "false"
}
env {
name = "ATUIN_DB_URI"
value = "postgres://atuin:${var.atuin_postgresql_password}@${var.postgresql_host}:5432/atuin"
}
env {
name = "RUST_LOG"
value = "info"
}
volume_mount {
name = "config"
mount_path = "/config"
}
resources {
requests = {
memory = "64Mi"
cpu = "50m"
}
limits = {
memory = "256Mi"
cpu = "500m"
}
}
liveness_probe {
http_get {
path = "/healthz"
port = 8888
}
initial_delay_seconds = 10
period_seconds = 30
}
readiness_probe {
http_get {
path = "/healthz"
port = 8888
}
initial_delay_seconds = 5
period_seconds = 10
}
}
volume {
name = "config"
nfs {
server = var.nfs_server
path = "/mnt/main/atuin"
}
}
}
}
}
}
resource "kubernetes_service" "atuin" {
metadata {
name = "atuin"
namespace = kubernetes_namespace.atuin.metadata[0].name
labels = {
app = "atuin"
}
}
spec {
selector = {
app = "atuin"
}
port {
name = "http"
port = 80
target_port = 8888
}
}
}
module "ingress" {
source = "../../modules/kubernetes/ingress_factory"
namespace = kubernetes_namespace.atuin.metadata[0].name
name = "atuin"
tls_secret_name = var.tls_secret_name
}

1
stacks/atuin/secrets Symbolic link
View file

@ -0,0 +1 @@
../../secrets

View file

@ -0,0 +1,8 @@
include "root" {
path = find_in_parent_folders()
}
dependency "platform" {
config_path = "../platform"
skip_outputs = true
}

10
stacks/atuin/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

10
stacks/nextcloud/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

10
stacks/ollama/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

10
stacks/platform/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

10
stacks/rybbit/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

10
stacks/servarr/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -47,8 +47,9 @@ resource "kubernetes_namespace" "trading-bot" {
metadata {
name = "trading-bot"
labels = {
tier = local.tiers.edge
"resource-governance/custom-quota" = "true"
tier = local.tiers.edge
"resource-governance/custom-quota" = "true"
"goldilocks.fairwinds.com/vpa-update-mode" = "off"
}
}
}
@ -265,6 +266,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
value = env.value
}
}
env {
name = "TRADING_OTEL_METRICS_PORT"
value = "9091"
}
resources {
requests = {
cpu = "10m"
@ -288,6 +293,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
value = env.value
}
}
env {
name = "TRADING_OTEL_METRICS_PORT"
value = "9092"
}
resources {
requests = {
cpu = "100m"
@ -311,6 +320,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
value = env.value
}
}
env {
name = "TRADING_OTEL_METRICS_PORT"
value = "9093"
}
resources {
requests = {
cpu = "10m"
@ -334,6 +347,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
value = env.value
}
}
env {
name = "TRADING_OTEL_METRICS_PORT"
value = "9094"
}
resources {
requests = {
cpu = "10m"
@ -357,6 +374,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
value = env.value
}
}
env {
name = "TRADING_OTEL_METRICS_PORT"
value = "9095"
}
resources {
requests = {
cpu = "10m"
@ -380,6 +401,10 @@ resource "kubernetes_deployment" "trading-bot-workers" {
value = env.value
}
}
env {
name = "TRADING_OTEL_METRICS_PORT"
value = "9096"
}
resources {
requests = {
cpu = "10m"

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}

10
stacks/ytdlp/tiers.tf Normal file
View file

@ -0,0 +1,10 @@
# Generated by Terragrunt. Sig: nIlQXj57tbuaRZEa
locals {
tiers = {
core = "0-core"
cluster = "1-cluster"
gpu = "2-gpu"
edge = "3-edge"
aux = "4-aux"
}
}