Compare commits
12 Commits
db25a0ea79
...
5d95773722
| Author | SHA1 | Date | |
|---|---|---|---|
|
5d95773722
|
|||
|
c59ee18d09
|
|||
|
72b006a7e4
|
|||
|
0b01f40ac8
|
|||
|
d17c8b1b34
|
|||
|
5ee891fe2b
|
|||
|
d1aae53fa6
|
|||
|
6c419454d8
|
|||
|
706cd8e919
|
|||
|
c0e0d74e4f
|
|||
|
74707a469c
|
|||
|
3b9a75c7ba
|
43
flake.lock
generated
43
flake.lock
generated
@@ -18,49 +18,13 @@
|
|||||||
"type": "github"
|
"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": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1761236834,
|
"lastModified": 1762943920,
|
||||||
"narHash": "sha256-+pthv6hrL5VLW2UqPdISGuLiUZ6SnAXdd2DdUE+fV2Q=",
|
"narHash": "sha256-ITeH8GBpQTw9457ICZBddQEBjlXMmilML067q0e6vqY=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d5faa84122bc0a1fd5d378492efce4e289f8eac1",
|
"rev": "91c9a64ce2a84e648d0cf9671274bb9c2fb9ba60",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -73,7 +37,6 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"krew2nix": "krew2nix",
|
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
13
flake.nix
13
flake.nix
@@ -4,14 +4,9 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
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
|
let
|
||||||
lib = nixpkgs.lib;
|
lib = nixpkgs.lib;
|
||||||
|
|
||||||
@@ -24,16 +19,12 @@
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
kubectl = krew2nix.packages.${system}.kubectl;
|
|
||||||
in {
|
in {
|
||||||
# Define the devShell for the current system
|
# Define the devShell for the current system
|
||||||
devShell = pkgs.mkShell {
|
devShell = pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
kubernetes-helm
|
kubernetes-helm
|
||||||
(kubectl.withKrewPlugins (plugins: with plugins; [
|
kubectl-cnpg
|
||||||
cnpg
|
|
||||||
]))
|
|
||||||
nil
|
nil
|
||||||
terraform
|
terraform
|
||||||
tflint
|
tflint
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
global:
|
global:
|
||||||
storageClass: longhorn-crypto
|
storageClass: longhorn
|
||||||
image:
|
image:
|
||||||
rootless: false
|
rootless: false
|
||||||
service:
|
service:
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
|
global:
|
||||||
|
nodeSelector:
|
||||||
|
nodepool: worker
|
||||||
defaultSettings:
|
defaultSettings:
|
||||||
defaultReplicaCount: 3
|
defaultReplicaCount: "3"
|
||||||
storageOverProvisioningPercentage: 100
|
storageOverProvisioningPercentage: "100"
|
||||||
backupCompressionMethod: "gzip"
|
backupCompressionMethod: "gzip"
|
||||||
|
replicaSoftAntiAffinity: "true"
|
||||||
|
concurrentReplicaRebuildPerNodeLimit: "1"
|
||||||
|
replicaReplenishmentWaitInterval: "600"
|
||||||
|
disableSchdedulingOnCordonedNode: "true"
|
||||||
defaultBackupStore:
|
defaultBackupStore:
|
||||||
backupTarget: "s3://homelab@auto/longhorn"
|
backupTarget: "s3://longhorn-backups@auto"
|
||||||
backupTargetCredentialSecret: cloudflare-token
|
backupTargetCredentialSecret: cloudflare-token
|
||||||
metrics:
|
metrics:
|
||||||
serviceMonitor:
|
serviceMonitor:
|
||||||
enabled: true
|
enabled: false
|
||||||
ingress:
|
ingress:
|
||||||
enabled: true
|
enabled: true
|
||||||
ingressClassName: nginx-internal
|
ingressClassName: nginx-internal
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
controller:
|
controller:
|
||||||
|
replicaCount: 3
|
||||||
|
nodeSelector:
|
||||||
|
nodepool: worker
|
||||||
ingressClassResource:
|
ingressClassResource:
|
||||||
name: nginx-internal
|
name: nginx-internal
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -9,8 +12,31 @@ controller:
|
|||||||
service:
|
service:
|
||||||
annotations:
|
annotations:
|
||||||
external-dns.alpha.kubernetes.io/hostname: "dogar.dev"
|
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:
|
tcp:
|
||||||
22: "homelab/gitea-ssh:22"
|
22: "homelab/gitea-ssh:22"
|
||||||
25565: "minecraft/monifactory-server:25565"
|
25565: "minecraft/monifactory-server:25565"
|
||||||
25566: "minecraft/gtnh-server:25565"
|
25566: "minecraft/gtnh-server:25565"
|
||||||
25567: "minecraft/tfg-server:25565"
|
25567: "minecraft/tfg-server:25565"
|
||||||
|
25568: "minecraft/atm10-server:25565"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
commonLabels:
|
metadata:
|
||||||
|
labels:
|
||||||
app.kubernetes.io/managed-by: Kustomize
|
app.kubernetes.io/managed-by: Kustomize
|
||||||
resources:
|
resources:
|
||||||
- ./metallb/pool.yaml
|
- ./metallb/pool.yaml
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ apiVersion: metallb.io/v1beta1
|
|||||||
kind: IPAddressPool
|
kind: IPAddressPool
|
||||||
metadata:
|
metadata:
|
||||||
name: pool
|
name: pool
|
||||||
namespace: homelab
|
namespace: metallb-system
|
||||||
spec:
|
spec:
|
||||||
addresses:
|
addresses:
|
||||||
- 192.168.18.192/26
|
- 192.168.18.192/26
|
||||||
@@ -12,7 +12,7 @@ apiVersion: metallb.io/v1beta1
|
|||||||
kind: L2Advertisement
|
kind: L2Advertisement
|
||||||
metadata:
|
metadata:
|
||||||
name: pool
|
name: pool
|
||||||
namespace: homelab
|
namespace: metallb-system
|
||||||
spec:
|
spec:
|
||||||
ipAddressPools:
|
ipAddressPools:
|
||||||
- pool
|
- pool
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ type LonghornOptions = {
|
|||||||
helm: HelmProvider;
|
helm: HelmProvider;
|
||||||
};
|
};
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Longhorn extends Construct {
|
export class Longhorn extends Construct {
|
||||||
@@ -19,15 +18,15 @@ export class Longhorn extends Construct {
|
|||||||
super(scope, id);
|
super(scope, id);
|
||||||
|
|
||||||
const { helm, kubernetes } = options.providers;
|
const { helm, kubernetes } = options.providers;
|
||||||
|
const namespace = "longhorn-system";
|
||||||
|
|
||||||
new Release(this, id, {
|
new Release(this, id, {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
namespace: options.namespace,
|
namespace,
|
||||||
provider: helm,
|
provider: helm,
|
||||||
repository: "https://charts.longhorn.io",
|
repository: "https://charts.longhorn.io",
|
||||||
chart: "longhorn",
|
chart: "longhorn",
|
||||||
createNamespace: true,
|
createNamespace: true,
|
||||||
upgradeInstall: true,
|
|
||||||
values: [
|
values: [
|
||||||
fs.readFileSync("helm/values/longhorn.values.yaml", {
|
fs.readFileSync("helm/values/longhorn.values.yaml", {
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
@@ -38,44 +37,19 @@ export class Longhorn extends Construct {
|
|||||||
new Manifest(this, "recurring-backup-job", {
|
new Manifest(this, "recurring-backup-job", {
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
manifest: {
|
manifest: {
|
||||||
apiVersion: "longhorn.io/v1beta1",
|
apiVersion: "longhorn.io/v1beta2",
|
||||||
kind: "RecurringJob",
|
kind: "RecurringJob",
|
||||||
metadata: {
|
metadata: {
|
||||||
name: "daily-backup",
|
name: "daily-backup",
|
||||||
namespace: options.namespace,
|
namespace,
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
cron: "0 0 * * *",
|
cron: "0 0 * * *",
|
||||||
task: "backup",
|
task: "backup",
|
||||||
retain: 30,
|
retain: 7,
|
||||||
groups: ["default"],
|
|
||||||
concurrency: 3,
|
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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
main.ts
34
main.ts
@@ -1,9 +1,10 @@
|
|||||||
import * as dotenv from "dotenv";
|
import * as dotenv from "dotenv";
|
||||||
import { cleanEnv, str } from "envalid";
|
import { cleanEnv, str } from "envalid";
|
||||||
import { Construct } from "constructs";
|
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 { HelmProvider } from "@cdktf/provider-helm/lib/provider";
|
||||||
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
import { KubernetesProvider } from "@cdktf/provider-kubernetes/lib/provider";
|
||||||
|
import { NamespaceV1 } from "@cdktf/provider-kubernetes/lib/namespace-v1";
|
||||||
|
|
||||||
import { GiteaServer } from "./gitea";
|
import { GiteaServer } from "./gitea";
|
||||||
import { OnePassword } from "./1password";
|
import { OnePassword } from "./1password";
|
||||||
@@ -12,7 +13,6 @@ import { Longhorn } from "./longhorn";
|
|||||||
import { AuthentikServer } from "./authentik";
|
import { AuthentikServer } from "./authentik";
|
||||||
import { ValkeyCluster } from "./valkey";
|
import { ValkeyCluster } from "./valkey";
|
||||||
import { CertManager } from "./cert-manager";
|
import { CertManager } from "./cert-manager";
|
||||||
import { Manifest } from "@cdktf/provider-kubernetes/lib/manifest";
|
|
||||||
import { Nginx } from "./nginx";
|
import { Nginx } from "./nginx";
|
||||||
import { Prometheus } from "./prometheus";
|
import { Prometheus } from "./prometheus";
|
||||||
import { MetalLB } from "./metallb";
|
import { MetalLB } from "./metallb";
|
||||||
@@ -45,16 +45,11 @@ class Homelab extends TerraformStack {
|
|||||||
|
|
||||||
const namespace = "homelab";
|
const namespace = "homelab";
|
||||||
|
|
||||||
const ns = new Manifest(this, "namespace", {
|
new NamespaceV1(this, "namespace", {
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
manifest: {
|
|
||||||
kind: "Namespace",
|
|
||||||
apiVersion: "v1",
|
|
||||||
metadata: {
|
metadata: {
|
||||||
name: namespace,
|
name: namespace,
|
||||||
},
|
},
|
||||||
spec: {},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
new Longhorn(this, "longhorn", {
|
new Longhorn(this, "longhorn", {
|
||||||
@@ -65,12 +60,10 @@ class Homelab extends TerraformStack {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
longhorn.node.addDependency(ns);
|
|
||||||
|
|
||||||
new MetalLB(this, "metallb", {
|
new MetalLB(this, "metallb", {
|
||||||
provider: helm,
|
provider: helm,
|
||||||
name: "metallb",
|
name: "metallb",
|
||||||
namespace,
|
namespace: "metallb-system",
|
||||||
});
|
});
|
||||||
|
|
||||||
new OnePassword(this, "one-password", {
|
new OnePassword(this, "one-password", {
|
||||||
@@ -121,7 +114,6 @@ class Homelab extends TerraformStack {
|
|||||||
kubernetes,
|
kubernetes,
|
||||||
helm,
|
helm,
|
||||||
},
|
},
|
||||||
storageClass: "longhorn-crypto",
|
|
||||||
users: ["shahab", "budget-tracker", "authentik", "gitea"],
|
users: ["shahab", "budget-tracker", "authentik", "gitea"],
|
||||||
primaryUser: "shahab",
|
primaryUser: "shahab",
|
||||||
initSecretName: "postgres-password",
|
initSecretName: "postgres-password",
|
||||||
@@ -156,21 +148,9 @@ class Homelab extends TerraformStack {
|
|||||||
const app = new App();
|
const app = new App();
|
||||||
const stack = new Homelab(app, "homelab");
|
const stack = new Homelab(app, "homelab");
|
||||||
|
|
||||||
new S3Backend(stack, {
|
new LocalBackend(stack, {
|
||||||
encrypt: true,
|
path: "terraform.tfstate",
|
||||||
bucket: env.BUCKET,
|
workspaceDir: ".",
|
||||||
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}`,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.synth();
|
app.synth();
|
||||||
|
|||||||
231
media/deployment.yaml
Normal file
231
media/deployment.yaml
Normal 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
76
media/ingress.yaml
Normal 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
5
media/namespace.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: media
|
||||||
106
media/pvc.yaml
Normal file
106
media/pvc.yaml
Normal 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
69
media/service.yaml
Normal 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
|
||||||
@@ -5,7 +5,6 @@ metadata:
|
|||||||
name: monifactory-data
|
name: monifactory-data
|
||||||
namespace: minecraft
|
namespace: minecraft
|
||||||
spec:
|
spec:
|
||||||
storageClassName: longhorn-crypto
|
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteMany
|
- ReadWriteMany
|
||||||
resources:
|
resources:
|
||||||
@@ -18,7 +17,6 @@ metadata:
|
|||||||
name: gtnh-data
|
name: gtnh-data
|
||||||
namespace: minecraft
|
namespace: minecraft
|
||||||
spec:
|
spec:
|
||||||
storageClassName: longhorn-crypto
|
|
||||||
accessModes:
|
accessModes:
|
||||||
- ReadWriteMany
|
- ReadWriteMany
|
||||||
resources:
|
resources:
|
||||||
@@ -31,7 +29,21 @@ metadata:
|
|||||||
name: tfg-data
|
name: tfg-data
|
||||||
namespace: minecraft
|
namespace: minecraft
|
||||||
spec:
|
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:
|
accessModes:
|
||||||
- ReadWriteMany
|
- ReadWriteMany
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
@@ -43,3 +43,18 @@ spec:
|
|||||||
port: 25565
|
port: 25565
|
||||||
selector:
|
selector:
|
||||||
app: tfg-server
|
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
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ metadata:
|
|||||||
name: monifactory-server
|
name: monifactory-server
|
||||||
namespace: minecraft
|
namespace: minecraft
|
||||||
spec:
|
spec:
|
||||||
|
serviceName: monifactory-server
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: monifactory-server
|
app: monifactory-server
|
||||||
@@ -13,6 +14,8 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: monifactory-server
|
app: monifactory-server
|
||||||
spec:
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
nodepool: worker
|
||||||
containers:
|
containers:
|
||||||
- name: monifactory-server
|
- name: monifactory-server
|
||||||
image: itzg/minecraft-server:java17
|
image: itzg/minecraft-server:java17
|
||||||
@@ -37,7 +40,7 @@ spec:
|
|||||||
- name: INIT_MEMORY
|
- name: INIT_MEMORY
|
||||||
value: 4G
|
value: 4G
|
||||||
- name: MAX_MEMORY
|
- name: MAX_MEMORY
|
||||||
value: 8G
|
value: 12G
|
||||||
- name: ALLOW_FLIGHT
|
- name: ALLOW_FLIGHT
|
||||||
value: "TRUE"
|
value: "TRUE"
|
||||||
- name: ENABLE_ROLLING_LOGS
|
- name: ENABLE_ROLLING_LOGS
|
||||||
@@ -53,7 +56,7 @@ spec:
|
|||||||
memory: "4Gi"
|
memory: "4Gi"
|
||||||
limits:
|
limits:
|
||||||
cpu: 8
|
cpu: 8
|
||||||
memory: "8Gi"
|
memory: "12Gi"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: monifactory-data
|
- name: monifactory-data
|
||||||
mountPath: /data
|
mountPath: /data
|
||||||
@@ -68,6 +71,7 @@ metadata:
|
|||||||
name: gtnh-server
|
name: gtnh-server
|
||||||
namespace: minecraft
|
namespace: minecraft
|
||||||
spec:
|
spec:
|
||||||
|
serviceName: gtnh-server
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: gtnh-server
|
app: gtnh-server
|
||||||
@@ -76,6 +80,8 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: gtnh-server
|
app: gtnh-server
|
||||||
spec:
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
nodepool: worker
|
||||||
containers:
|
containers:
|
||||||
- name: gtnh-server
|
- name: gtnh-server
|
||||||
image: itzg/minecraft-server:java25
|
image: itzg/minecraft-server:java25
|
||||||
@@ -97,7 +103,7 @@ spec:
|
|||||||
- name: SKIP_GENERIC_PACK_UPDATE_CHECK
|
- name: SKIP_GENERIC_PACK_UPDATE_CHECK
|
||||||
value: "true"
|
value: "true"
|
||||||
- name: MEMORY
|
- name: MEMORY
|
||||||
value: 6G
|
value: 12G
|
||||||
- name: JVM_OPTS
|
- name: JVM_OPTS
|
||||||
value: "-Dfml.readTimeout=180 -Dfml.queryResult=confirm @java9args.txt"
|
value: "-Dfml.readTimeout=180 -Dfml.queryResult=confirm @java9args.txt"
|
||||||
- name: CUSTOM_JAR_EXEC
|
- name: CUSTOM_JAR_EXEC
|
||||||
@@ -112,7 +118,7 @@ spec:
|
|||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 8
|
cpu: 8
|
||||||
memory: "8Gi"
|
memory: "12Gi"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: gtnh-data
|
- name: gtnh-data
|
||||||
mountPath: /data
|
mountPath: /data
|
||||||
@@ -127,6 +133,7 @@ metadata:
|
|||||||
name: tfg-server
|
name: tfg-server
|
||||||
namespace: minecraft
|
namespace: minecraft
|
||||||
spec:
|
spec:
|
||||||
|
serviceName: tfg-server
|
||||||
selector:
|
selector:
|
||||||
matchLabels:
|
matchLabels:
|
||||||
app: tfg-server
|
app: tfg-server
|
||||||
@@ -135,6 +142,8 @@ spec:
|
|||||||
labels:
|
labels:
|
||||||
app: tfg-server
|
app: tfg-server
|
||||||
spec:
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
nodepool: worker
|
||||||
containers:
|
containers:
|
||||||
- name: tfg-server
|
- name: tfg-server
|
||||||
image: itzg/minecraft-server:java17
|
image: itzg/minecraft-server:java17
|
||||||
@@ -159,7 +168,7 @@ spec:
|
|||||||
- name: INIT_MEMORY
|
- name: INIT_MEMORY
|
||||||
value: 2G
|
value: 2G
|
||||||
- name: MAX_MEMORY
|
- name: MAX_MEMORY
|
||||||
value: 8G
|
value: 12G
|
||||||
- name: ALLOW_FLIGHT
|
- name: ALLOW_FLIGHT
|
||||||
value: "TRUE"
|
value: "TRUE"
|
||||||
- name: ENABLE_ROLLING_LOGS
|
- name: ENABLE_ROLLING_LOGS
|
||||||
@@ -175,7 +184,7 @@ spec:
|
|||||||
memory: "2Gi"
|
memory: "2Gi"
|
||||||
limits:
|
limits:
|
||||||
cpu: 6
|
cpu: 6
|
||||||
memory: "9Gi"
|
memory: "12Gi"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: tfg-data
|
- name: tfg-data
|
||||||
mountPath: /data
|
mountPath: /data
|
||||||
@@ -183,3 +192,71 @@ spec:
|
|||||||
- name: tfg-data
|
- name: tfg-data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: tfg-data
|
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
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { HelmProvider } from "@cdktf/provider-helm/lib/provider";
|
|||||||
import { Release } from "@cdktf/provider-helm/lib/release";
|
import { Release } from "@cdktf/provider-helm/lib/release";
|
||||||
import { Construct } from "constructs";
|
import { Construct } from "constructs";
|
||||||
|
|
||||||
|
import { NixCache } from "./nix-cache";
|
||||||
|
|
||||||
type NginxOptions = {
|
type NginxOptions = {
|
||||||
provider: HelmProvider;
|
provider: HelmProvider;
|
||||||
name: string;
|
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
105
nginx/nix-cache.ts
Normal 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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?
|
|
||||||
}
|
|
||||||
@@ -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 = "/";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
48
nixos/master/flake.lock
generated
48
nixos/master/flake.lock
generated
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -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
54
package-lock.json
generated
@@ -75,9 +75,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/sourcemap-codec": {
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -121,13 +121,14 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.0.3",
|
"version": "24.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz",
|
||||||
"integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==",
|
"integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.8.0"
|
"undici-types": "~7.16.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
@@ -173,6 +174,7 @@
|
|||||||
"semver"
|
"semver"
|
||||||
],
|
],
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"archiver": "7.0.1",
|
"archiver": "7.0.1",
|
||||||
"json-stable-stringify": "1.2.1",
|
"json-stable-stringify": "1.2.1",
|
||||||
@@ -1250,7 +1252,8 @@
|
|||||||
"version": "10.4.2",
|
"version": "10.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz",
|
||||||
"integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==",
|
"integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/create-require": {
|
"node_modules/create-require": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -1270,9 +1273,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "16.5.0",
|
"version": "16.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
|
||||||
"integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
|
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
@@ -1282,15 +1285,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/envalid": {
|
"node_modules/envalid": {
|
||||||
"version": "8.0.0",
|
"version": "8.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/envalid/-/envalid-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/envalid/-/envalid-8.1.0.tgz",
|
||||||
"integrity": "sha512-PGeYJnJB5naN0ME6SH8nFcDj9HVbLpYIfg1p5lAyM9T4cH2lwtu2fLbozC/bq+HUUOIFxhX/LP0/GmlqPHT4tQ==",
|
"integrity": "sha512-OT6+qVhKVyCidaGoXflb2iK1tC8pd0OV2Q+v9n33wNhUJ+lus+rJobUj4vJaQBPxPZ0vYrPGuxdrenyCAIJcow==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "2.6.2"
|
"tslib": "2.8.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.12"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/make-error": {
|
"node_modules/make-error": {
|
||||||
@@ -1345,17 +1348,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.6.2",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"license": "0BSD"
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.8.3",
|
"version": "5.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -1365,9 +1369,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.8.0",
|
"version": "7.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
|
||||||
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ type PostgresClusterOptions = {
|
|||||||
};
|
};
|
||||||
name: string;
|
name: string;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
storageClass: string;
|
|
||||||
users: string[];
|
users: string[];
|
||||||
primaryUser: string;
|
primaryUser: string;
|
||||||
initSecretName: string;
|
initSecretName: string;
|
||||||
@@ -31,11 +30,13 @@ export class PostgresCluster extends Construct {
|
|||||||
chart: "cloudnative-pg",
|
chart: "cloudnative-pg",
|
||||||
name: "postgres-system",
|
name: "postgres-system",
|
||||||
namespace: "cnpg-system",
|
namespace: "cnpg-system",
|
||||||
|
createNamespace: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const destinationPath = "s3://homelab/";
|
const destinationPath = "s3://postgres-backups/";
|
||||||
const endpointURL = options.backupR2EndpointURL;
|
const endpointURL = options.backupR2EndpointURL;
|
||||||
const barmanStoreName = "r2-postgres-backup-store";
|
const barmanStoreName = "r2-postgres-backup-store";
|
||||||
|
const backupServerName = `${options.name}-backup`;
|
||||||
|
|
||||||
const barmanConfiguration = {
|
const barmanConfiguration = {
|
||||||
destinationPath,
|
destinationPath,
|
||||||
@@ -49,6 +50,16 @@ export class PostgresCluster extends Construct {
|
|||||||
name: "cloudflare-token",
|
name: "cloudflare-token",
|
||||||
key: "secret_access_key",
|
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,
|
name: barmanStoreName,
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
|
retentionPolicy: "15d",
|
||||||
configuration: {
|
configuration: {
|
||||||
...barmanConfiguration,
|
...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
|
// Server certificate
|
||||||
new Manifest(this, "server-cert", {
|
new Manifest(this, "server-cert", {
|
||||||
provider: kubernetes,
|
provider: kubernetes,
|
||||||
@@ -332,7 +325,7 @@ export class PostgresCluster extends Construct {
|
|||||||
postgresql: {
|
postgresql: {
|
||||||
parameters: {
|
parameters: {
|
||||||
archive_mode: "on",
|
archive_mode: "on",
|
||||||
archive_timeout: "5min",
|
archive_timeout: "60min",
|
||||||
checkpoint_timeout: "10min",
|
checkpoint_timeout: "10min",
|
||||||
checkpoint_completion_target: "0.7",
|
checkpoint_completion_target: "0.7",
|
||||||
dynamic_shared_memory_type: "posix",
|
dynamic_shared_memory_type: "posix",
|
||||||
@@ -346,16 +339,17 @@ export class PostgresCluster extends Construct {
|
|||||||
logging_collector: "on",
|
logging_collector: "on",
|
||||||
max_parallel_workers: "32",
|
max_parallel_workers: "32",
|
||||||
max_replication_slots: "32",
|
max_replication_slots: "32",
|
||||||
max_wal_size: "768MB",
|
|
||||||
max_worker_processes: "32",
|
max_worker_processes: "32",
|
||||||
max_slot_wal_keep_size: "256MB",
|
max_slot_wal_keep_size: "256MB",
|
||||||
|
max_wal_size: "512MB",
|
||||||
min_wal_size: "128MB",
|
min_wal_size: "128MB",
|
||||||
shared_memory_type: "mmap",
|
shared_memory_type: "mmap",
|
||||||
shared_preload_libraries: "",
|
shared_preload_libraries: "",
|
||||||
ssl_max_protocol_version: "TLSv1.3",
|
ssl_max_protocol_version: "TLSv1.3",
|
||||||
ssl_min_protocol_version: "TLSv1.3",
|
ssl_min_protocol_version: "TLSv1.3",
|
||||||
|
wal_compression: "on",
|
||||||
wal_keep_size: "128MB",
|
wal_keep_size: "128MB",
|
||||||
wal_level: "logical",
|
wal_level: "replica",
|
||||||
wal_log_hints: "on",
|
wal_log_hints: "on",
|
||||||
wal_receiver_timeout: "5s",
|
wal_receiver_timeout: "5s",
|
||||||
wal_sender_timeout: "5s",
|
wal_sender_timeout: "5s",
|
||||||
@@ -368,31 +362,16 @@ export class PostgresCluster extends Construct {
|
|||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
name: "barman-cloud.cloudnative-pg.io",
|
name: "barman-cloud.cloudnative-pg.io",
|
||||||
enabled: true,
|
|
||||||
isWALArchiver: true,
|
isWALArchiver: true,
|
||||||
parameters: {
|
parameters: {
|
||||||
barmanObjectName: barmanStoreName,
|
barmanObjectName: barmanStoreName,
|
||||||
|
serverName: backupServerName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
enableSuperuserAccess: true,
|
|
||||||
// bootstrap: {
|
|
||||||
// recovery: {
|
|
||||||
// source: "clusterBackup",
|
|
||||||
// database: "postgres",
|
|
||||||
// owner: options.primaryUser,
|
|
||||||
// secret: {
|
|
||||||
// name: options.initSecretName,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
bootstrap: {
|
bootstrap: {
|
||||||
initdb: {
|
recovery: {
|
||||||
database: "postgres",
|
source: "clusterBackup",
|
||||||
secret: {
|
|
||||||
name: options.initSecretName,
|
|
||||||
},
|
|
||||||
postInitSQL: [`CREATE USER ${options.primaryUser} SUPERUSER;`],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
externalClusters: [
|
externalClusters: [
|
||||||
@@ -402,7 +381,8 @@ export class PostgresCluster extends Construct {
|
|||||||
name: "barman-cloud.cloudnative-pg.io",
|
name: "barman-cloud.cloudnative-pg.io",
|
||||||
parameters: {
|
parameters: {
|
||||||
barmanObjectName: barmanStoreName,
|
barmanObjectName: barmanStoreName,
|
||||||
serverName: "postgres-cluster",
|
serverName: backupServerName,
|
||||||
|
skipWalArchiveCheck: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -416,6 +396,7 @@ export class PostgresCluster extends Construct {
|
|||||||
serviceTemplate: {
|
serviceTemplate: {
|
||||||
metadata: {
|
metadata: {
|
||||||
name: "postgres-cluster",
|
name: "postgres-cluster",
|
||||||
|
superuser: true,
|
||||||
annotations: {
|
annotations: {
|
||||||
"external-dns.alpha.kubernetes.io/hostname":
|
"external-dns.alpha.kubernetes.io/hostname":
|
||||||
"postgres.dogar.dev",
|
"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: {
|
storage: {
|
||||||
size: "10Gi",
|
size: "10Gi",
|
||||||
storageClass: options.storageClass,
|
storageClass: "longhorn",
|
||||||
},
|
},
|
||||||
walStorage: {
|
walStorage: {
|
||||||
size: "1Gi",
|
size: "2Gi",
|
||||||
storageClass: options.storageClass,
|
storageClass: "longhorn",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -451,8 +444,18 @@ export class PostgresCluster extends Construct {
|
|||||||
namespace: options.namespace,
|
namespace: options.namespace,
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
schedule: "0 0 0 * * *", // daily at midnight
|
immediate: true,
|
||||||
|
// weekly midnight on Sunday
|
||||||
|
schedule: "* 0 0 * * 0",
|
||||||
backupOwnerReference: "self",
|
backupOwnerReference: "self",
|
||||||
|
method: "plugin",
|
||||||
|
pluginConfiguration: {
|
||||||
|
name: "barman-cloud.cloudnative-pg.io",
|
||||||
|
parameters: {
|
||||||
|
barmanObjectName: barmanStoreName,
|
||||||
|
serverName: backupServerName,
|
||||||
|
},
|
||||||
|
},
|
||||||
cluster: {
|
cluster: {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export class ValkeyCluster extends Construct {
|
|||||||
const labels = { app: "valkey" };
|
const labels = { app: "valkey" };
|
||||||
const { provider, name, namespace } = options;
|
const { provider, name, namespace } = options;
|
||||||
|
|
||||||
new DeploymentV1(this, "valkeyDeployment", {
|
new DeploymentV1(this, "valkey-deployment", {
|
||||||
provider,
|
provider,
|
||||||
metadata: {
|
metadata: {
|
||||||
name,
|
name,
|
||||||
@@ -93,7 +93,7 @@ export class ValkeyCluster extends Construct {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
new ServiceV1(this, "valkeyService", {
|
new ServiceV1(this, "valkey-service", {
|
||||||
provider,
|
provider,
|
||||||
metadata: {
|
metadata: {
|
||||||
name,
|
name,
|
||||||
|
|||||||
Reference in New Issue
Block a user