Compare commits

...

12 Commits

27 changed files with 856 additions and 502 deletions

43
flake.lock generated
View File

@@ -18,49 +18,13 @@
"type": "github"
}
},
"flake-utils_2": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"krew2nix": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1716272275,
"narHash": "sha256-JWDyPhAJp263EVVsGrKwrJU+xdDReHsDmSe7A190/Cg=",
"owner": "eigengrau",
"repo": "krew2nix",
"rev": "0c1fecaab044dba1249c5d09366891ec467b4ad2",
"type": "github"
},
"original": {
"owner": "eigengrau",
"repo": "krew2nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1761236834,
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
"lastModified": 1762943920,
"narHash": "sha256-ITeH8GBpQTw9457ICZBddQEBjlXMmilML067q0e6vqY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1",
"rev": "91c9a64ce2a84e648d0cf9671274bb9c2fb9ba60",
"type": "github"
},
"original": {
@@ -73,7 +37,6 @@
"root": {
"inputs": {
"flake-utils": "flake-utils",
"krew2nix": "krew2nix",
"nixpkgs": "nixpkgs"
}
},

View File

@@ -4,14 +4,9 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
krew2nix = {
url = "github:eigengrau/krew2nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, flake-utils, krew2nix, ... }: flake-utils.lib.eachDefaultSystem (system:
outputs = { nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system:
let
lib = nixpkgs.lib;
@@ -24,16 +19,12 @@
];
};
};
kubectl = krew2nix.packages.${system}.kubectl;
in {
# Define the devShell for the current system
devShell = pkgs.mkShell {
buildInputs = with pkgs; [
kubernetes-helm
(kubectl.withKrewPlugins (plugins: with plugins; [
cnpg
]))
kubectl-cnpg
nil
terraform
tflint

View File

@@ -1,5 +1,5 @@
global:
storageClass: longhorn-crypto
storageClass: longhorn
image:
rootless: false
service:

View File

@@ -1,13 +1,20 @@
global:
nodeSelector:
nodepool: worker
defaultSettings:
defaultReplicaCount: 3
storageOverProvisioningPercentage: 100
defaultReplicaCount: "3"
storageOverProvisioningPercentage: "100"
backupCompressionMethod: "gzip"
replicaSoftAntiAffinity: "true"
concurrentReplicaRebuildPerNodeLimit: "1"
replicaReplenishmentWaitInterval: "600"
disableSchdedulingOnCordonedNode: "true"
defaultBackupStore:
backupTarget: "s3://homelab@auto/longhorn"
backupTarget: "s3://longhorn-backups@auto"
backupTargetCredentialSecret: cloudflare-token
metrics:
serviceMonitor:
enabled: true
enabled: false
ingress:
enabled: true
ingressClassName: nginx-internal

View File

@@ -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"

View File

@@ -1,6 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
commonLabels:
app.kubernetes.io/managed-by: Kustomize
metadata:
labels:
app.kubernetes.io/managed-by: Kustomize
resources:
- ./metallb/pool.yaml

View File

@@ -3,7 +3,7 @@ apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool
namespace: homelab
namespace: metallb-system
spec:
addresses:
- 192.168.18.192/26
@@ -12,7 +12,7 @@ apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: pool
namespace: homelab
namespace: metallb-system
spec:
ipAddressPools:
- pool

View File

@@ -11,7 +11,6 @@ type LonghornOptions = {
helm: HelmProvider;
};
name: string;
namespace: string;
};
export class Longhorn extends Construct {
@@ -19,15 +18,15 @@ export class Longhorn extends Construct {
super(scope, id);
const { helm, kubernetes } = options.providers;
const namespace = "longhorn-system";
new Release(this, id, {
name: options.name,
namespace: options.namespace,
namespace,
provider: helm,
repository: "https://charts.longhorn.io",
chart: "longhorn",
createNamespace: true,
upgradeInstall: true,
values: [
fs.readFileSync("helm/values/longhorn.values.yaml", {
encoding: "utf8",
@@ -38,44 +37,19 @@ export class Longhorn extends Construct {
new Manifest(this, "recurring-backup-job", {
provider: kubernetes,
manifest: {
apiVersion: "longhorn.io/v1beta1",
apiVersion: "longhorn.io/v1beta2",
kind: "RecurringJob",
metadata: {
name: "daily-backup",
namespace: options.namespace,
namespace,
},
spec: {
cron: "0 0 * * *",
task: "backup",
retain: 30,
groups: ["default"],
retain: 7,
concurrency: 3,
},
},
});
new Manifest(this, "longhorn-crypto-storage-class", {
provider: kubernetes,
manifest: {
kind: "StorageClass",
apiVersion: "storage.k8s.io/v1",
metadata: {
name: "longhorn-crypto",
},
provisioner: "driver.longhorn.io",
allowVolumeExpansion: true,
parameters: {
numberOfReplicas: "3",
staleReplicaTimeout: "2880", // 48 hours in minutes
encrypted: "true",
"csi.storage.k8s.io/provisioner-secret-name": "longhorn-encryption",
"csi.storage.k8s.io/provisioner-secret-namespace": options.namespace,
"csi.storage.k8s.io/node-publish-secret-name": "longhorn-encryption",
"csi.storage.k8s.io/node-publish-secret-namespace": options.namespace,
"csi.storage.k8s.io/node-stage-secret-name": "longhorn-encryption",
"csi.storage.k8s.io/node-stage-secret-namespace": options.namespace,
},
},
});
}
}

38
main.ts
View File

@@ -1,9 +1,10 @@
import * as dotenv from "dotenv";
import { cleanEnv, str } from "envalid";
import { Construct } from "constructs";
import { App, TerraformStack, S3Backend } from "cdktf";
import { App, TerraformStack, LocalBackend } from "cdktf";
import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
import { NamespaceV1 } from "@cdktf/provider-kubernetes/lib/namespace-v1";
import { GiteaServer } from "./gitea";
import { OnePassword } from "./1password";
@@ -12,7 +13,6 @@ import { Longhorn } from "./longhorn";
import { AuthentikServer } from "./authentik";
import { ValkeyCluster } from "./valkey";
import { CertManager } from "./cert-manager";
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
import { Nginx } from "./nginx";
import { Prometheus } from "./prometheus";
import { MetalLB } from "./metallb";
@@ -45,15 +45,10 @@ class Homelab extends TerraformStack {
const namespace = "homelab";
const ns = new Manifest(this, "namespace", {
new NamespaceV1(this, "namespace", {
provider: kubernetes,
manifest: {
kind: "Namespace",
apiVersion: "v1",
metadata: {
name: namespace,
},
spec: {},
metadata: {
name: namespace,
},
});
@@ -65,12 +60,10 @@ class Homelab extends TerraformStack {
},
});
longhorn.node.addDependency(ns);
new MetalLB(this, "metallb", {
provider: helm,
name: "metallb",
namespace,
namespace: "metallb-system",
});
new OnePassword(this, "one-password", {
@@ -121,7 +114,6 @@ class Homelab extends TerraformStack {
kubernetes,
helm,
},
storageClass: "longhorn-crypto",
users: ["shahab", "budget-tracker", "authentik", "gitea"],
primaryUser: "shahab",
initSecretName: "postgres-password",
@@ -156,21 +148,9 @@ class Homelab extends TerraformStack {
const app = new App();
const stack = new Homelab(app, "homelab");
new S3Backend(stack, {
encrypt: true,
bucket: env.BUCKET,
key: "terraform.tfstate",
region: "auto",
skipCredentialsValidation: true,
skipMetadataApiCheck: true,
skipRegionValidation: true,
skipRequestingAccountId: true,
skipS3Checksum: true,
accessKey: env.R2_ACCESS_KEY_ID,
secretKey: env.R2_SECRET_ACCESS_KEY,
endpoints: {
s3: `${r2Endpoint}/${env.BUCKET}`,
},
new LocalBackend(stack, {
path: "terraform.tfstate",
workspaceDir: ".",
});
app.synth();

231
media/deployment.yaml Normal file
View File

@@ -0,0 +1,231 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
nodeSelector:
kubernetes.io/hostname: aamil-3
containers:
- name: server
image: jellyfin/jellyfin:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8096
name: http
env:
- name: TZ
value: "Asia/Karachi"
volumeMounts:
- name: config
mountPath: /config
- name: cache
mountPath: /cache
- name: media
mountPath: /media
volumes:
- name: config
persistentVolumeClaim:
claimName: jellyfin-config
- name: cache
emptyDir: {}
- name: media
persistentVolumeClaim:
claimName: media
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: sonarr
template:
metadata:
labels:
app: sonarr
spec:
nodeSelector:
kubernetes.io/hostname: aamil-3
containers:
- name: sonarr
image: lscr.io/linuxserver/sonarr:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8989
name: http
env:
- name: TZ
value: "Asia/Karachi"
- name: PUID
value: "1000"
- name: PGID
value: "1000"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media
- name: downloads
mountPath: /downloads
volumes:
- name: config
persistentVolumeClaim:
claimName: sonarr-config
- name: media
persistentVolumeClaim:
claimName: media
- name: downloads
persistentVolumeClaim:
claimName: downloads
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: qbittorrent
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: qbittorrent
template:
metadata:
labels:
app: qbittorrent
spec:
nodeSelector:
kubernetes.io/hostname: aamil-3
containers:
- name: qbittorrent
image: lscr.io/linuxserver/qbittorrent:latest
ports:
- containerPort: 8080 # web UI
name: http
- containerPort: 6881
name: bt
- containerPort: 6881
protocol: UDP
name: bt-udp
env:
- name: TZ
value: "Asia/Karachi"
- name: PUID
value: "1000"
- name: PGID
value: "1000"
- name: WEBUI_PORT
value: "8080"
volumeMounts:
- name: config
mountPath: /config
- name: downloads
mountPath: /downloads
volumes:
- name: config
persistentVolumeClaim:
claimName: qbittorrent-config
- name: downloads
persistentVolumeClaim:
claimName: downloads
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prowlarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: prowlarr
template:
metadata:
labels:
app: prowlarr
spec:
nodeSelector:
nodepool: worker
containers:
- name: prowlarr
image: lscr.io/linuxserver/prowlarr:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9696
name: http
env:
- name: TZ
value: "Asia/Karachi"
- name: PUID
value: "1000"
- name: PGID
value: "1000"
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
persistentVolumeClaim:
claimName: prowlarr-config
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: radarr
namespace: media
spec:
replicas: 1
selector:
matchLabels:
app: radarr
template:
metadata:
labels:
app: radarr
spec:
nodeSelector:
kubernetes.io/hostname: aamil-3
containers:
- name: radarr
image: lscr.io/linuxserver/radarr:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 7878
name: http
env:
- name: TZ
value: "Asia/Karachi"
- name: PUID
value: "1000"
- name: PGID
value: "1000"
volumeMounts:
- name: config
mountPath: /config
- name: media
mountPath: /media
- name: downloads
mountPath: /downloads
volumes:
- name: config
persistentVolumeClaim:
claimName: radarr-config
- name: media
persistentVolumeClaim:
claimName: media
- name: downloads
persistentVolumeClaim:
claimName: downloads

76
media/ingress.yaml Normal file
View File

@@ -0,0 +1,76 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: server
namespace: media
annotations:
# cert-manager (Cloudflare DNS-01)
cert-manager.io/cluster-issuer: cloudflare-issuer
cert-manager.io/acme-challenge-type: dns01
cert-manager.io/private-key-size: "4096"
# Jellyfin / streaming friendly nginx settings
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
nginx.ingress.kubernetes.io/use-proxy-protocol: "false"
nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
spec:
ingressClassName: nginx-internal
tls:
- hosts:
- media.dogar.dev
secretName: media-tls
- hosts:
- sonarr.dogar.dev
secretName: sonarr-tls
- hosts:
- radarr.dogar.dev
secretName: radarr-tls
- hosts:
- torrent.dogar.dev
secretName: torrent-tls
rules:
- host: media.dogar.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: server
port:
number: 80
- host: sonarr.dogar.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sonarr
port:
number: 80
- host: radarr.dogar.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: radarr
port:
number: 80
- host: torrent.dogar.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: qbittorrent
port:
number: 80

5
media/namespace.yaml Normal file
View File

@@ -0,0 +1,5 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: media

106
media/pvc.yaml Normal file
View File

@@ -0,0 +1,106 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jellyfin-config
namespace: media
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job.longhorn.io/backup: "enabled"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: longhorn
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: media
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 512Gi
storageClassName: longhorn
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sonarr-config
namespace: media
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job.longhorn.io/backup: "enabled"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 512Mi
storageClassName: longhorn
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: qbittorrent-config
namespace: media
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job.longhorn.io/backup: "enabled"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 512Mi
storageClassName: longhorn
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: downloads
namespace: media
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 450Gi
storageClassName: longhorn
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prowlarr-config
namespace: media
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job.longhorn.io/backup: "enabled"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 512Mi
storageClassName: longhorn
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: radarr-config
namespace: media
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job.longhorn.io/backup: "enabled"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 512Mi
storageClassName: longhorn

69
media/service.yaml Normal file
View File

@@ -0,0 +1,69 @@
---
apiVersion: v1
kind: Service
metadata:
name: server
namespace: media
spec:
selector:
app: server
ports:
- name: http
port: 80
targetPort: 8096
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: sonarr
namespace: media
spec:
selector:
app: sonarr
ports:
- name: http
port: 80
targetPort: 8989
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: qbittorrent
namespace: media
spec:
selector:
app: qbittorrent
ports:
- name: http
port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: prowlarr
namespace: media
spec:
selector:
app: prowlarr
ports:
- name: http
port: 80
targetPort: 9696
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: radarr
namespace: media
spec:
selector:
app: radarr
ports:
- name: http
port: 80
targetPort: 7878

View File

@@ -5,7 +5,6 @@ metadata:
name: monifactory-data
namespace: minecraft
spec:
storageClassName: longhorn-crypto
accessModes:
- ReadWriteMany
resources:
@@ -18,7 +17,6 @@ metadata:
name: gtnh-data
namespace: minecraft
spec:
storageClassName: longhorn-crypto
accessModes:
- ReadWriteMany
resources:
@@ -31,7 +29,21 @@ metadata:
name: tfg-data
namespace: minecraft
spec:
storageClassName: longhorn-crypto
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: atm10-data
namespace: minecraft
labels:
recurring-job.longhorn.io/source: "enabled"
recurring-job.longhorn.io/backup: "enabled"
spec:
accessModes:
- ReadWriteMany
resources:

View File

@@ -43,3 +43,18 @@ spec:
port: 25565
selector:
app: tfg-server
---
apiVersion: v1
kind: Service
metadata:
name: atm10-server
namespace: minecraft
labels:
app: atm10-server
spec:
type: ClusterIP
ports:
- name: atm10
port: 25565
selector:
app: atm10-server

View File

@@ -5,6 +5,7 @@ metadata:
name: monifactory-server
namespace: minecraft
spec:
serviceName: monifactory-server
selector:
matchLabels:
app: monifactory-server
@@ -13,6 +14,8 @@ spec:
labels:
app: monifactory-server
spec:
nodeSelector:
nodepool: worker
containers:
- name: monifactory-server
image: itzg/minecraft-server:java17
@@ -37,7 +40,7 @@ spec:
- name: INIT_MEMORY
value: 4G
- name: MAX_MEMORY
value: 8G
value: 12G
- name: ALLOW_FLIGHT
value: "TRUE"
- name: ENABLE_ROLLING_LOGS
@@ -53,7 +56,7 @@ spec:
memory: "4Gi"
limits:
cpu: 8
memory: "8Gi"
memory: "12Gi"
volumeMounts:
- name: monifactory-data
mountPath: /data
@@ -68,6 +71,7 @@ metadata:
name: gtnh-server
namespace: minecraft
spec:
serviceName: gtnh-server
selector:
matchLabels:
app: gtnh-server
@@ -76,6 +80,8 @@ spec:
labels:
app: gtnh-server
spec:
nodeSelector:
nodepool: worker
containers:
- name: gtnh-server
image: itzg/minecraft-server:java25
@@ -97,7 +103,7 @@ spec:
- name: SKIP_GENERIC_PACK_UPDATE_CHECK
value: "true"
- name: MEMORY
value: 6G
value: 12G
- name: JVM_OPTS
value: "-Dfml.readTimeout=180 -Dfml.queryResult=confirm @java9args.txt"
- name: CUSTOM_JAR_EXEC
@@ -112,7 +118,7 @@ spec:
resources:
limits:
cpu: 8
memory: "8Gi"
memory: "12Gi"
volumeMounts:
- name: gtnh-data
mountPath: /data
@@ -127,6 +133,7 @@ metadata:
name: tfg-server
namespace: minecraft
spec:
serviceName: tfg-server
selector:
matchLabels:
app: tfg-server
@@ -135,6 +142,8 @@ spec:
labels:
app: tfg-server
spec:
nodeSelector:
nodepool: worker
containers:
- name: tfg-server
image: itzg/minecraft-server:java17
@@ -159,7 +168,7 @@ spec:
- name: INIT_MEMORY
value: 2G
- name: MAX_MEMORY
value: 8G
value: 12G
- name: ALLOW_FLIGHT
value: "TRUE"
- name: ENABLE_ROLLING_LOGS
@@ -175,7 +184,7 @@ spec:
memory: "2Gi"
limits:
cpu: 6
memory: "9Gi"
memory: "12Gi"
volumeMounts:
- name: tfg-data
mountPath: /data
@@ -183,3 +192,71 @@ spec:
- name: tfg-data
persistentVolumeClaim:
claimName: tfg-data
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: atm10-server
namespace: minecraft
spec:
serviceName: atm10-server
selector:
matchLabels:
app: atm10-server
template:
metadata:
labels:
app: atm10-server
spec:
nodeSelector:
nodepool: worker
containers:
- name: atm10-server
image: itzg/minecraft-server:java21
env:
- name: EULA
value: "TRUE"
- name: MODE
value: "survival"
- name: MODPACK_PLATFORM
value: "AUTO_CURSEFORGE"
- name: CF_API_KEY
valueFrom:
secretKeyRef:
name: curseforge
key: credential
- name: CF_PAGE_URL
value: "https://www.curseforge.com/minecraft/modpacks/all-the-mods-10/files/7121777"
- name: VERSION
value: "1.21.1"
- name: INIT_MEMORY
value: 2G
- name: MAX_MEMORY
value: 15G
- name: ALLOW_FLIGHT
value: "TRUE"
- name: ENABLE_ROLLING_LOGS
value: "TRUE"
- name: USE_MEOWICE_FLAGS
value: "TRUE"
- name: CF_OVERRIDES_EXCLUSIONS
value: |
# Not applicable for server side
shaderpacks/**
ports:
- name: minecraft
containerPort: 25565
resources:
requests:
cpu: 2
memory: "2Gi"
limits:
cpu: 6
memory: "16Gi"
volumeMounts:
- name: atm10-data
mountPath: /data
volumes:
- name: atm10-data
persistentVolumeClaim:
claimName: atm10-data

View File

@@ -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",
});
}
}

105
nginx/nix-cache.ts Normal file
View File

@@ -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",
},
},
},
});
}
}

View File

@@ -1,145 +0,0 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
{ pkgs, meta, ... }:
{
imports = [ ./hardware-configuration.nix ];
nix = {
settings = {
require-sigs = false;
experimental-features = [ "nix-command" "flakes" ];
};
};
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
networking.hostName = meta.hostname; # Define your hostname.
# Pick only one of the below networking options.
networking.networkmanager.enable = true;
networking.interfaces.enp1s0.ipv4.addresses = [
{
address = (
if meta.hostname == "homelab-0" then "192.168.18.10"
else if meta.hostname == "homelab-1" then "192.168.18.11"
else if meta.hostname == "homelab-2" then "192.168.18.12"
else throw "Unknown hostname"
);
prefixLength = 24;
}
];
networking.defaultGateway = "192.168.18.1";
networking.nameservers = [
"192.168.18.250"
"1.1.1.1"
];
# Set your time zone.
time.timeZone = "Asia/Karachi";
# Select internationalisation properties.
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "us";
};
# Fixes for longhorn
systemd.tmpfiles.rules = [
"L+ /usr/local/bin - - - - /run/current-system/sw/bin/"
];
virtualisation.docker.logDriver = "json-file";
services.k3s = {
enable = true;
role = "server";
tokenFile = /var/lib/rancher/k3s/server/token;
extraFlags = toString ([
"--write-kubeconfig-mode \"0644\""
"--cluster-init"
"--disable servicelb"
"--disable traefik"
"--disable local-storage"
] ++ (if meta.hostname == "homelab-0" then [] else [
"--server https://192.168.18.10:6443"
]));
clusterInit = (meta.hostname == "homelab-0");
};
services.openiscsi = {
enable = true;
name = "iqn.2016-04.com.open-iscsi:${meta.hostname}";
};
# Define a user account. Don't forget to set a password with passwd.
users.users.shahab = {
isNormalUser = true;
extraGroups = [ "wheel" ]; # Enable sudo for the user.
packages = with pkgs; [
tree
cloudflared
];
# Created using mkpasswd
hashedPassword = "$6$.ZlYnf2cZph4tCbM$E/JJUDirRV8MZrgX4Rh.Pi1q95tev1ZxcKjPA1I.uURv56qoWcC39MJWO9S2T5MlkPVbSLGiM8Ihfz9mERImo/";
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGD/V4jLpuk7uAovkbHFr6uulfBKZmsH+BqmXIR2aYD0"
];
};
security.sudo.extraRules = [
{
users = ["shahab"];
commands = [
{ command = "ALL"; options = ["NOPASSWD"]; }
];
}
];
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
neovim
k3s
cifs-utils
nfs-utils
git
];
# List services that you want to enable:
# Enable the OpenSSH daemon.
services.openssh.enable = true;
# Open ports in the firewall.
# networking.firewall.allowedTCPPorts = [ 80 ];
# networking.firewall.allowedUDPPorts = [ ... ];
# Or disable the firewall altogether.
networking.firewall.enable = false;
# Copy the NixOS configuration file and link it from the resulting system
# (/run/current-system/configuration.nix). This is useful in case you
# accidentally delete configuration.nix.
# system.copySystemConfiguration = true;
# This option defines the first version of NixOS you have installed on this particular machine,
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
#
# Most users should NEVER change this value after the initial install, for any reason,
# even if you've upgraded your system to a new NixOS release.
#
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
# so changing it will NOT upgrade your system.
#
# This value being lower than the current NixOS release does NOT mean your system is
# out of date, out of support, or vulnerable.
#
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
# and migrated your data accordingly.
#
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
system.stateVersion = "24.05"; # Did you read the comment?
}

View File

@@ -1,45 +0,0 @@
{
disko.devices = {
disk = {
vdb = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
priority = 1;
name = "ESP";
start = "1M";
end = "128M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
luks = {
size = "100%";
content = {
name = "crypted";
type = "luks";
passwordFile = "/tmp/secret.key";
settings = {
allowDiscards = true;
crypttabExtraOpts =
[ "fido2-device=auto" "token-timeout=10" ];
};
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
};
}

View File

@@ -1,48 +0,0 @@
{
"nodes": {
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1758287904,
"narHash": "sha256-IGmaEf3Do8o5Cwp1kXBN1wQmZwQN3NLfq5t4nHtVtcU=",
"owner": "nix-community",
"repo": "disko",
"rev": "67ff9807dd148e704baadbd4fd783b54282ca627",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1759994382,
"narHash": "sha256-wSK+3UkalDZRVHGCRikZ//CyZUJWDJkBDTQX1+G77Ow=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5da4a26309e796daa7ffca72df93dbe53b8164c7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"disko": "disko",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -1,37 +0,0 @@
{
description = "Homelab NixOS Flake";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
# Disko
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, disko, ... }: let
nodes = [
"homelab-0"
"homelab-1"
"homelab-2"
];
in {
nixosConfigurations = builtins.listToAttrs (map (name: {
name = name;
value = nixpkgs.lib.nixosSystem {
specialArgs = {
meta = { hostname = name; };
};
system = "x86_64-linux";
modules = [
# Modules
disko.nixosModules.disko
./hardware-configuration.nix
./disko-config.nix
./configuration.nix
];
};
}) nodes);
};
}

View File

@@ -1,24 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, modulesPath, ... }:
{
imports = [(modulesPath + "/installer/scan/not-detected.nix")];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault false;
networking.interfaces.enp1s0.useDHCP = lib.mkDefault false;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

54
package-lock.json generated
View File

@@ -75,9 +75,9 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"dev": true,
"license": "MIT"
},
@@ -121,13 +121,14 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "24.0.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz",
"integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==",
"version": "24.9.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
"integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.8.0"
"undici-types": "~7.16.0"
}
},
"node_modules/acorn": {
@@ -173,6 +174,7 @@
"semver"
],
"license": "MPL-2.0",
"peer": true,
"dependencies": {
"archiver": "7.0.1",
"json-stable-stringify": "1.2.1",
@@ -1250,7 +1252,8 @@
"version": "10.4.2",
"resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz",
"integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==",
"license": "Apache-2.0"
"license": "Apache-2.0",
"peer": true
},
"node_modules/create-require": {
"version": "1.1.1",
@@ -1270,9 +1273,9 @@
}
},
"node_modules/dotenv": {
"version": "16.5.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
"integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
@@ -1282,15 +1285,15 @@
}
},
"node_modules/envalid": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/envalid/-/envalid-8.0.0.tgz",
"integrity": "sha512-PGeYJnJB5naN0ME6SH8nFcDj9HVbLpYIfg1p5lAyM9T4cH2lwtu2fLbozC/bq+HUUOIFxhX/LP0/GmlqPHT4tQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/envalid/-/envalid-8.1.0.tgz",
"integrity": "sha512-OT6+qVhKVyCidaGoXflb2iK1tC8pd0OV2Q+v9n33wNhUJ+lus+rJobUj4vJaQBPxPZ0vYrPGuxdrenyCAIJcow==",
"license": "MIT",
"dependencies": {
"tslib": "2.6.2"
"tslib": "2.8.1"
},
"engines": {
"node": ">=8.12"
"node": ">=18"
}
},
"node_modules/make-error": {
@@ -1345,17 +1348,18 @@
}
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/typescript": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -1365,9 +1369,9 @@
}
},
"node_modules/undici-types": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"dev": true,
"license": "MIT"
},

View File

@@ -11,7 +11,6 @@ type PostgresClusterOptions = {
};
name: string;
namespace: string;
storageClass: string;
users: string[];
primaryUser: string;
initSecretName: string;
@@ -31,11 +30,13 @@ export class PostgresCluster extends Construct {
chart: "cloudnative-pg",
name: "postgres-system",
namespace: "cnpg-system",
createNamespace: true,
});
const destinationPath = "s3://homelab/";
const destinationPath = "s3://postgres-backups/";
const endpointURL = options.backupR2EndpointURL;
const barmanStoreName = "r2-postgres-backup-store";
const backupServerName = `${options.name}-backup`;
const barmanConfiguration = {
destinationPath,
@@ -49,6 +50,16 @@ export class PostgresCluster extends Construct {
name: "cloudflare-token",
key: "secret_access_key",
},
region: {
name: "cloudflare-token",
key: "AWS_REGION",
},
},
wal: {
compression: "gzip",
},
data: {
compression: "gzip",
},
};
@@ -62,11 +73,9 @@ export class PostgresCluster extends Construct {
name: barmanStoreName,
},
spec: {
retentionPolicy: "15d",
configuration: {
...barmanConfiguration,
wal: {
compression: "gzip",
},
},
},
},
@@ -147,22 +156,6 @@ export class PostgresCluster extends Construct {
},
});
// Secret for server certificate
new Manifest(this, "server-ca-cert-secret", {
provider: kubernetes,
manifest: {
apiVersion: "v1",
kind: "Secret",
metadata: {
name: certNames.server,
namespace: options.namespace,
labels: {
"cnpg.io/reload": "",
},
},
},
});
// Server certificate
new Manifest(this, "server-cert", {
provider: kubernetes,
@@ -332,7 +325,7 @@ export class PostgresCluster extends Construct {
postgresql: {
parameters: {
archive_mode: "on",
archive_timeout: "5min",
archive_timeout: "60min",
checkpoint_timeout: "10min",
checkpoint_completion_target: "0.7",
dynamic_shared_memory_type: "posix",
@@ -346,16 +339,17 @@ export class PostgresCluster extends Construct {
logging_collector: "on",
max_parallel_workers: "32",
max_replication_slots: "32",
max_wal_size: "768MB",
max_worker_processes: "32",
max_slot_wal_keep_size: "256MB",
max_wal_size: "512MB",
min_wal_size: "128MB",
shared_memory_type: "mmap",
shared_preload_libraries: "",
ssl_max_protocol_version: "TLSv1.3",
ssl_min_protocol_version: "TLSv1.3",
wal_compression: "on",
wal_keep_size: "128MB",
wal_level: "logical",
wal_level: "replica",
wal_log_hints: "on",
wal_receiver_timeout: "5s",
wal_sender_timeout: "5s",
@@ -368,31 +362,16 @@ export class PostgresCluster extends Construct {
plugins: [
{
name: "barman-cloud.cloudnative-pg.io",
enabled: true,
isWALArchiver: true,
parameters: {
barmanObjectName: barmanStoreName,
serverName: backupServerName,
},
},
],
enableSuperuserAccess: true,
// bootstrap: {
// recovery: {
// source: "clusterBackup",
// database: "postgres",
// owner: options.primaryUser,
// secret: {
// name: options.initSecretName,
// },
// },
// },
bootstrap: {
initdb: {
database: "postgres",
secret: {
name: options.initSecretName,
},
postInitSQL: [`CREATE USER ${options.primaryUser} SUPERUSER;`],
recovery: {
source: "clusterBackup",
},
},
externalClusters: [
@@ -402,7 +381,8 @@ export class PostgresCluster extends Construct {
name: "barman-cloud.cloudnative-pg.io",
parameters: {
barmanObjectName: barmanStoreName,
serverName: "postgres-cluster",
serverName: backupServerName,
skipWalArchiveCheck: true,
},
},
},
@@ -416,6 +396,7 @@ export class PostgresCluster extends Construct {
serviceTemplate: {
metadata: {
name: "postgres-cluster",
superuser: true,
annotations: {
"external-dns.alpha.kubernetes.io/hostname":
"postgres.dogar.dev",
@@ -428,14 +409,26 @@ export class PostgresCluster extends Construct {
},
],
},
roles: [
{
name: options.primaryUser,
inRoles: ["postgres"],
inherit: true,
disablePassword: true,
createdb: true,
createrole: true,
login: true,
ensure: "present",
},
],
},
storage: {
size: "10Gi",
storageClass: options.storageClass,
storageClass: "longhorn",
},
walStorage: {
size: "1Gi",
storageClass: options.storageClass,
size: "2Gi",
storageClass: "longhorn",
},
},
},
@@ -451,8 +444,18 @@ export class PostgresCluster extends Construct {
namespace: options.namespace,
},
spec: {
schedule: "0 0 0 * * *", // daily at midnight
immediate: true,
// weekly midnight on Sunday
schedule: "* 0 0 * * 0",
backupOwnerReference: "self",
method: "plugin",
pluginConfiguration: {
name: "barman-cloud.cloudnative-pg.io",
parameters: {
barmanObjectName: barmanStoreName,
serverName: backupServerName,
},
},
cluster: {
name: options.name,
},

View File

@@ -17,7 +17,7 @@ export class ValkeyCluster extends Construct {
const labels = { app: "valkey" };
const { provider, name, namespace } = options;
new DeploymentV1(this, "valkeyDeployment", {
new DeploymentV1(this, "valkey-deployment", {
provider,
metadata: {
name,
@@ -93,7 +93,7 @@ export class ValkeyCluster extends Construct {
},
});
new ServiceV1(this, "valkeyService", {
new ServiceV1(this, "valkey-service", {
provider,
metadata: {
name,