[ci skip] Deploy health dashboard service

Apple Health data visualization app (Svelte + FastAPI + Caddy).
Uses shared PostgreSQL via DBaaS, NFS storage for uploads,
accessible at health.viktorbarzin.me.
This commit is contained in:
Viktor Barzin 2026-02-08 01:54:24 +00:00
parent 00943e92fe
commit 43bee50de8
No known key found for this signature in database
GPG key ID: 0EB088298288D958
6 changed files with 162 additions and 7 deletions

View file

@ -0,0 +1,129 @@
variable "tls_secret_name" {}
variable "tier" { type = string }
variable "postgresql_password" {}
variable "secret_key" { type = string }
resource "kubernetes_namespace" "health" {
metadata {
name = "health"
}
}
module "tls_secret" {
source = "../setup_tls_secret"
namespace = kubernetes_namespace.health.metadata[0].name
tls_secret_name = var.tls_secret_name
}
resource "kubernetes_deployment" "health" {
metadata {
name = "health"
namespace = kubernetes_namespace.health.metadata[0].name
labels = {
app = "health"
tier = var.tier
}
}
spec {
replicas = 1
selector {
match_labels = {
app = "health"
}
}
template {
metadata {
labels = {
app = "health"
}
}
spec {
container {
name = "health"
image = "viktorbarzin/health:latest"
port {
container_port = 80
}
env {
name = "DATABASE_URL"
value = "postgresql+asyncpg://health:${var.postgresql_password}@postgresql.dbaas.svc.cluster.local:5432/health"
}
env {
name = "SECRET_KEY"
value = var.secret_key
}
env {
name = "UPLOAD_DIR"
value = "/data/uploads"
}
env {
name = "WEBAUTHN_RP_ID"
value = "health.viktorbarzin.me"
}
env {
name = "WEBAUTHN_ORIGIN"
value = "https://health.viktorbarzin.me"
}
env {
name = "COOKIE_SECURE"
value = "true"
}
volume_mount {
name = "uploads"
mount_path = "/data/uploads"
}
resources {
requests = {
memory = "256Mi"
cpu = "100m"
}
limits = {
memory = "1Gi"
cpu = "1"
}
}
}
volume {
name = "uploads"
nfs {
server = "10.0.10.15"
path = "/mnt/main/health"
}
}
}
}
}
}
resource "kubernetes_service" "health" {
metadata {
name = "health"
namespace = kubernetes_namespace.health.metadata[0].name
labels = {
app = "health"
}
}
spec {
selector = {
app = "health"
}
port {
name = "http"
port = 80
target_port = 80
}
}
}
module "ingress" {
source = "../ingress_factory"
namespace = kubernetes_namespace.health.metadata[0].name
name = "health"
tls_secret_name = var.tls_secret_name
max_body_size = "100m"
}

View file

@ -122,6 +122,8 @@ variable "openrouter_api_key" { type = string }
variable "slack_bot_token" { type = string }
variable "slack_channel" { type = string }
variable "affine_postgresql_password" { type = string }
variable "health_postgresql_password" { type = string }
variable "health_secret_key" { type = string }
variable "defcon_level" {
@ -143,7 +145,7 @@ locals {
], # Activel used services
# Optional services
5 : [
"blog", "descheduler", "drone", "hackmd", "kms", "privatebin", "vault", "reloader", "city-guesser", "echo",
"blog", "descheduler", "drone", "hackmd", "health", "kms", "privatebin", "vault", "reloader", "city-guesser", "echo",
"url", "excalidraw", "travel_blog", "dashy", "send", "ytdlp", "wealthfolio", "rybbit", "stirling-pdf",
"networking-toolbox", "navidrome", "freshrss", "forgejo", "tor-proxy", "real-estate-crawler", "n8n",
"changedetection", "linkwarden", "matrix", "homepage", "meshcentral", "diun", "cyberchef", "ntfy", "ollama",
@ -1089,6 +1091,17 @@ module "plotting-book" {
depends_on = [null_resource.core_services]
}
module "health" {
source = "./health"
for_each = contains(local.active_modules, "health") ? { health = true } : {}
tls_secret_name = var.tls_secret_name
postgresql_password = var.health_postgresql_password
secret_key = var.health_secret_key
tier = local.tiers.aux
depends_on = [null_resource.core_services]
}
module "whisper" {
source = "./whisper"
for_each = contains(local.active_modules, "whisper") ? { whisper = true } : {}