{ lib, config, globals, ... }: { options.nextcloud.enable = lib.mkEnableOption "nextcloud"; config = lib.mkIf config.nextcloud.enable { kubernetes.resources = { secrets.database.stringData.databasePassword = "ref+sops://secrets.yml#/nextcloud/databasePassword"; deployments = { server.spec = { selector.matchLabels = { app = "nextcloud"; component = "server"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "nextcloud"; component = "server"; }; spec = { volumes.data.persistentVolumeClaim.claimName = "data"; containers.nextcloud = { image = globals.images.nextcloud; ports.web.containerPort = 80; env = { POSTGRES_USER.value = "nextcloud"; POSTGRES_DB.value = "nextcloud"; POSTGRES_HOST.value = "lewis.dmz"; POSTGRES_PASSWORD.valueFrom.secretKeyRef = { name = "database"; key = "databasePassword"; }; }; volumeMounts = [ { name = "data"; mountPath = "/var/www/html"; } ]; }; securityContext = { fsGroup = 33; fsGroupChangePolicy = "OnRootMismatch"; }; affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution = [ { weight = 1; preference.matchExpressions = [ { key = "storageType"; operator = "In"; values = ["fast"]; } ]; } ]; }; }; }; database.spec = { selector.matchLabels = { app = "nextcloud"; component = "database"; }; strategy = { type = "RollingUpdate"; rollingUpdate = { maxSurge = 0; maxUnavailable = 1; }; }; template = { metadata.labels = { app = "nextcloud"; component = "database"; }; spec = { containers.postgres = { image = globals.images.postgres15; imagePullPolicy = "IfNotPresent"; ports.postgres.containerPort = 5432; env = { POSTGRES_DB.value = "nextcloud"; POSTGRES_USER.value = "nextcloud"; PGDATA.value = "/pgdata/data"; POSTGRES_PASSWORD.valueFrom.secretKeyRef = { name = "database"; key = "databasePassword"; }; }; volumeMounts = [ { name = "database"; mountPath = "/pgdata"; } ]; }; volumes.database.persistentVolumeClaim.claimName = "database"; }; }; }; }; services = { server.spec = { type = "LoadBalancer"; loadBalancerIP = globals.nextcloudIPv4; selector = { app = "nextcloud"; component = "server"; }; ports.web = { port = 80; targetPort = "web"; }; }; database.spec = { selector = { app = "nextcloud"; component = "database"; }; ports.postgres = { port = 5432; targetPort = "postgres"; }; }; }; }; lab = { tailscaleIngresses.tailscale = { host = "nextcloud"; service.name = "server"; }; longhorn.persistentVolumeClaim = { data = { volumeName = "nextcloud"; storage = "50Gi"; }; database = { volumeName = "nextcloud-db"; storage = "400Mi"; }; }; }; }; }