# Gitea — local git server for private/sensitive infrastructure repos # Accessible at git.neuralplatform.dev (internal only, real TLS) resource "kubernetes_config_map" "gitea_custom_css" { metadata { name = "gitea-custom-css" namespace = kubernetes_namespace.git.metadata[0].name } data = { "header.tmpl" = <<-TMPL TMPL "custom.css" = <<-CSS /* ── Typography & base ── */ :root { --color-primary: #6366f1; --color-primary-dark: #4f46e5; --color-secondary: #8b5cf6; --color-bg: #0f0f17; --color-surface: #16161f; --color-surface-2: #1e1e2e; --color-border: #2a2a3d; --color-text: #e2e2f0; --color-text-muted: #8888aa; --color-green: #22d3a5; --radius: 10px; } body { background: var(--color-bg) !important; color: var(--color-text) !important; font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif !important; } /* ── Top navbar ── */ .navbar, #navbar { background: var(--color-surface) !important; border-bottom: 1px solid var(--color-border) !important; box-shadow: 0 1px 12px rgba(0,0,0,0.4) !important; } .navbar .brand svg, .navbar .brand img { filter: brightness(1.2); } /* ── Sidebar & panels ── */ .repository, .ui.container, .ui.segment, .ui.card, .ui.cards > .card { background: var(--color-surface) !important; border: 1px solid var(--color-border) !important; border-radius: var(--radius) !important; } /* ── Buttons ── */ .ui.primary.button, .ui.green.button { background: var(--color-primary) !important; border: none !important; border-radius: 8px !important; } .ui.primary.button:hover { background: var(--color-primary-dark) !important; } /* ── Inputs ── */ input, textarea, select, .ui.input > input, .ui.dropdown { background: var(--color-surface-2) !important; border: 1px solid var(--color-border) !important; color: var(--color-text) !important; border-radius: 8px !important; } /* ── Sign-in page ── */ .user.signin .ui.segment, .user.signup .ui.segment { background: var(--color-surface) !important; border: 1px solid var(--color-border) !important; border-radius: 16px !important; box-shadow: 0 8px 32px rgba(0,0,0,0.5) !important; padding: 2.5rem !important; } /* ── Repo file tree ── */ .repository.file.list .file-list { background: var(--color-surface) !important; border-radius: var(--radius) !important; border: 1px solid var(--color-border) !important; } .repository.file.list .file-list tr:hover td { background: var(--color-surface-2) !important; } /* ── Labels & badges ── */ .ui.label { border-radius: 6px !important; } /* ── Dashboard activity feed ── */ .feeds .news { border-bottom: 1px solid var(--color-border) !important; } /* ── Code blocks ── */ pre, code { background: var(--color-surface-2) !important; border: 1px solid var(--color-border) !important; border-radius: 6px !important; } /* ── Muted footer ── */ #footer { background: var(--color-surface) !important; border-top: 1px solid var(--color-border) !important; color: var(--color-text-muted) !important; } CSS } } resource "kubernetes_namespace" "git" { metadata { name = "git" labels = { managed-by = "terraform" tier = "infrastructure" } } } resource "kubernetes_persistent_volume_claim" "gitea_data" { wait_until_bound = false metadata { name = "gitea-data" namespace = kubernetes_namespace.git.metadata[0].name } spec { access_modes = ["ReadWriteOnce"] resources { requests = { storage = "20Gi" } } } } resource "kubernetes_secret" "gitea_db_secret" { metadata { name = "gitea-db" namespace = kubernetes_namespace.git.metadata[0].name } data = { password = var.gitea_db_password } } resource "kubernetes_deployment" "gitea" { metadata { name = "gitea" namespace = kubernetes_namespace.git.metadata[0].name labels = { app = "gitea" } } spec { replicas = 1 strategy { type = "Recreate" } selector { match_labels = { app = "gitea" } } template { metadata { labels = { app = "gitea" } } spec { container { name = "gitea" image = "gitea/gitea:1.22" port { name = "http" container_port = 3000 } port { name = "ssh" container_port = 22 } env { name = "GITEA__database__DB_TYPE" value = "postgres" } env { name = "GITEA__database__HOST" value = "postgres-postgresql.platform.svc.cluster.local:5432" } env { name = "GITEA__database__NAME" value = "gitea" } env { name = "GITEA__database__USER" value = "gitea" } env { name = "GITEA__database__PASSWD" value_from { secret_key_ref { name = kubernetes_secret.gitea_db_secret.metadata[0].name key = "password" } } } env { name = "GITEA__server__DOMAIN" value = var.gitea_domain } env { name = "GITEA__server__ROOT_URL" value = "https://${var.gitea_domain}" } env { name = "GITEA__server__SSH_DOMAIN" value = var.gitea_domain } env { name = "GITEA__server__SSH_PORT" value = "30022" } env { name = "GITEA__server__START_SSH_SERVER" value = "false" } env { name = "GITEA__service__DISABLE_REGISTRATION" value = "true" } env { name = "GITEA__service__REQUIRE_SIGNIN_VIEW" value = "true" } env { name = "GITEA__security__INSTALL_LOCK" value = "true" } env { name = "GITEA__packages__ENABLED" value = "true" } env { name = "GITEA__webhook__ALLOWED_HOST_LIST" value = "192.168.0.0/24,10.0.0.0/8" } volume_mount { name = "data" mount_path = "/data" } volume_mount { name = "custom-css" mount_path = "/data/gitea/custom/public/assets/css/custom.css" sub_path = "custom.css" } volume_mount { name = "custom-css" mount_path = "/data/gitea/custom/templates/custom/header.tmpl" sub_path = "header.tmpl" } resources { requests = { memory = "256Mi" cpu = "100m" } limits = { memory = "512Mi" cpu = "500m" } } } volume { name = "data" persistent_volume_claim { claim_name = kubernetes_persistent_volume_claim.gitea_data.metadata[0].name } } volume { name = "custom-css" config_map { name = kubernetes_config_map.gitea_custom_css.metadata[0].name } } } } } depends_on = [helm_release.postgres] } resource "kubernetes_service" "gitea" { metadata { name = "gitea" namespace = kubernetes_namespace.git.metadata[0].name } spec { selector = { app = "gitea" } port { name = "http" port = 3000 target_port = 3000 } port { name = "ssh" port = 22 target_port = 22 node_port = 30022 } type = "NodePort" } } resource "kubernetes_ingress_v1" "gitea" { metadata { name = "gitea" namespace = kubernetes_namespace.git.metadata[0].name annotations = { "traefik.ingress.kubernetes.io/router.entrypoints" = "websecure" "cert-manager.io/cluster-issuer" = "letsencrypt-prod" } } spec { tls { hosts = [var.gitea_domain] secret_name = "gitea-tls" } rule { host = var.gitea_domain http { path { path = "/" path_type = "Prefix" backend { service { name = kubernetes_service.gitea.metadata[0].name port { number = 3000 } } } } } } } depends_on = [helm_release.cert_manager] }