diff --git a/homelab/conduit.nix b/homelab/conduit.nix new file mode 100644 index 0000000..49a871e --- /dev/null +++ b/homelab/conduit.nix @@ -0,0 +1,97 @@ +let + appName = "conduwuit"; + conduwuit-Image = "git.gmem.ca/arch/conduwuit:latest"; +in +{ ... }: { + kubernetes.resources.services.conduwuit = { + spec = { + selector.app = appName; + ports.http = { + port = 6167; + targetPort = 6167; + }; + }; + }; + kubernetes.resources.statefulSets.conduwuit.spec = { + selector.matchLabels.app = appName; + serviceName = appName; + template = { + metadata.labels.app = appName; + spec = { + volumes = { + config.configMap.name = appName; + }; + containers = { + conduwuit = { + image = conduwuit-Image; + imagePullPolicy = "Always"; + ports.http.containerPort = 6167; + volumeMounts = [ + { name = "data"; mountPath = "/var/lib/matrix-conduit"; } + { name = "config"; mountPath = "/etc/matrix-conduit/conduit.toml"; + subPath = "conduit.toml"; } + ]; + env.CONDUIT_CONFIG.value = "/etc/matrix-conduit/conduit.toml"; + }; + }; + }; + }; + volumeClaimTemplates = [ + { metadata.name = "data"; + spec = { + storageClassName = "nfs-client"; + accessModes = [ "ReadWriteOnce" ]; + resources.requests.storage = "5Gi"; + }; + } + ]; + }; + kubernetes.resources.ingresses.conduwuit = { + metadata = { + name = appName; + annotations = { + "cert-manager.io/issuer" = "le-issuer"; + }; + }; + spec = { + tls = [ { hosts = [ "chat.gmem.ca" ]; secretName = "gmem-ca-wildcard"; } ]; + rules = [ + { + host = "chat.gmem.ca"; + http.paths = [ + { path = "/"; pathType = "Prefix"; + backend.service = { + name = appName; + port.name = "http"; }; + } + ]; + } + ]; + }; + }; + kubernetes.resources.configMaps.conduwuit = { + metadata = { + name = appName; + annotations = { + "cert-manager.io/issuer" = "le-issuer"; + }; + }; + data."conduit.toml" = + '' + [global] + # The Conduit server needs all /_matrix/ requests to be reachable at + # https://your.server.name/ on port 443 (client-server) and 8448 (federation). + server_name = "gmem.ca" + + # This is the only directory where Conduit will save its data + database_path = "/var/lib/matrix-conduit/" + database_backend = "rocksdb" + port = 6167 + max_request_size = 20_000_000 # in bytes + allow_federation = true + allow_check_for_updates = false + trusted_servers = ["matrix.org"] + address = "0.0.0.0" + ''; + }; +} diff --git a/homelab/irc.nix b/homelab/irc.nix new file mode 100644 index 0000000..661ddd9 --- /dev/null +++ b/homelab/irc.nix @@ -0,0 +1,123 @@ +let + appName = "soju"; + sojuImage = "git.gmem.ca/arch/soju:latest"; + gamjaImage = "git.gmem.ca/arch/gamja:latest"; +in +{ + kubernetes.resources.services.soju = { + spec = { + type = "NodePort"; + selector.app = appName; + ports.tls = { + port = 6697; + targetPort = 6697; + }; + }; + }; + kubernetes.resources.services.soju-ws = { + spec = { + selector.app = appName; + ports.ws = { + port = 80; + targetPort = 80; + }; + }; + }; + kubernetes.resources.services.gamja = { + spec = { + selector.app = "gamja"; + ports.http = { + port = 80; + targetPort = 80; + }; + }; + }; + kubernetes.resources.deployments.soju.spec = { + selector.matchLabels.app = appName; + template = { + metadata.labels.app = appName; + spec = { + volumes = { + config.configMap.name = "soju"; + ssl.secret.secretName = "gmem-ca-wildcard"; + }; + containers = { + soju = { + image = sojuImage; + imagePullPolicy = "Always"; + volumeMounts = [ { name = "config"; mountPath = "/etc/soju/config"; subPath = "config"; } + { name = "ssl"; mountPath = "/ssl"; } ]; + ports.tls.containerPort = 6697; + ports.ws.containerPort = 80; + + env.PGHOST.valueFrom.secretKeyRef = { + name = "hippo-pguser-soju"; + key = "host"; + }; + env.PGPASSWORD.valueFrom.secretKeyRef = { + name = "hippo-pguser-soju"; + key = "password"; + }; + env.PGUSER.valueFrom.secretKeyRef = { + name = "hippo-pguser-soju"; + key = "user"; + }; + env.PGDATABASE.valueFrom.secretKeyRef = { + name = "hippo-pguser-soju"; + key = "dbname"; + }; + }; + }; + }; + }; + }; + kubernetes.resources.deployments.gamja.spec = { + selector.matchLabels.app = "gamja"; + template = { + metadata.labels.app = "gamja"; + spec = { + containers = { + gamja = { + image = gamjaImage; + imagePullPolicy = "Always"; + ports.http.containerPort = 80; + }; + }; + }; + }; + }; + + kubernetes.resources.ingresses.irc = { + metadata.annotations = { + "cert-manager.io/issuer" = "le-issuer"; + }; + spec = { + tls = [ { hosts = [ "irc.gmem.ca" ]; secretName = "gmem-ca-wildcard"; } ]; + rules = [ { host = "irc.gmem.ca"; http.paths = [ + { path = "/"; pathType = "Prefix"; + backend.service = { + name = "gamja"; + port.number = 80; + }; + } + { path = "/socket"; pathType = "Prefix"; + backend.service = { + name = "soju-ws"; + port.number = 80; + }; + } + ];}]; + }; + }; + + kubernetes.resources.configMaps.soju.data.config = '' +listen ircs:// +listen unix+admin:///app/admin +listen ws+insecure:// +hostname irc.gmem.ca +title irc.gmem.ca +db postgres "dbname=soju" +message-store db +tls /ssl/tls.crt /ssl/tls.key + ''; +} diff --git a/homelab/netboot.nix b/homelab/netboot.nix new file mode 100644 index 0000000..eec9a70 --- /dev/null +++ b/homelab/netboot.nix @@ -0,0 +1,97 @@ +let + appName = "netbootxyz"; + netbootxyzImage = "ghcr.io/netbootxyz/netbootxyz"; +in +{ + kubernetes.resources.services.netbootxyz = { + spec = { + selector.app = appName; + ports.http = { + port = 80; + targetPort = 80; + }; + ports.interface = { + port = 3000; + targetPort = 3000; + }; + }; + }; + kubernetes.resources.services.netbootxyz-tftp = { + spec = { + externalTrafficPolicy = "Local"; + sessionAffinity = "None"; + type = "NodePort"; + selector.app = appName; + ports.tftp = { + port = 69; + protocol = "UDP"; + targetPort = 69; + }; + }; + }; + kubernetes.resources.deployments.netbootxyz.spec = { + selector.matchLabels.app = appName; + template = { + metadata.labels.app = appName; + spec = { + volumes = [ + { name = "config"; persistentVolumeClaim.claimName = "netbootxyz-config"; } + { name = "assets"; persistentVolumeClaim.claimName = "netbootxyz-assets"; } + ]; + containers = { + netbootxyz = { + image = netbootxyzImage; + imagePullPolicy = "Always"; + volumeMounts = [ + { mountPath = "/config"; name = "config"; } + { mountPath = "/assets"; name = "assets"; } + ]; + env.SUBFOLDER.value = "/ui/"; + ports.http.containerPort = 80; + ports.interface.containerPort = 3000; + ports.tftp = { + containerPort = 69; + protocol = "UDP"; + }; + }; + }; + }; + }; + }; + + kubernetes.resources.persistentVolumeClaims.netbootxyz-config.spec = { + resources.requests.storage = "1Gi"; + volumeMode = "Filesystem"; + accessModes = [ "ReadWriteMany" ]; + }; + kubernetes.resources.persistentVolumeClaims.netbootxyz-assets.spec = { + resources.requests.storage = "10Gi"; + volumeMode = "Filesystem"; + accessModes = [ "ReadWriteMany" ]; + }; + + kubernetes.resources.ingresses.netbootxyz = { + metadata.annotations = { + "cert-manager.io/issuer" = "le-issuer"; + "nginx.ingress.kubernetes.io/ssl-redirect" = "false"; + }; + spec = { + tls = [ { hosts = [ "netboot.gmem.ca" ]; secretName = "gmem-ca-wildcard"; } ]; + rules = [ { host = "netboot.gmem.ca"; http.paths = [ + { path = "/ui"; pathType = "Prefix"; + backend.service = { + name = "netbootxyz"; + port.number = 3000; + }; + } + { path = "/"; pathType = "Prefix"; + backend.service = { + name = "netbootxyz"; + port.number = 80; + }; + } + ];}]; + }; + }; + +} diff --git a/homelab/piped.nix b/homelab/piped.nix new file mode 100644 index 0000000..4c013d7 --- /dev/null +++ b/homelab/piped.nix @@ -0,0 +1,69 @@ +{ lib, config, kubenix, ... }: { + kubernetes.helm.releases.piped = { + namespace = "default"; + chart = kubenix.lib.helm.fetch { + repo = "https://helm.piped.video"; + chart = "piped"; + version = "5.0.0"; + sha256 = "wfw0e37q52VW+bUMBmXILwUM0F1O1cH7Jk+6tmLAcS8="; + }; + values = { + postgresql.enabled = false; + backend.config = { + FRONTEND_URL = "https://piped.gmem.ca"; + API_URL = "https://pipedapi.gmem.ca"; + PROXY_PART = "https://ytproxy.gmem.ca"; + database.connection_url = "jdbc:postgresql://hippo-primary.default.svc:5432/piped"; + database.secret = { + name = "hippo-pguser-piped"; + username = "user"; + password = "password"; + }; + }; + fontend.env.BACKEND_HOSTNAME= "pipedapi.gmem.ca"; + ingress = { + main = { + tls = [ { hosts = [ "piped.gmem.ca" ]; secretName = "gmem-ca-wildcard"; } ]; + hosts = [ + { host = "piped.gmem.ca"; paths = [ { path = "/"; } ]; } + ]; + }; + backend = { + tls = [ { hosts = [ "pipedapi.gmem.ca" ]; secretName = "gmem-ca-wildcard"; } ]; + hosts = [ + { host = "pipedapi.gmem.ca"; paths = [ { path = "/"; } ]; } + ]; + }; + ytproxy = { + tls = [ { hosts = [ "ytproxy.gmem.ca" ]; secretName = "gmem-ca-wildcard"; } ]; + hosts = [ + { host = "ytproxy.gmem.ca"; paths = [ { path = "/"; } ]; } + ]; + }; + }; + }; + }; + + kubernetes.resources.cronJobs.piped-refresh.spec = { + schedule = "*/5 * * * *"; + jobTemplate.spec.template.spec = { + restartPolicy = "Never"; + containers.refresh-subscriptions = { + image = "alpine:3.15"; + envFrom = [ { secretRef.name = "hippo-pguser-piped"; } ]; + command = [ + "/bin/ash" + "-c" + '' + apk --no-cache add postgresql-client curl && + export PGPASSWORD=$password && + export subs=$(psql -U piped -h hippo-primary.default.svc -qtAX -c 'select id from public.pubsub;') && + while IFS= read -r line; do + curl -k "https://pipedapi.gmem.ca/channel/$line" > /dev/null + done < <(printf '%s' "$subs") + '' + ]; + }; + }; + }; +} diff --git a/homelab/postgres-cluster.yml b/homelab/postgres-cluster.yml index fa88e02..a75b6b9 100644 --- a/homelab/postgres-cluster.yml +++ b/homelab/postgres-cluster.yml @@ -3,7 +3,7 @@ kind: PostgresCluster metadata: name: hippo spec: - image: git.gmem.ca/arch/custom-postgres@sha256:e8e4b522b6912cb56924695bf6cf233d6162b3eafecf4d7abd050ebbfe83b0ac + image: git.gmem.ca/arch/custom-postgres@sha256:539194fc6c290445477b229bb7b792785b67619894bcfd7483e5bdb62eaa0658 postgresVersion: 15 databaseInitSQL: key: init.sql @@ -24,12 +24,6 @@ spec: shared_preload_libraries: vectors backups: pgbackrest: - restore: - enabled: true - repoName: repo1 - options: - - --type=time - - --target="2023-12-16 00:00:00-00" manual: repoName: repo1 options: @@ -65,6 +59,12 @@ spec: - name: pterodactyl databases: - pterodactyl + - name: piped + databases: + - piped + - name: soju + databases: + - soju --- apiVersion: v1 kind: ConfigMap @@ -79,6 +79,10 @@ data: CREATE EXTENSION vectors; \c pterodactyl GRANT CREATE ON SCHEMA public TO "pterodactyl"; + \c piped + GRANT CREATE ON SCHEMA public TO "piped"; + \c soju + GRANT CREATE ON SCHEMA public TO "soju"; --- apiVersion: monitoring.coreos.com/v1 kind: PodMonitor diff --git a/homelab/pterodactyl.nix b/homelab/pterodactyl.nix index 1f4c8f1..7dca726 100644 --- a/homelab/pterodactyl.nix +++ b/homelab/pterodactyl.nix @@ -18,22 +18,15 @@ in template = { metadata.labels.app = appName; spec = { - volumes = { - secret.secret.secretName = "pterodactyl"; - }; containers = { pterodactyl-panel = { image = pterodactyl-panel-Image; imagePullPolicy = "Always"; ports.http.containerPort = 8080; - lifecycle.postStart.exec.command = [ - "/bin/sh" "-c" - "cp /var/secret/pterodactyl.env /var/www/pterodactyl/.env" - ]; volumeMounts = [ - { name = "secret"; mountPath = "/var/secret"; } { name = "data"; mountPath = "/var/www/pterodactyl/storage/app"; } ]; + envFrom = [ { secretRef.name = "pterodactyl"; } ]; }; }; };