diff --git a/helm/values/nginx-internal.values.yaml b/helm/values/nginx-internal.values.yaml index fb74f43..a618c67 100644 --- a/helm/values/nginx-internal.values.yaml +++ b/helm/values/nginx-internal.values.yaml @@ -1,4 +1,7 @@ controller: + replicaCount: 3 + nodeSelector: + nodepool: worker ingressClassResource: name: nginx-internal enabled: true @@ -9,8 +12,31 @@ controller: service: annotations: external-dns.alpha.kubernetes.io/hostname: "dogar.dev" + extraVolumes: + - name: nix-cache + persistentVolumeClaim: + claimName: nix-cache + extraVolumeMounts: + - name: nix-cache + mountPath: /var/cache/nginx/nix + podSecurityContext: + fsGroup: 101 + config: + proxy-buffering: "on" + proxy-ssl-server-name: "true" + http-snippet: | + # Persistent on-disk cache; lives on the PVC + proxy_cache_path /var/cache/nginx/nix levels=1:2 keys_zone=cachecache:32m max_size=120g inactive=365d use_temp_path=off; + + # Only advertise cacheability for 200/302 + map $status $cache_header { + 200 "public"; + 302 "public"; + default "no-cache"; + } tcp: 22: "homelab/gitea-ssh:22" 25565: "minecraft/monifactory-server:25565" 25566: "minecraft/gtnh-server:25565" 25567: "minecraft/tfg-server:25565" + 25568: "minecraft/atm10-server:25565" diff --git a/nginx/index.ts b/nginx/index.ts index d9e6a2a..31bd78f 100644 --- a/nginx/index.ts +++ b/nginx/index.ts @@ -3,6 +3,8 @@ import { HelmProvider } from "@cdktf/provider-helm/lib/provider"; import { Release } from "@cdktf/provider-helm/lib/release"; import { Construct } from "constructs"; +import { NixCache } from "./nix-cache"; + type NginxOptions = { provider: HelmProvider; name: string; @@ -24,5 +26,11 @@ export class Nginx extends Construct { }), ], }); + + new NixCache(this, "nix-cache", { + namespace: options.namespace, + host: "nix.dogar.dev", + ingressClassName: "nginx-internal", + }); } } diff --git a/nginx/nix-cache.ts b/nginx/nix-cache.ts new file mode 100644 index 0000000..2054d1d --- /dev/null +++ b/nginx/nix-cache.ts @@ -0,0 +1,105 @@ +import { Construct } from "constructs"; +import { ServiceV1 } from "@cdktf/provider-kubernetes/lib/service-v1"; +import { IngressV1 } from "@cdktf/provider-kubernetes/lib/ingress-v1"; +import { PersistentVolumeClaimV1 } from "@cdktf/provider-kubernetes/lib/persistent-volume-claim-v1"; + +export interface NixCacheProps { + namespace: string; + host: string; + ingressClassName?: string; + externalName?: string; +} + +export class NixCache extends Construct { + constructor(scope: Construct, id: string, props: NixCacheProps) { + super(scope, id); + + const { + namespace, + host, + ingressClassName: ingressClass = "nginx-internal", + externalName: upstreamHost = "cache.nixos.org", + } = props; + + // 1) ExternalName Service -> cache.nixos.org + new ServiceV1(this, "nixcache-upstream-svc", { + metadata: { + name: "nixcache-upstream", + namespace, + }, + spec: { + type: "ExternalName", + externalName: upstreamHost, + }, + }); + + // 2) Ingress that targets the ExternalName Service over HTTPS:443 + new IngressV1(this, "nixcache-ingress", { + metadata: { + name: "nix-cache", + namespace, + annotations: { + // Use the cache zone defined in controller.config.http-snippet + "nginx.ingress.kubernetes.io/proxy-cache": "cachecache", + "nginx.ingress.kubernetes.io/proxy-cache-valid": "200 302 60d", + "nginx.ingress.kubernetes.io/proxy-cache-lock": "true", + "nginx.ingress.kubernetes.io/proxy-buffering": "on", + + // Upstream is HTTPS with SNI and a fixed Host header + "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", + "nginx.ingress.kubernetes.io/proxy-ssl-server-name": "true", + "nginx.ingress.kubernetes.io/upstream-vhost": upstreamHost, + + // Use cert-manager to provision TLS certs via Cloudflare + "cert-manager.io/cluster-issuer": "cloudflare-issuer", + "cert-manager.io/acme-challenge-type": "dns01", + "cert-manager.io/private-key-size": "4096", + }, + }, + spec: { + ingressClassName: ingressClass, + rule: [ + { + host, + http: { + path: [ + { + path: "/", + pathType: "Prefix", + backend: { + service: { + name: "nixcache-upstream", + port: { number: 443 }, + }, + }, + }, + ], + }, + }, + ], + tls: [ + { + hosts: [host], + secretName: "nix-cache-tls", + }, + ], + }, + }); + + // 3) PersistentVolumeClaim for caching + new PersistentVolumeClaimV1(this, "nix-cache-pvc", { + metadata: { + name: "nix-cache", + namespace, + }, + spec: { + accessModes: ["ReadWriteMany"], + resources: { + requests: { + storage: "128Gi", + }, + }, + }, + }); + } +}