# Package registries — Verdaccio (npm) and devpi (PyPI) # Both proxy to public registries and cache locally on Legion resource "kubernetes_namespace" "packages" { metadata { name = "packages" labels = { managed-by = "terraform" tier = "infrastructure" } } } resource "kubernetes_persistent_volume_claim" "verdaccio_data" { metadata { name = "verdaccio-data" namespace = kubernetes_namespace.packages.metadata[0].name } spec { access_modes = ["ReadWriteOnce"] resources { requests = { storage = "10Gi" } } } } resource "kubernetes_persistent_volume_claim" "devpi_data" { metadata { name = "devpi-data" namespace = kubernetes_namespace.packages.metadata[0].name } spec { access_modes = ["ReadWriteOnce"] resources { requests = { storage = "10Gi" } } } } # Verdaccio — npm proxy/cache resource "kubernetes_config_map" "verdaccio_config" { metadata { name = "verdaccio-config" namespace = kubernetes_namespace.packages.metadata[0].name } data = { "config.yaml" = <<-EOT storage: /verdaccio/storage auth: htpasswd: file: /verdaccio/storage/htpasswd max_users: 1 uplinks: npmjs: url: https://registry.npmjs.org/ cache: true packages: '@harmonic-framework/*': access: $authenticated publish: $authenticated unpublish: $authenticated '**': access: $all publish: $authenticated proxy: npmjs listen: 0.0.0.0:4873 server: keepAliveTimeout: 60 log: type: stdout format: pretty level: http EOT } } resource "kubernetes_deployment" "verdaccio" { metadata { name = "verdaccio" namespace = kubernetes_namespace.packages.metadata[0].name } spec { replicas = 1 selector { match_labels = { app = "verdaccio" } } template { metadata { labels = { app = "verdaccio" } } spec { security_context { fs_group = 101 } container { name = "verdaccio" image = "verdaccio/verdaccio:5" port { container_port = 4873 } # Override k8s service env injection which conflicts with Verdaccio's port detection env { name = "VERDACCIO_PORT" value = "4873" } volume_mount { name = "config" mount_path = "/verdaccio/conf/config.yaml" sub_path = "config.yaml" } volume_mount { name = "data" mount_path = "/verdaccio/storage" } resources { requests = { memory = "128Mi", cpu = "50m" } limits = { memory = "512Mi" } } } volume { name = "config" config_map { name = kubernetes_config_map.verdaccio_config.metadata[0].name } } volume { name = "data" persistent_volume_claim { claim_name = kubernetes_persistent_volume_claim.verdaccio_data.metadata[0].name } } } } } } resource "kubernetes_service" "verdaccio" { metadata { name = "verdaccio" namespace = kubernetes_namespace.packages.metadata[0].name } spec { selector = { app = "verdaccio" } port { port = 4873 target_port = 4873 } } } # devpi — PyPI proxy/cache resource "kubernetes_deployment" "devpi" { metadata { name = "devpi" namespace = kubernetes_namespace.packages.metadata[0].name } spec { replicas = 1 selector { match_labels = { app = "devpi" } } template { metadata { labels = { app = "devpi" } } spec { init_container { name = "devpi-init" image = "python:3.12-slim" command = ["sh", "-c", "pip install -q devpi-server devpi-web && if [ ! -f /data/.serverversion ]; then devpi-init --serverdir /data; fi && chmod 600 /data/.secret 2>/dev/null || true"] volume_mount { name = "data" mount_path = "/data" } } container { name = "devpi" image = "python:3.12-slim" command = ["sh", "-c", "pip install -q devpi-server devpi-web && exec devpi-server --serverdir /data --host 0.0.0.0 --port 3141 --outside-url https://pypi.neuralplatform.ai"] port { container_port = 3141 } volume_mount { name = "data" mount_path = "/data" } resources { requests = { memory = "512Mi", cpu = "100m" } limits = { memory = "2Gi" } } } volume { name = "data" persistent_volume_claim { claim_name = kubernetes_persistent_volume_claim.devpi_data.metadata[0].name } } } } } } resource "kubernetes_service" "devpi" { metadata { name = "devpi" namespace = kubernetes_namespace.packages.metadata[0].name } spec { selector = { app = "devpi" } port { port = 3141 target_port = 3141 } } }