151 Commits

Author SHA1 Message Date
191f2c747e remove larry from psql 2025-12-31 16:01:33 -05:00
2cf472ed35 remove nvidia and larry selectors 2025-12-31 15:43:39 -05:00
38c5b1b2df sops yaml 2025-12-21 14:06:18 -05:00
0b38af2492 kube prometheus stack downgrade 2025-12-19 16:01:50 -05:00
f776bdccaf kube prometheus stack grafana credentials 2025-12-19 15:38:15 -05:00
c2d39fb5b7 immich postgres podmonitor 2025-12-19 15:24:50 -05:00
a491af0099 update kube prometheus stack 2025-12-19 15:06:19 -05:00
2ba715a948 prometheus: use all monitors 2025-12-19 14:15:50 -05:00
156e26b9a5 update traefik 2025-12-19 13:15:03 -05:00
bc5b430426 remove reflector 2025-12-18 06:24:36 -05:00
2c8f7a0ef1 remove wildcard cert 2025-12-18 06:24:21 -05:00
27c6abb459 move all certs to automatic issuer 2025-12-18 06:17:35 -05:00
f1d0cbeedd move issuer to configs 2025-12-18 06:12:31 -05:00
8f4c2dc1b3 try ingress-generated certs 2025-12-18 05:34:06 -05:00
c9ab918716 remove sealed secrets 2025-12-17 16:11:34 -05:00
22eb8f3817 add all sops secrets 2025-12-17 15:57:49 -05:00
2278720656 remove all sealed secrets 2025-12-17 15:55:18 -05:00
03f4c29ec9 Revert "test: sops"
This reverts commit a1474579a5.
2025-12-17 15:49:50 -05:00
a1474579a5 test: sops 2025-12-17 15:37:08 -05:00
48f6f5e1b5 sops decryption on all kustomizations 2025-12-17 14:21:48 -05:00
e072415e68 sops enable on booklore 2025-12-17 12:48:24 -05:00
75d3669947 sops secret test 2025-12-17 12:35:26 -05:00
290617d375 update longhorn defaults 2025-12-17 10:58:17 -05:00
fd0663d455 patch kustomize controller for global SOPS 2025-12-17 10:35:48 -05:00
28f4c67477 remove calibre 2025-12-17 06:02:04 -05:00
eeef0657ed refactor dns endpoint usage to annotations 2025-12-17 05:50:08 -05:00
f66dd41bf5 fix nextcloud aggain again 2025-12-13 23:20:29 -05:00
3673d4a32c fix nextcloud aggain 2025-12-13 23:12:54 -05:00
fd9ea70d25 fix nextcloud 2025-12-13 23:06:58 -05:00
b2a695cce8 fix immich 2025-12-13 22:50:12 -05:00
ed607e8dde update nextcloud again 2025-12-13 22:37:56 -05:00
39b820b704 update nextcloud once 2025-12-13 22:31:42 -05:00
32e9573888 update authentik and immich secrets again 2025-12-13 22:30:15 -05:00
7c63381686 update authentik and immich secrets 2025-12-13 21:48:28 -05:00
4c04890598 downgrade nextcloud postgres 2025-12-13 20:44:12 -05:00
3f2eb57074 update nextcloud 2025-12-13 20:37:44 -05:00
6730b79a87 fix gitea secret ref 2025-12-13 20:35:25 -05:00
4504b2635b fix karakeep secret 2025-12-13 20:15:05 -05:00
23e681529d update secrets 2025-12-13 20:11:59 -05:00
5bb12088eb namespaces before crds 2025-12-13 14:56:38 -05:00
437ad8d5fc fix longorn secret 2025-12-13 13:35:55 -05:00
e497126f24 traefik remove server loadbalancerip 2025-12-13 12:53:18 -05:00
1aacc702e7 move metallb configs to controllers 2025-12-13 12:42:40 -05:00
202f41968a fix traefik 2025-12-13 12:30:19 -05:00
322d16c104 cert namespace 2025-12-13 12:02:14 -05:00
2780080af9 move cert and issuer to controllers 2025-12-13 11:58:35 -05:00
6e63085fb3 re-ecnrypt all secrets, update some values 2025-12-13 11:33:20 -05:00
f12e27c5c6 change clusters to backup mode 2025-12-13 09:15:34 -05:00
8ff38d1cbf update crds 2025-12-12 18:23:47 -05:00
Flux
744e5a8cce Add Flux v2.7.4 component manifests 2025-12-12 17:11:50 -05:00
2582696e53 update server to new local 2025-12-12 14:29:35 -05:00
28c142c348 minecraft whitelist 2025-12-11 16:19:09 -05:00
8cb9a318ca minecraft loadbalancer 2025-12-09 13:44:50 -05:00
9b43e6b7e5 minecraft ingress 2025-12-08 17:02:25 -05:00
b1aa0ae0ae minecraft 2025-12-08 16:58:04 -05:00
969a3adf32 stirling pdf fix chart ref 2025-12-03 12:56:27 -05:00
6708cd2f91 stirling pdf fix 2025-12-03 12:53:49 -05:00
dffee43871 stirling pdf 2025-12-03 12:52:39 -05:00
66c98c84c1 update: use new gpu node label 2025-12-03 11:56:49 -05:00
6489eb02fe update: nvidia device plugin -> cdi plugin 2025-12-03 11:49:49 -05:00
3d31e8ec54 fix: deprecated metallb annotations 2025-12-01 10:37:14 -05:00
586e5c245e fix: retention policy 2025-11-27 20:48:28 -05:00
f74e995af7 fix: update booklore dns 2025-10-30 12:48:08 -04:00
5685149b77 fix: update booklore mariadb tag 2025-10-30 10:58:55 -04:00
8e974c6e91 fix: ingress 2025-10-30 10:49:46 -04:00
ea570f1ef9 fix: mariadb tag change 2025-10-30 10:44:58 -04:00
f15974712d booklore 2025-10-30 10:36:29 -04:00
dff4173e0a update authentik 2025-10-22 10:50:14 -04:00
b0d723a730 update immich again again again again again 2025-10-22 10:41:47 -04:00
cb7f79cea9 update immich again again again again 2025-10-22 10:32:07 -04:00
3a8a8807df update immich again again again 2025-10-22 10:05:06 -04:00
53956bc121 update immich again again 2025-10-22 09:48:56 -04:00
3536b46c4c update immich again 2025-10-22 09:39:56 -04:00
2a8197698b update immich 2025-10-22 09:32:31 -04:00
646dfa1c6c jellyfin transcode and cache folder 2025-10-21 12:08:12 -04:00
876c260d8a gitea actions fix root url 2025-10-21 11:04:55 -04:00
109fef07f8 gitea actions fix release name 2025-10-21 10:59:38 -04:00
2dc7088a07 gitea root url fix 2025-10-21 10:51:50 -04:00
b60f464b14 gitea actions 2025-10-21 10:48:02 -04:00
9cb1f1776f gitea enable actions 2025-10-21 10:27:35 -04:00
636e162ccc update gitea 2025-10-21 10:19:04 -04:00
3a4a6160c7 remove woodpecker 2025-10-21 10:11:20 -04:00
dff7ee1b25 remove qbittorrent and readarr 2025-10-05 16:56:06 -04:00
914ac3e05f update: removed plane 2025-09-27 12:41:22 -04:00
8d6275c5c0 actual fix port again again 2025-08-18 07:28:49 -04:00
aad9cc733f actual fix port again 2025-08-18 07:25:48 -04:00
b631e5b0c8 actual fix port 2025-08-18 07:14:56 -04:00
2567371b24 add actual again 2025-08-17 23:16:56 -04:00
824d17e48e karakeep fixed openai env variable 2025-07-15 15:21:21 -04:00
680f33f67c karakeep openai 2025-07-15 15:12:23 -04:00
417dbcaa02 remove roundcube 2025-06-17 15:54:03 -04:00
eb58e2925c karakeep back to nightly 2025-06-11 09:49:31 -04:00
47e6e2c559 karakeep fix 2025-06-11 09:46:14 -04:00
463f5b5de6 karakeep enable sign ups 2025-06-11 09:33:32 -04:00
310084743b hoarder -> karakeep 2025-06-11 09:17:48 -04:00
b8a80b1207 immich cnpg backup 2025-06-10 21:28:17 -04:00
fef24dc3cb longhorn wasabi secret fix for real this time 2025-06-10 16:50:29 -04:00
d66d0a5898 longhorn wasabi secret fix AGAIN 2025-06-10 16:47:34 -04:00
0aafd83d11 longhorn wasabi secret fix 2025-06-10 16:46:00 -04:00
682a5d7f15 longhorn wasabi 2025-06-10 16:42:00 -04:00
95204ab87d authentik cluster refactor 2025-06-10 16:32:29 -04:00
b43e1a8021 authentik cnpg cluster update 2025-06-10 16:13:07 -04:00
9043b3fe8c authentik cnpg skip wal archive check 2025-06-10 16:02:39 -04:00
0f6c348cd7 authentik cnpg test recovery 2025-06-10 15:53:09 -04:00
61f793a53c authentik cnpg add https 2025-06-10 15:29:03 -04:00
2effdb5a11 authentik cnpg try wasabi 2025-06-10 15:25:13 -04:00
3af28c1327 authentik cnpg try again AGAIN AGAIN 2025-06-10 13:30:07 -04:00
a481b39804 authentik cnpg try again AGAIN AGAIN 2025-06-10 13:27:16 -04:00
daecd18a1c authentik cnpg try again AGAIN AGAIN 2025-06-10 13:17:12 -04:00
cd87cb6db0 authentik cnpg try again AGAIN 2025-06-10 12:48:30 -04:00
e4cd178558 authentik cnpg try again AGAIN 2025-06-10 12:46:23 -04:00
1bc927163f authentik cnpg try again 2025-06-10 12:35:55 -04:00
aaa23b83fc authentik cnpg initdb 2025-06-10 12:28:35 -04:00
988c557214 authentik cnpg fix backup url 2025-06-10 12:19:53 -04:00
2688eace91 authentik cnpg remove initdb 2025-06-10 12:10:52 -04:00
a70c3c6359 authentik cnpg backup and restore 2025-06-10 12:03:07 -04:00
c9f9d7ed8f infra fix longhorn storage class AGAIN 2025-06-10 11:14:20 -04:00
84061baea7 infra reduce interval 2025-06-10 10:51:12 -04:00
6cd81a298b longhorn fix joblist again agin 2025-06-10 10:43:26 -04:00
a713647197 longhorn fix joblist again 2025-06-10 10:26:06 -04:00
f74da6a76d longhorn fix joblist again 2025-06-10 10:12:25 -04:00
75f07226aa longhorn recurring job CRDs 2025-06-10 10:07:18 -04:00
05a3648e1c authentik fix releas name 2025-06-10 09:17:04 -04:00
4f032d88e0 longhorn storage class recurringjobselector 2025-06-10 08:55:59 -04:00
a68e34a8d6 authentik add secret key to worker 2025-06-09 18:10:30 -04:00
073e66ea82 authentik 2025-06-09 18:04:34 -04:00
6749d92a43 re-enable prune 2025-06-09 17:23:11 -04:00
b8c7e8a353 keycloak fix resource limits 2025-06-09 17:07:17 -04:00
e77a8f51b2 keycloak fix chart ref 2025-06-09 16:59:06 -04:00
28e587a792 keycloak 2025-06-09 16:56:41 -04:00
fc9aeea582 immich remove proxy 2025-06-09 16:20:38 -04:00
099dabb671 traefik reenable dashboard 2025-06-09 16:01:26 -04:00
f8ab829e77 traefik update version 2025-06-09 15:53:49 -04:00
5ed48c7bcf traefik increase transport timeout for immich 2025-06-09 15:38:58 -04:00
50c82802c2 immich nvidia runtime fi 2025-06-09 14:40:07 -04:00
2ec6f85316 immich nvidia runtime 2025-06-09 14:23:23 -04:00
c90d1c0f63 immich nvidia support 2025-06-09 13:24:09 -04:00
e335b184c8 nvidia fix config map name 2025-06-09 13:11:01 -04:00
aa06e70feb nvidia time sharing 2025-06-09 13:08:11 -04:00
9372f79c4c ntfy remove kustomization 2025-06-09 10:03:58 -04:00
79d4e6f303 ntfy move generate configmap to normal configmap 2025-06-09 10:02:12 -04:00
e5f1a78c8d ntfy fix yaml again again 2025-06-09 09:58:15 -04:00
118e172313 ntfy fix yaml again 2025-06-09 09:52:18 -04:00
dfbd0532c9 ntfy fix yaml 2025-06-09 09:49:04 -04:00
249096bc1c ntfy 2025-06-09 09:46:19 -04:00
99f6236262 longhorn pg storageclass 2025-06-08 13:36:22 -04:00
cc4afd2003 remove short timeouts 2025-06-08 09:34:43 -04:00
ba3fdcbdd4 fix metallb namespace reference 2025-06-08 09:23:05 -04:00
36e18d5575 fix longhorn namespace reference 2025-06-08 09:22:19 -04:00
cfd5d5e6d0 fixed OCIrepo apiversion 2025-06-08 09:20:00 -04:00
ca695f44a0 Merge pull request #4 from michaelthomson0797/refactor/server-restructure
[Refactor] change entire server folder structure
2025-06-08 09:14:30 -04:00
235 changed files with 3343 additions and 6306 deletions

3
.sops.yaml Normal file
View File

@@ -0,0 +1,3 @@
creation_rules:
- encrypted_regex: ^(data|stringData)$
age: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9

View File

@@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: actual
namespace: actual
spec:
selector:
matchLabels:
app: actual
template:
metadata:
labels:
app: actual
spec:
containers:
- name: actual
image: docker.io/actualbudget/actual-server:latest
imagePullPolicy: Always
env:
- name: ACTUAL_PORT
value: "5006"
ports:
- containerPort: 5006
name: http
protocol: TCP
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: actual-data

28
apps/actual/ingress.yaml Normal file
View File

@@ -0,0 +1,28 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: actual
namespace: actual
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: actual.michaelthomson.dev
http:
paths:
- pathType: ImplementationSpecific
path: /
backend:
service:
name: actual
port:
name: http
tls:
- hosts:
- actual.michaelthomson.dev
secretName: actual-tls

View File

@@ -1,12 +1,12 @@
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: roundcubemail-temp-pvc name: actual-data
namespace: roundcube namespace: actual
spec: spec:
storageClassName: longhorn
accessModes:
- ReadWriteOnce
resources: resources:
requests: requests:
storage: 10Gi storage: 10Gi
storageClassName: longhorn
accessModes:
- ReadWriteOnce

View File

@@ -1,11 +1,11 @@
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: readarr name: actual
namespace: media namespace: actual
spec: spec:
selector: selector:
app: readarr app: actual
ports: ports:
- port: 80 - port: 80
targetPort: http targetPort: http

View File

@@ -0,0 +1,23 @@
apiVersion: v1
data:
password: ENC[AES256_GCM,data:a7nwc49lItIjjg6f7Vaz6Kyyb4CgwMmudHpsQAY39539fvCWtYjsoQzEqEXZdcwPyqB2qlOHewXcStBgG1B1iKKZhqE=,iv:yK9EZWhBNLm9lNs7V7Fm2MQWv3Lfb1o34P25+p00FgQ=,tag:ie24X9bcK1NdxZWhEKITHw==,type:str]
username: ENC[AES256_GCM,data:VmGN5YxRGZcS/EWy,iv:QKGSkxBSfMusEkl3sS1m3KQREvwUCP0aag8u7VPzWxo=,tag:zXthxvtKBex3XpRqO6Qcyg==,type:str]
kind: Secret
metadata:
name: authentik-postgres-credentials
namespace: authentik
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkZFlqTWZzTVNOV294bXF5
MEFFWGNXZkN6YjgrdGx2NkZyMHVWN25KSm5rCmxBQzNsSk53bDZiK3RQUCtYbjRu
NVUwZHJPSUhZTnEvdmNYNENSR1NSTTgKLS0tIFlmMTRSOWlKU1dYT0ZQQW1yTGx5
dWt0TXRDZ2VVVjREYjIvdTFUcVNxYjAKVYa8GZoKORII5nN0590OWzdbyoXe6Eyi
mRKUxtVsbhCPtfabQGn/tu40g7A9CFcWh51geIGewkTVmVlx0ulv/Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:32:24Z"
mac: ENC[AES256_GCM,data:N81ubg0zmCZpZKa+Z/IJZunsUUT8dZrWfp48cBNLg5GPr1O2SrvFUPo+ZWSDLRWWgea5E00kU1luDHcnTuHtjSF457anCc1LpezJnIIfPHQBE7wIrWkZMW1QYsScZhtNvkDf1LhXuo2JZnRkAZ249JzzPEYxy+GjLXU3hNaaeyw=,iv:V6Op3ZA9Rw2g20gzZapZt7GfnW7TW988psIIDlwxzaE=,tag:anOAkNKfUFhmntDH/i/v2w==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -0,0 +1,22 @@
apiVersion: v1
data:
key: ENC[AES256_GCM,data:0YHxGccmrLh2LFfAeySEqdfuE35FfzsAVI/XNcKKWKUS4HZ5sKUVy8PLSrl99nZRtC66Vj2Vsj/Zj+Ir/3/n8Vzhy04=,iv:whuMt5eTvp962tNisNDc5ygBaCzRs1MwBtOxWP+atv8=,tag:mcerAaPbzujtI25tPLETnQ==,type:str]
kind: Secret
metadata:
name: authentik-secret-key
namespace: authentik
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhRlB4Vjg5cU1QWWovRTFW
M1Q0cmpaWkNUek54T1VheGxMbVlIeUlybjMwCnVTY2VLTXVSbEpUc0lTRUtETUV3
TGRmVDB5cnhpU2k2YkNuL3d6OTVETW8KLS0tIDZoNjlTVERvR1FSczB5d09IVnpl
QnloYTFKNGdyR3FuS3N2WjVVVGFKRWsKd8MPL8raiwfz/fLsjL76tdeCBDu/cirV
DKFx+Tu8KTugK6gGteXA2/PHZPEB/U9Zh1OD3t6AdPZMQJaiNKq/4Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:RlZUTVt/3acp5BX92MI3USohXoAlZy8QAgr0HwLu0IMc+gUcykCXV/voYSJgIQlHhKDo/Jwa0+KhU3DLT/9GS4UF/E2GCJhj9t9DlagnchLxxJXYyP/7FPUkoOfDKmG1Sc2Gq3i/gTVklzQ0DpwQflF0F50BLDv1FqxUD84jVoI=,iv:T/Hd0kenM4LikCB9mkSrFMVD1UeA+Dvwi+3TLziwsdI=,tag:rfosFTQZo695lnznWC8JcQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -0,0 +1,57 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: postgres-cluster
namespace: authentik
annotations:
# needed to allow for recovery from same name cluster backup
cnpg.io/skipEmptyWalArchiveCheck: enabled
spec:
instances: 2
managed:
roles:
- name: authentik
superuser: true
login: true
bootstrap:
# initdb:
# database: authentik
# owner: authentik
# secret:
# name: authentik-postgres-credentials
# NOTE: uncomment this and commend the above initdb when recovering
recovery:
source: postgres-cluster
storage:
size: 8Gi
storageClass: longhorn-pg
externalClusters:
- name: postgres-cluster
barmanObjectStore:
destinationPath: "s3://mthomson-cnpg-backup/authentik/"
endpointURL: "https://s3.ca-central-1.wasabisys.com"
s3Credentials:
accessKeyId:
name: wasabi-secret
key: ACCESS_KEY_ID
secretAccessKey:
name: wasabi-secret
key: ACCESS_SECRET_KEY
backup:
barmanObjectStore:
destinationPath: "s3://mthomson-cnpg-backup/authentik/"
endpointURL: "https://s3.ca-central-1.wasabisys.com"
s3Credentials:
accessKeyId:
name: wasabi-secret
key: ACCESS_KEY_ID
secretAccessKey:
name: wasabi-secret
key: ACCESS_SECRET_KEY
retentionPolicy: "10d"

View File

@@ -0,0 +1,69 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: authentik
namespace: authentik
spec:
chart:
spec:
chart: authentik
version: 2025.8.4
sourceRef:
kind: HelmRepository
name: authentik
interval: 15m
releaseName: authentik
values:
authentik:
secret_key: file:///secret-key/key
postgresql:
host: postgres-cluster-rw
user: file:///postgres-creds/username
password: file:///postgres-creds/password
server:
ingress:
enabled: true
ingressClassName: traefik
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
hosts:
- authentik.michaelthomson.dev
tls:
- secretName: authentik-tls
hosts:
- authentik.michaelthomson.dev
volumes:
- name: postgres-creds
secret:
secretName: authentik-postgres-credentials
- name: secret-key
secret:
secretName: authentik-secret-key
volumeMounts:
- name: postgres-creds
mountPath: /postgres-creds
readOnly: true
- name: secret-key
mountPath: /secret-key
readOnly: true
worker:
env:
- name: AUTHENTIK_SECRET_KEY
valueFrom:
secretKeyRef:
name: authentik-secret-key
key: key
volumes:
- name: postgres-creds
secret:
secretName: authentik-postgres-credentials
volumeMounts:
- name: postgres-creds
mountPath: /postgres-creds
readOnly: true
redis:
enabled: true

View File

@@ -1,8 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1 apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository kind: HelmRepository
metadata: metadata:
name: woodpecker name: authentik
namespace: woodpecker namespace: authentik
spec: spec:
interval: 15m interval: 15m
url: https://woodpecker-ci.org/ url: https://charts.goauthentik.io/

View File

@@ -0,0 +1,11 @@
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: scheduled-backup
namespace: authentik
spec:
schedule: "0 0 0 * * *"
backupOwnerReference: self
#immediate: true
cluster:
name: postgres-cluster

View File

@@ -0,0 +1,23 @@
apiVersion: v1
data:
ACCESS_KEY_ID: ENC[AES256_GCM,data:cJS1WkKlhgbWGqgOhFs9xjqriMIyGwaSq2W1tQ==,iv:5qj9+BjOPGvVFg9gIH9128nlOaQ27KMgjlIPIMF51IE=,tag:m80qHYyAbXGt1AGe+cXUuQ==,type:str]
ACCESS_SECRET_KEY: ENC[AES256_GCM,data:E1/lSR0Crdjt/N0BV0d7PgKSn00sKkNd9s4qsknK3MO4W3JSkwE2g4HyJvbjwDEmWZck7dB//WE=,iv:VoLSzFxrdGKKOVVNE8iiQtGS67yJYjknlxz4fs/DDJI=,tag:aPJEsutmqMobr+vXSCJ62g==,type:str]
kind: Secret
metadata:
name: wasabi-secret
namespace: authentik
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEQzVzc1EzaWsvWWlXa2tu
U1NXVFh4TDhuUXZZcXNHVVBBeUR5Y2RvT2pRCnZPL0t5RVMyVzRVeTluYVhZNkJT
ZjF0S2lsUWFvdTdFaXVGZ2NlOHVGUm8KLS0tIGZVR3lUT2ltR0pLUU4yT1BTWTZW
UkZiNmNPbUMvRUs3dDVDNjBnb0htM2cKvsfEiaSE2A5R+pvb0UoaPmvSFMQR2GDi
DBJ+OyMFhz0HxQO31/yrlZGcVxBKq/Q4DXD1zDtWapQ3ds/OBjxHlg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:s9DcnPm61QEc8v+VxeCMYlpbEY5XkgciP1f1Mrprix23FoBJOnLn3sJlCc1Ew6tZE4ilyhr6rK6CJA0Aqsvfro5dS0wQUI1CuDjS4+yx1ANfZzxICYNSIHXVhQiSIQ5g0ANaUVvzaj7pBKA/FvV+BTav2UbdDRUGNVsmZY5NZ5g=,iv:oJ8THhyCaB7+sBwqh9fpLIulKMWTDHdLKSZjMAZFDxo=,tag:IhpmqbLYUE9QCS1B28pdZQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: baikal.michaelthomson.dev
namespace: baikal
spec:
endpoints:
- dnsName: baikal.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -4,6 +4,9 @@ metadata:
name: baikal name: baikal
namespace: baikal namespace: baikal
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
@@ -21,4 +24,4 @@ spec:
tls: tls:
- hosts: - hosts:
- baikal.michaelthomson.dev - baikal.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: baikal-tls

View File

@@ -0,0 +1,23 @@
apiVersion: v1
data:
password: ENC[AES256_GCM,data:WJbyXSCQ2qUtXBtv,iv:h3L3BeSaGQqU+nzlunl3BUOk2dei3Ra60IgNP2sCDQg=,tag:BoooixO1SpnvK7Jvxw56cg==,type:str]
user: ENC[AES256_GCM,data:6D78pKeGDJI=,iv:fl2MNa+EZXKwAOjRGglwPGFGMSc+uSfUJ6vn8U5aPvE=,tag:PU179YKHwlEfJ7OLI68nIQ==,type:str]
kind: Secret
metadata:
name: basic-auth
namespace: booklore
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpbmVWT3pRaTFrYXNyLys1
OEZxUTltSUpYaGgySCtzalA3SG9mVktlSzNrClNJNTBibUx4WWFZdDh1UUFXd2pu
ck9kVm1VckgxOVZUYjdTUHB4Uy9meGsKLS0tIHpJbk1yZU1jMzFPM2VZWkFWc21o
N2xLS0svZkd5MS9HRVUvN2MrWUhPK0kKC6SFkfSBu3CQKdt3+g+5JOjRLtwbxZS/
LQzDjeTqTKZHmrgxKwKsU15QtI0B1ie7f544KCuIAjvEeeBZb8AoRg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T17:34:49Z"
mac: ENC[AES256_GCM,data:ZJrymPllZvecBBeMTR1T1FZpHztqpsZ8SVqStshQMSd9Brf0F0KHNr9xd+dTrSuaeqR8rchLZ89hN+7an/JhkFm+4ffXWtdg5m6ES+Lbu6qGf3QczcQ4bssUhL4kuvTdM+7zVwD6XnyGF2G2hvSvJ2L8V364CX0ZOUCX+Cyk7Ss=,iv:GrVHO0vUz0pgloai/4KlCM/eCQSI1eEF59kuPVjG4y0=,tag:AXcIcDSD8DZOxbcrvvHMyQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -0,0 +1,50 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: booklore
namespace: booklore
spec:
chart:
spec:
chart: ./example-chart
sourceRef:
kind: GitRepository
name: booklore
interval: 15m
releaseName: booklore
values:
mariadb:
enabled: true
image:
tag: latest
auth:
database: booklore
username: booklore-user
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
hosts:
- host: booklore.michaelthomson.dev
paths:
- path: "/"
pathType: ImplementationSpecific
tls:
- hosts:
- booklore.michaelthomson.dev
secretName: booklore-tls
# If you want to bring your own persistence (such as a hostPath),
# disable these and do so in extraVolumes/extraVolumeMounts
persistence:
dataVolume:
enabled: true
size: 1Gi
booksVolume:
enabled: true
size: 10Gi

View File

@@ -0,0 +1,10 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: booklore
namespace: booklore
spec:
interval: 15m
url: https://github.com/booklore-app/booklore.git
ref:
branch: develop

View File

@@ -1,10 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: calibre-web-config
namespace: calibre-web
data:
PUID: "1000"
PGID: "1000"
TZ: "America/Toronto"
DOCKER_MODS: "linuxserver/mods:universal-calibre"

View File

@@ -1,38 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: calibre-web
namespace: calibre-web
spec:
selector:
matchLabels:
app: calibre-web
template:
metadata:
labels:
app: calibre-web
spec:
containers:
- name: calibre-web
image: lscr.io/linuxserver/calibre-web:latest
imagePullPolicy: Always
envFrom:
- configMapRef:
name: calibre-web-config
optional: false
ports:
- containerPort: 8083
name: http
protocol: TCP
volumeMounts:
- name: config
mountPath: /config
- mountPath: /books
name: data
volumes:
- name: config
persistentVolumeClaim:
claimName: calibre-web-config
- name: data
persistentVolumeClaim:
claimName: calibre-web-data

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: calibre.michaelthomson.dev
namespace: calibre-web
spec:
endpoints:
- dnsName: calibre.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: calibre-web
namespace: calibre-web
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: calibre.michaelthomson.dev
http:
paths:
- pathType: ImplementationSpecific
path: /
backend:
service:
name: calibre-web
port:
name: http
tls:
- hosts:
- calibre.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: calibre-web-config
namespace: calibre-web
spec:
resources:
requests:
storage: 4Gi
storageClassName: longhorn
accessModes:
- ReadWriteOnce

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: calibre-web-data
namespace: calibre-web
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 8Gi

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: calibre-web
namespace: calibre-web
spec:
selector:
app: calibre-web
ports:
- port: 80
targetPort: http
name: http

View File

@@ -0,0 +1,23 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: actions
namespace: gitea
spec:
chart:
spec:
chart: actions
version:
sourceRef:
kind: HelmRepository
name: gitea
interval: 15m
releaseName: actions
values:
enabled: true
existingSecret: actions-secret
existingSecretKey: token
giteaRootURL: http://gitea-http:3000
statefulset:
persistence:
size: 1Gi

View File

@@ -0,0 +1,22 @@
apiVersion: v1
data:
token: ENC[AES256_GCM,data:k6dhRoR3XCITRikJStLu1+gkW8Xcrt/EnKtq/LtMOdDOC906nyDbLbLXo4yWkUPb4wOT7/FHtjM=,iv:v/7sYpp//k4NgIHIxrSgUCK0ddTS2knRXt7bv/tK6BQ=,tag:t8yskoe9Q+T1UFhzmdEgSQ==,type:str]
kind: Secret
metadata:
name: actions-secret
namespace: gitea
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYUWxLU2Z5bmJSYUs2YS9q
bFFCSEJlTGtuNEFjVGtsMDFySW5TNnF6RTBzClpMdk9CRU9kTHoyVEJZU1JITnRS
aVhjMm9ndTBXYklkWUpMV0hYNWtrVFkKLS0tIEJLRmF5NVNNamlkSWNjam1lY1pF
MmtSTTJET3VWQStHN25DeDV6aGRrVkkKcMOwuTZY/meJjQZgzmAU37mUS4VjG7H/
q8c+keASqJI511XhWi8K938U8YREge7sDw8sa+RrXpoiy3zyipZOLQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:wr1ngpRm44ueRUsfITsQa9tuWffScHsz66QCfilsc8fO8gprb0eicYAgJ6J7JygGO7hZdnLB4z1Q/5bZFmdsvK2Oz3tV/NX/gZVGbFDqPFHfjDU+5rl7lrBnRh6D1RwvYqJzNL38dDO5oUXTOfDGijS574qB4EpyUnu7+AbJwtE=,iv:7kXdBFzz/M0Kynuk3fmnWWRV7VLN0BXELrYqt/VtQ9s=,tag:FqCzxPTwnL0yBX0+SrWbZA==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -1,15 +1,23 @@
kind: SealedSecret apiVersion: v1
apiVersion: bitnami.com/v1alpha1 data:
password: ENC[AES256_GCM,data:wcJdmRnN4nFOaIiM/Lyp8fceSRKpJW9laUYsZU/9UCmreJP3YHGFdw==,iv:35aJWV/ReimElkgHDEvd1VMi1+fL8ayB2YO5Ej6Iqrs=,tag:Vl665zuBbhsU28zXH+Madw==,type:str]
username: ENC[AES256_GCM,data:vnhGaPemu1i1kpHOPvRg8w==,iv:Ika50tGu/d6m6UxzUpZFhK/SxLsUMmB/GNeeFPmszdU=,tag:wC5CLp+5OhzLKYolmr1aTg==,type:str]
kind: Secret
metadata: metadata:
name: gitea-admin-secret name: admin-secret
namespace: gitea namespace: gitea
creationTimestamp: sops:
spec: age:
template: - recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
metadata: enc: |
name: gitea-admin-secret -----BEGIN AGE ENCRYPTED FILE-----
namespace: gitea YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLMFNmREJGMStuTEhyRi9w
creationTimestamp: OTc4RTlrWWJwNlc2Z3liOXQrd1Jmc0VMQ3hJCjlJMzJDdDYvNWhtUVF6ZlBmR0Nx
encryptedData: RGNrZWlBcnpjSjZLaU95aGZjcXZVNWcKLS0tIHk0UkFnWkxFRHB3THQ1UytRSzdL
password: AgAajDLwVR0AFIKlQLIQU12BIKOu4qYIBIdhTJCPYrA5fj4yZZQBnAukYevTJYf76B0dYR6VzTg3uRVqHm1ve3iM73izGKR3Vab6EuWsXpS+JtqBzPuTuZCL0E+8Q+5JPacn/mOEhk97C1oUv4ZJJgPOPE88ySti+tN0T2UqUp2c1Umys4ZEuRQfESAmgwe08HV30XvkB5EZW68mjzwEry/tYKNLFnon2njNvm3/jObaWDjHeKl0pjFRoyKcTqZHgk92y+jU78ubDQlcsQiP8PRlcHKLxjEexguLYJzZGnTUVMCOMn64FN2H4mW2bBi0Apx/FsrNZQeHf1/WcLTci4ccObnhFi6kjrdZFBc/YBcXviyLrDw+CzUz1ZFSIdGxOHhJm09yJ2YmssuhxeLQ/Y8g6UUSSf2cwcAC4e7gl7EIAayod7wFQySTur7MCuKduV/e50l0OOLYHuB7DwEEhG0LONQ54FF3yrqUhOwn6C3qYPSB10ibbVFuiTreROosIpDoaZ/2TLkjcmHRiRRD7XxXusEjjvd6MH0dCrMc4NM9Dflrf3uZNuuY+tvpAr6bOnOFAN+k7+ttuskuwHmFiuy1UGkFwAs1zMcCStAYdv6+qtwi6+xIAih0XOLV43cQ3R+bZiT8yQZb3wj7oBW6rR6xJ9MpI1fexbedtJWJywfOzdCuopFV9JZWVlXurmPFoSVzEZ7CRvVvRlgS2p2PFsIzpytDW2lvlc9DwBtrrGw= ZTB2WVBmWnZLT3FsekFhSHFkQ1RLNlkKbQfo7CDYk/EadaE6SEmsCZX5ubOTcbD3
username: AgBtjjUFVdKLXE6/+MxXhBjRkUwqg1wAvw5Sl8W8FYYBLV56PzvSl8OqWPcpNwiquvYHZTdv2/vLyVEkk3YuhxYK5SGaIb8Ap4q8OJcdK5xFKKjLCx8kzkJ5Rwa11VfqWOTqwjgrSRgfjRI3Sc9xyrAMkQUgXbI3qdj5WfP6o6YDy6fK0Qm4bTD6F/+qj3xRkonWGY54268xdlHhzNR72Cqu4Wfl6BbiLafEU4U1mrxsSzJlno5LYyCC/g8WkkIrX3JrIYUt3wuTUheA/mhqCuLPH66iW6+lSyKoH2ruUn6p8i5uRltQNI8rYLxa3zdH7Ju3AXlUSv1FHv4zanCsG1SBaWrNsiKCAvEODB2IKGNENpkBkD7Uw51TvqZFoSZyyMbQIZLeCwcaRGtAPPGz2rKG7LcWIBpjy+J7dekmT0M1ObwbjyacluLmt/zw1FBL3JHPBv5RRBVGOmNFztmBobErRcBaOam9jg3SBAdOJfDuAcWOE68CKAUcRJ6wR+dqoP5zOwYtmFva7YRb35gO5XmwbNuCKlsR7ZOl3323aJ3Ill1A329XcPgsB2YmlXXHN9xAtsodDRKnT+t2pxVk1DtRWh+M8Ixy+QlYzhQBdb878G/ZKb5PI67S1RcGU7DROld/9bQBYfIxa2+F3JC+IjUJFVRrHn87BbE16OCPKgOaq+P3n0R8jwwcDDEwSssjVrC3VvcelBsj3aOUvg== lj4rj1v2dYME/wDj9rFp5IwESalXwKzUVzC8e1GuzbY6pDQPx5EW4Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:ApUlG4FA/KYrwm6u/6qNU2Cqz08MxRNmiBmiwCZgNF4aX0CWzRZ9+VbO/jIJUpzKB3W7EdpbiyuT7Ie3h0lwYIZY5xUXP4CDxsZ+TozAFJq/CgXs/BacTZIVhSEL93W+O4ett/UuIL66rtuiZcBY0CdM80j7aTy20ilse8wwusM=,iv:UWdNu4hW6OcMHkqQcrzmLZlU4gevBwAMInbjtC9R3hI=,tag:W+SgpfrOvR9HnGRfnGSgwQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -1,16 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: gitea.michaelthomson.dev
namespace: gitea
spec:
endpoints:
- dnsName: gitea.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "false"

View File

@@ -1,22 +1,22 @@
{ apiVersion: v1
"kind": "SealedSecret", data:
"apiVersion": "bitnami.com/v1alpha1", mailer: ENC[AES256_GCM,data:baGCpPHJejjMFeiBcgSroJWqmUj/8PzvwAdzZ+nLacen2I91iaIRIgztvsk=,iv:6M2+sKRc1ZC5CqY4X43xgGO/CeWOfjMVzNgelYd0V6c=,tag:I15tnxf8CQaLu+/0GNdeOA==,type:str]
"metadata": { kind: Secret
"name": "gitea-mailer-config-secret", metadata:
"namespace": "gitea", name: gitea-mailer-config-secret
"creationTimestamp": null namespace: gitea
}, sops:
"spec": { age:
"template": { - recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
"metadata": { enc: |
"name": "gitea-mailer-config-secret", -----BEGIN AGE ENCRYPTED FILE-----
"namespace": "gitea", YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJMmxwWGZUb2JRK0FHdFd6
"creationTimestamp": null SFN5MGdZR3puUDNhMElTTy96SnVRUzJwYjFvCkJsdlJCRG9zVXdzOEY1REQ4NWRw
}, R05taHVZMlpySXVXWmNIc25VYng4WWsKLS0tIERoL0tUVmUvbG5ha0h0cWIvZDND
"type": "Opaque" NkI0eUlmYjg3Zk9iVmNkZVpXWkh2TW8K/coOzGAPF42522cM6DZVAEEv3LmZaIhu
}, BVyl8ijATNLMIfiFpP5bHpljPHrn3lGP70RzwoCV15t1fC6pjeParA==
"encryptedData": { -----END AGE ENCRYPTED FILE-----
"mailer": "AgDViQgjYRiW3AjnwQZWKauZKoSMmf/LqaOiAZTE1yxULaIE3quXZjm6vkZTtvYqT2eDkKe20O5iTDyBdsO3+29LRnnOm6kF/y4cZ/JOiWfh6nJ0hx6g+MybG3rq4GcWQj7C5OQCi97ctHYemDaWoNKkjwSvNpt+pKcEaBgaqyWQ1knLxP8BaPg51R8CnIe5opn7+AsQwiwi9JX4ucrU46QqLVTg3KT+CobRlEFqtU3jd2CQuj1CN4Y/XgtQFHh3hLB+c05HV6sd0xwo9zMKUSQe2k++5Z5esGj4Hu25UXn36iwmJCfueMor2Y0yOBndPNNviRMMgKjE383retjL1o6n8HkIo5YTrKd18EyuQcq/EdhA8kb3uKX4N1EtOrFLlMGAUKliV42e+3w3IfXtFC9bvTpHivmKIQwZSlPQbF1SVFIbhiBdvNClYJpR61P7ZS6h0D57Tf3vmRpKTSlrHH01sbaKDd9+/kVGUQ0Lk4XRXK0JyTJkNDIiEBuiBB3H/GEZ27k4heBFav6w06gp3zhoOhmhq4XJcFWcselOJeY5cqSUzhLx440zMwwPWvEDH+/nrbhanx6KGFU5Lm6qX7tMn54+P4Ch/vAcnPs/0sXNx0xleGsRVEis+2/EmbdSDwe42+orKxbpQU1bEj7Rqtwiwk4VsTKXgPfzKXcgMMXo+4vvP4t8rCRo1hMkx1EXhKascwntdOb1Nz52QZvij02eNiQhDA2exuG8Room1Ox9Sb4=" lastmodified: "2025-12-17T20:36:08Z"
} mac: ENC[AES256_GCM,data:QBxnUAGg6xchZ9iqKK8gAmdJhDfma5BZlJVRZcfzGM57diuO2OE4JDbjW5gqf21OACL4d2funVlXRVlioLoe0tfZJY3AAedOmyQVXdrr0PwarbPztbWAFVvIMeQWPZUyPd3GxgaAATeBVCanSEgVTIOVqCN/DXNSHY2XcQ9x9Y0=,iv:ugLYt5NxsTIy0wUul748IGIzayG+zPQ/z5kH3T9IfiE=,tag:3yTjZ+MMMVNmi/8p321fFg==,type:str]
} encrypted_regex: ^(data|stringData)$
} version: 3.11.0

View File

@@ -7,12 +7,11 @@ spec:
chart: chart:
spec: spec:
chart: gitea chart: gitea
version: 11.x version: 12.x
sourceRef: sourceRef:
kind: HelmRepository kind: HelmRepository
name: gitea name: gitea
interval: 15m interval: 15m
timeout: 5m
releaseName: gitea releaseName: gitea
values: values:
global: global:
@@ -26,12 +25,15 @@ spec:
port: 2222 port: 2222
clusterIP: clusterIP:
annotations: annotations:
metallb.universe.tf/loadBalancerIPs: 192.168.2.248 metallb.io/loadBalancerIPs: 192.168.18.248
ingress: ingress:
enabled: true enabled: true
className: traefik className: traefik
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "false"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
hosts: hosts:
@@ -42,7 +44,7 @@ spec:
tls: tls:
- hosts: - hosts:
- gitea.michaelthomson.dev - gitea.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: gitea-tls
persistence: persistence:
claimName: gitea-shared-storage claimName: gitea-shared-storage
@@ -53,6 +55,8 @@ spec:
config: config:
server: server:
SSH_PORT: 2222 SSH_PORT: 2222
actions:
ENABLED: true
service: service:
DISABLE_REGISTRATION: true DISABLE_REGISTRATION: true
REGISTER_EMAIL_CONFIRM: true REGISTER_EMAIL_CONFIRM: true
@@ -67,7 +71,7 @@ spec:
SMTP_PORT: 465 SMTP_PORT: 465
USER: gitea@michaelthomson.dev USER: gitea@michaelthomson.dev
admin: admin:
existingSecret: gitea-admin-secret existingSecret: admin-secret
email: "gitea@michaelthomson.dev" email: "gitea@michaelthomson.dev"
additionalConfigSources: additionalConfigSources:
- secret: - secret:

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: hoarder.michaelthomson.dev
namespace: hoarder
spec:
endpoints:
- dnsName: hoarder.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -1,18 +0,0 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: hoarder-secrets
namespace: hoarder
spec:
encryptedData:
MEILI_MASTER_KEY: AgCHcsgG2eNFA8M//KlFEXsD8v+kh9MWiIPr/vWBXqOtoyCoA5vTcrWdQvnmO+ic93kiBy2sTRa2thR2UQd9h3GnC4+MkTGZDLmbiArlE6HltuSWUnqaZESop8NBu8p3mFJ3kX8sLA3RzEZrj4/rmFT3CFym5v6vXjXxGaaT2C0VjsCxeOnGjcEyfm4gaptNP14v43bRRsxZtLo1F/pI1vkMPMbcQPsGXuiIkOxbaMAgGdlybMX1q7ZWWdXEHb/o+RDN2D2c9GJeZDgk/znT1A8IwfAUue1BpF2VamtFxoX2aI2w0xjGeJ7ffUOS3VzuBSAITsw4lb+7gCmC7FByqjxCmoiBI3L20XcFoWMmvNFKqsOPDVduNCJeYAZQHSNfC0SxGIu1tUw1T66NijsItDPH5vjH6BGvWyS3E+YMkxEHMV6ZJWkk3+S0gMRURSEo3Dr/MCby2x6MPbaKFB06u2Vyr0XWRUAXlphzndO0Ibt9P/KVldNX+ZueVxoZkxt+PiJqhWb6ZT8s0VBPmWleufbyjkZoa00KVM4/IGrSBJdLboGGmHU1p1EZGzpMEexCp/G0iEuNqkLJo8cCRxrHH6zsVunIpXnTYg+6Ob032+LDGGG2jKGKsjAlKKod/TIpL15poZZoVIv57IkLYd6bYASDQ9M4NpSJ3gyyIe+jICHBGFQ4t/mBfzlfy4fpjpFRxGNOQhr6TNBIgda9QI17OTkNDyace9Ltqu6CUIDvgOUYUH/gTBfYFtSk0NZWPJdJ+aA=
NEXT_PUBLIC_SECRET: AgB3LRSR+Y/VbTXIHpqlMUR1ec3LXdsghJ8vmMGEB+674W+x36ciekTkv8fGPj+XJXnXgPqCMrAr/Wd6ExrkW/nI2ZxDvbYLQ4POW34b5vF8IV0KD2kARUz5UGmVJOsCRSdlqqEsED72U2Cotw8voYOpEk7GfWZPTAyg6iv6pJyIa3gXEtdKV4k8XOQmMvdAui/0iAoTOeMpP6Qe2hGqCvSCtrsw+aj+ptUlQkP9pOQW6Uo/XMebwwZVSkgFOr6pEPhr70qMbi31ERR1at/vNYArQy8PXmUxJGsRF5KgjD+Nq6rrZPXJFjEk6qx+MAcysJ6rCJeYiCmZMZHabZ9CrhFTVdwtSO2su6B19hXS7fACzIrFNr5Z23NAn6+SoDodXo+Bqa+1ldHFzZl9ve0eoHEB8sG1qVvA5wWMtPm4D2mxd0UTlK0/EqY1jP+EvWNC05v/uD4toIEX3HEZCqdPqghmWxwq8qCm3ZpYvmxQwZxWHZdpxIen262vMZ6s5yZVC/n/v2EVmswqllUBvBCHq6WBBZqF5tgYBsuwy4qf976HMGvXXVx/WcE92eA3iT1olUnFJ7I4Isdp28tFl8jv5JLHJJozzWI91iwPUAwT5xFXi/2Jtk9Oe7QNjsEpYqnxxbogbMS6UZL4TJ1QNsyY29iue+E9q2Eck9Btb8xDtpSH2FNKNo/3FNcbe6hNXdwEbqoGIcNPZNNGDMOFVq6EeTmyxxR3CZYahHt65BXO0K/Smv8n4NSwI0e5T7Hn4S5o8JM=
NEXTAUTH_SECRET: AgChzv5iFZC4pFksnh7blvLWRn/2VsCqjOqkRnFQFTApAKf6CyfUgkFy5yBgbwqtS4oak6jtadtVZQuiWXrY2bIRvROwL4AEqGvteUhURSL7Hy/3oRd6BoBiT/zoiTkBmZRBG1LsI6KjCWXvjKAQGsoJ6sPQOGVGZ2eb57ne51op7xrhAyWbCuuy5tw237Qb/DnTgqeIQ4SmgTytLd5jO6nZ1yhzpmUW6ynu8TLy3ar3vIecc7IQkS7mmnXJgGilUrNUkdNjFdxkALBPah4a0qgwaRrZVh0MLa4Kvud5iYEC6Y5YFxZ2/6pH/OA0+aEw4gWdENyxDRVmxkwHpN22Ya1svvEI1V3RD7RQFA4psLClly3bJDpE96NIS0gSbpGzo2xszf3iKX5U5WjnGEODg9udQ+/RZvluU1NjwkPP5wFpAZU1YC5w2OUtZH/tQQ0Lumn1YsgXeH/oEtXfMgSTWD0Yoxwv7r+bFPb03OUllTG8AFVrP0Uigz9sl/td1u9zvrPFQMNPITSUOFrMbnVA0riKVGqFkkfxSp93lRpKHx7sA7LWyrZfYdcEGsaxMdBWGUcuv4OCtCHQhuyuxkJc7/Dygg3roxPyaehU/j5fY962qnRtv2Okmpf1Lm9VvuB83+ZhnJJNFgWVh6rPUgA+v0rVKOpzSYHpP878EMf3wz08wghhFmhlBSimAftMa8B9zSBkzlqfm6ByrtUNsKSuPE3k1H4YjusxRKFu4DXgo0eiZWmVQWb+YzhS4/zp5aJU3lA=
OPENAI_API_KEY: AgDISqGkHBSMNAmZa5uXoE2DAPy0FbxoZB1ngYRVGbQWN6LxW/3u+O+qtggo1qd+yaPTXJTi5DST22CNLZfk+pdYtMsTb3lQrEM0BkiACDsppOah9pz675xdZrAZG1+BlwGDfyRyKmww6t12D01MEl5g5dgXSA5ZHzPkhR4BySWzbVTN5oF3Yj/7twDkE8ignpdD0lIzPEqoOjdgeQ7g1cUAOTjbj9Q46S75kIaXhzIRnForZi3wbnhFn8pzcuNMERYfxms4u2x5cfUHyRTjblsS7KRIN2ymtsVauCdpmbe6bf3q7WCZ1XE7HcHdDpDK5N0kZRSHVMQUTp3kGripMiBb5aAfYOQBm+6Rjd0OE49dwEfgOV/zecOPZeTp70xwS3RhjioJlVRzHUIYZ9PRjt0gLqEULAQzF8E0FoQcwcjCxtEqTwLHNcVJ3xUBrt/Oq4yTgKspuu+Mb45UUlxyfZUaXrMZp73OE5qFVeUUjGRze6iQ2Hd5znOWH7BUqN+esEzqIyzhhREBSdyKmGdV33eYLcFrnaQkClilf5xeIbKjfA3QLl/3gtdteU3IiYd0PPNXPQr7aYK1buDsLExDo1M9tZM19eypLphStnOtXxtdHFua0jit6Cr7tVFRSF1gJYmtrLpcK5q5bnAt1KCZ2DBQCMgSQhOd1v9t0DQB7dbqgm5+44OJRZDOyhgE03qG57tdsTgr6ufL3Q+wfbo60VVl6JnR+MqgDbTrXvwzWyt5junDDL/FI/MLE9HAH7y5UDCyoHALEAhecE6FF+H34g5NHxQKxHTb6Id5uBdGcSTPDmJO+hwHwTvvSQUQPknGQzFURRw9cLTk+IeTjCfrQE1mIYnk9M5aa0CHWSALB8eXovWUiY1o7A3WYZkIFIz4+bcIws1ihd0M/vGr/cnczDZR5WeIqg==
template:
metadata:
creationTimestamp: null
name: hoarder-secrets
namespace: hoarder

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: ha.michaelthomson.dev
namespace: homeassistant
spec:
endpoints:
- dnsName: ha.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -4,6 +4,7 @@ metadata:
name: homeassistant name: homeassistant
namespace: homeassistant namespace: homeassistant
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
@@ -21,4 +22,4 @@ spec:
tls: tls:
- hosts: - hosts:
- ha.michaelthomson.dev - ha.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: homeassistant-tls

View File

@@ -3,9 +3,12 @@ kind: Cluster
metadata: metadata:
name: immich-postgres name: immich-postgres
namespace: immich namespace: immich
annotations:
# needed to allow for recovery from same name cluster backup
cnpg.io/skipEmptyWalArchiveCheck: enabled
spec: spec:
imageName: ghcr.io/tensorchord/cloudnative-vectorchord:17-0.3.0 imageName: ghcr.io/tensorchord/cloudnative-vectorchord:17-0.3.0
instances: 1 instances: 2
postgresql: postgresql:
shared_preload_libraries: shared_preload_libraries:
@@ -18,15 +21,44 @@ spec:
login: true login: true
bootstrap: bootstrap:
initdb: # initdb:
database: immich # database: immich
owner: immich # owner: immich
secret: # secret:
name: immich-postgres-user # name: immich-postgres-user
postInitSQL: # postInitSQL:
- CREATE EXTENSION IF NOT EXISTS "vchord" CASCADE; # - CREATE EXTENSION IF NOT EXISTS "vchord" CASCADE;
- CREATE EXTENSION IF NOT EXISTS "earthdistance" CASCADE; # - CREATE EXTENSION IF NOT EXISTS "earthdistance" CASCADE;
# NOTE: uncomment this and commend the above initdb when recovering
recovery:
source: immich-postgres
storage: storage:
size: 8Gi size: 8Gi
storageClass: longhorn storageClass: longhorn-pg
externalClusters:
- name: immich-postgres
barmanObjectStore:
destinationPath: "s3://mthomson-cnpg-backup/immich/"
endpointURL: "https://s3.ca-central-1.wasabisys.com"
s3Credentials:
accessKeyId:
name: wasabi-secret
key: ACCESS_KEY_ID
secretAccessKey:
name: wasabi-secret
key: ACCESS_SECRET_KEY
backup:
barmanObjectStore:
destinationPath: "s3://mthomson-cnpg-backup/immich/"
endpointURL: "https://s3.ca-central-1.wasabisys.com"
s3Credentials:
accessKeyId:
name: wasabi-secret
key: ACCESS_KEY_ID
secretAccessKey:
name: wasabi-secret
key: ACCESS_SECRET_KEY
retentionPolicy: "10d"

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: immich.michaelthomson.dev
namespace: immich
spec:
endpoints:
- dnsName: immich.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -0,0 +1,11 @@
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: immich-postgres
namespace: immich
spec:
selector:
matchLabels:
cnpg.io/cluster: immich-postgres
podMetricsEndpoints:
- port: metrics

View File

@@ -12,23 +12,26 @@ spec:
kind: HelmRepository kind: HelmRepository
name: immich name: immich
interval: 15m interval: 15m
timeout: 5m
releaseName: immich releaseName: immich
values: values:
env: controllers:
DB_HOSTNAME: "immich-postgres-rw" main:
DB_USERNAME: "immich" containers:
DB_DATABASE_NAME: "immich" main:
DB_PASSWORD: "immich" image:
image: tag: v2.1.0
tag: v1.134.0 env:
DB_HOSTNAME: "immich-postgres-rw"
DB_USERNAME: "immich"
DB_DATABASE_NAME: "immich"
DB_PASSWORD: "immich"
immich: immich:
persistence: persistence:
library: library:
existingClaim: immich-data existingClaim: immich-data
redis: valkey:
enabled: true enabled: true
server: server:
@@ -37,6 +40,9 @@ spec:
main: main:
enabled: true enabled: true
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
hosts: hosts:
@@ -46,7 +52,7 @@ spec:
tls: tls:
- hosts: - hosts:
- immich.michaelthomson.dev - immich.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: immich-tls
machine-learning: machine-learning:
enabled: true enabled: true

View File

@@ -0,0 +1,11 @@
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: scheduled-backup
namespace: immich
spec:
schedule: "0 0 0 * * *"
backupOwnerReference: self
#immediate: true
cluster:
name: immich-postgres

View File

@@ -0,0 +1,23 @@
apiVersion: v1
data:
ACCESS_KEY_ID: ENC[AES256_GCM,data:ad1Xc2tUS5JCGiaOoL5udd058QxG592R7a+66A==,iv:erHAPm5E5w2B0fZ/sagwTsT16MTLnbYzmamT9OS3fEE=,tag:TMRosj0L+u3JL3o6ig0/rw==,type:str]
ACCESS_SECRET_KEY: ENC[AES256_GCM,data:QJ3RkLWP8QNPt+JoD1B3ZCQkZKH82ImgnR8ZgfPPnEDFYj2rRuTbZva33yL/wAz95ll8YbjxtQw=,iv:cO96syX0ZdukwhKvvtrTzQcy0qQGEiL3NSxigcop+EQ=,tag:JS9sT+iFgdFMkTM74ore2w==,type:str]
kind: Secret
metadata:
name: wasabi-secret
namespace: immich
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPa1lwSXVIM0ZRa1NhZ3lv
U05sZi9WbkVidVVDYVdXWWNZejRHNW9MNUF3CkNFVjc2bjFUZXhuQzAxUDBDVGxi
VGpZcHdZMHVWVW40NDRvY2RURFJ5OEUKLS0tIGlwRmNTZi9WWEhuWnB5TW1leVZt
eWpOMDdyakJEcWxYaFZiZ05nbCtWU00KmfoVxNBH7N44v/Xxcmjw/D/YQ93DA7yU
6/kk/7R2ya2JWtuqkOx9QPU8/TKaucU5V/IxPhoWquytevHkL5QhUw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:1iNzgy+OKP7tZXkiMLr/9oFLjLnEEKAkQdzceFkGUYiq7gHmujuplt9vU2JS+Kc7l5m9FyB7cFOjHpJec08owJf7gDXcHBkUQmGGIU6eso/n/G5lj2bDKoQgrZcS3+cgpDGY/oiFh34ZapSL1uEbgQudRWsfQZr7o8iHLGEir4s=,iv:md9IZ9n2ecQDnBHIkBGZHhc34uIi9aWzbsDbZo2hx/U=,tag:U3m6q5TfHiii7cGPsK0MOw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -2,7 +2,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: chrome name: chrome
namespace: hoarder namespace: karakeep
spec: spec:
replicas: 1 replicas: 1
selector: selector:

View File

@@ -2,7 +2,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: chrome name: chrome
namespace: hoarder namespace: karakeep
spec: spec:
selector: selector:
app: chrome app: chrome

View File

@@ -2,7 +2,7 @@ apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: data-pvc name: data-pvc
namespace: hoarder namespace: karakeep
spec: spec:
accessModes: accessModes:
- ReadWriteOnce - ReadWriteOnce

View File

@@ -1,14 +1,17 @@
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
name: hoarder-web-ingress name: karakeep-web-ingress
namespace: hoarder namespace: karakeep
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
rules: rules:
- host: "hoarder.michaelthomson.dev" - host: "karakeep.michaelthomson.dev"
http: http:
paths: paths:
- path: "/" - path: "/"
@@ -20,5 +23,5 @@ spec:
number: 3000 number: 3000
tls: tls:
- hosts: - hosts:
- hoarder.michaelthomson.dev - karakeep.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: karakeep-web-ingress-tls

View File

@@ -0,0 +1,30 @@
apiVersion: v1
data:
MEILI_MASTER_KEY: ENC[AES256_GCM,data:hGTazo5p3b+k9c1FsCzV8lkCKFqEv/pXbAF0FqnYK0euPusL20skBIBP/hZQCllL9ZIpHuHAK8ZA57TMrnBtBA==,iv:E/1DsMVmQ6r3IgF0g4UBvW0rLTUmc4OOBx7FJh0/fP8=,tag:I9NzdG8hkndQEEa+RwHGJA==,type:str]
NEXT_PUBLIC_SECRET: ENC[AES256_GCM,data:x0lLGcfMX4o76y+wpSUh4oTh4bm0CIw8+epVX3uO8BpN79xYFLMV3EzbUOi4Isldb0zdPzK6xlnF7tqCvTDY9Wq/SUs=,iv:vIfucp8BM9FaXUtoUUTXCQuRWTngFokKFpIwhA/IpXI=,tag:RykRRY1q2iV9zqe3rvxSkA==,type:str]
NEXTAUTH_SECRET: ENC[AES256_GCM,data:Z9GlM3phYB9WtU2K2HH9oAU7F7xZP48IsbK1JrwE72GZP53MiZmGDzTTzU/aP9DfG71PWqEgCPC56bQFr7UtvQ==,iv:SNNpv6J44Q4hxRvgzNNgt7NMUAoNMDAy3Ff7jrFAimQ=,tag:kvp3H+DgVAtXMwKzIPTJRA==,type:str]
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING: ENC[AES256_GCM,data:qQAQg6sCJO0=,iv:EqNG67j5uII6+TBnMY9wt6E1jq52vevccfs+pmn4zs8=,tag:UP2omHyj5qCw/jIErW8GVw==,type:str]
OAUTH_CLIENT_ID: ENC[AES256_GCM,data:IK87xFx5N0he669UzhYLeFbpfAcZB039p8bgw+6AGDi17MIRBmoQkVJ1bvnGM+EaG7A7ezdrEQk=,iv:OG2HE2ubV/2ZIllyKIFnA7nRNEZfCoyh7AX+M8rLqtk=,tag:uCf8YI9RymbjLzVR2h/btQ==,type:str]
OAUTH_CLIENT_SECRET: ENC[AES256_GCM,data:OA6t3SU4uhD3AXFYxk06dhYdQhESr2LaWJ58jTGDCIGS2hIb6Sx7tS1nlDK/7G2LB8IZbRDfLSXc+DoYlQ/WwIlFSi9gDbiBYpk0ZYtfuo0hapc0MMCOpdvh7nc9d1p5/tMkX/ZbO0N2BHSBVbtwWaXntDDUd5YJxRubE6pnN3jKRbqY6BGfSdWytf47n8SEK6O2NWIgxnvlkKPLX0H/iKOxaTKHpasyEVv9xw==,iv:31nVzU3o4TuIGlH35oD5PRXbWWIX8FZ2u0OnYorM7sY=,tag:5Y8YFbt28UPDKr7EVJjApQ==,type:str]
OAUTH_PROVIDER_NAME: ENC[AES256_GCM,data:lcMWx1XJ/86FVyB4,iv:jVH7sDJo7Gag+hWNbUf9FC+jGqjts7liXomeOeW0eJ0=,tag:ISkJ2s/ZMOdLsxKh1Iauqg==,type:str]
OAUTH_WELLKNOWN_URL: ENC[AES256_GCM,data:/29zd+yLKKPQs9KfYCDOOPLqpay3Hd/+6YE3NcufDCiBCGEzHE9YtqrwyYGhq/Z3RPBNB85aYgCZbEVVgTezOvMGeoOUWzrQirD0ZF7JYPQt+jbpLRKMgsD9YF9iySRCPickdp17Hh6ukwhPfcf1ucT5tT9sjXm6JVFJFg==,iv:hzF9F9btpP/7Add/g/E0RlPDO5npIbVaj0JoJ0Na/SA=,tag:c2rigTpq0vtct4FCIBPE6Q==,type:str]
OPENAI_API_KEY: ENC[AES256_GCM,data:am/9P6389pS9IrxX2oAiMP5NawG8oj77rY8mgfJCjaXfGOPARIGtOSkmFVyY1oQR51oi3jDAg++JR72IW5k1NFkQp9JehMZeNXgLIc3aBIVIjJ+8G+q4AZ63TJrPAnDd+XiXf0aOAyyMzwmRY/j9Gu4cZXGxvqdz5HAmQMwcBfpWRXpEA1+YnDea2YhXW796JHI6WPBD4dzFMUZ1q5PGWwMOsAi6ArIXTN30EK1AqM8EIlK5quubbRxbJCI16DGDzIbXnuLB7MW8mvzm93Yz1Q39Q01reO3XZbihLw==,iv:G9XIKNcqUIizhgzj0POi0tQ/nHOne3DLeDtRaP0lXUg=,tag:o1zZ8ZoYbQZad3ciV9lqjg==,type:str]
kind: Secret
metadata:
name: karakeep-secrets
namespace: karakeep
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAreXJUVW5FVUsrc2k0RUk0
ZkZRS3pZUXFaTUdManhKVWp1S0JiaHRQV200CjVUYlAwN09TelNsK1l4aTQzSEF0
SFVkQnUwaFAvbGN5Z0dVTVdMdmRXR1kKLS0tIEk4S2FINWU1ZmtSYWFsVm94UTVS
RTBKZEtZMUhLMEFlejNEek5iL0J5Q28Kk07rkAd/qNVyS40Iz7yfSJMpa2pGtvrj
0YBKgyDoKmQ1aNzPo5aiaKyaUdh1PYrkAI7q5J+rmXj/70DR662nSA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:4gHyTL/1DH/s4S/GdQOS7THzXNwo0xvMGdUqtEwgsjTSnoEZQMiUFLGOSnCy3LVG6JiPvCrJKDRrralrdaoSSWcmwy3pA/EG2eS58ooa02Hum2DgJ9XO25ZNSj16/gGJwgnEscGHSsAjRA3guAPAIbGip6DrhJJ3EfgVXT+J0OI=,iv:gV6QwYfTXiz4bfJNmW5yiZflspI3zULTEtVsWxirjvE=,tag:388de9lUv88lH3JoGsnlug==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -2,7 +2,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: meilisearch name: meilisearch
namespace: hoarder namespace: karakeep
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@@ -24,7 +24,7 @@ spec:
name: meilisearch name: meilisearch
envFrom: envFrom:
- secretRef: - secretRef:
name: hoarder-secrets name: karakeep-secrets
volumes: volumes:
- name: meilisearch - name: meilisearch
persistentVolumeClaim: persistentVolumeClaim:

View File

@@ -2,7 +2,7 @@ apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: meilisearch-pvc name: meilisearch-pvc
namespace: hoarder namespace: karakeep
spec: spec:
accessModes: accessModes:
- ReadWriteOnce - ReadWriteOnce

View File

@@ -2,7 +2,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: meilisearch name: meilisearch
namespace: hoarder namespace: karakeep
spec: spec:
selector: selector:
app: meilisearch app: meilisearch

View File

@@ -2,24 +2,26 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: web name: web
namespace: hoarder namespace: karakeep
spec: spec:
replicas: 1 replicas: 1
selector: selector:
matchLabels: matchLabels:
app: hoarder-web app: karakeep-web
template: template:
metadata: metadata:
labels: labels:
app: hoarder-web app: karakeep-web
spec: spec:
containers: containers:
- name: web - name: web
image: ghcr.io/hoarder-app/hoarder:release image: ghcr.io/karakeep-app/karakeep
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- containerPort: 3000 - containerPort: 3000
env: env:
- name: NEXTAUTH_URL
value: https://karakeep.michaelthomson.dev
- name: MEILI_ADDR - name: MEILI_ADDR
value: http://meilisearch:7700 value: http://meilisearch:7700
- name: BROWSER_WEB_URL - name: BROWSER_WEB_URL
@@ -27,13 +29,13 @@ spec:
- name: DATA_DIR - name: DATA_DIR
value: /data value: /data
- name: DISABLE_SIGNUPS - name: DISABLE_SIGNUPS
value: "true" value: "false"
volumeMounts: volumeMounts:
- mountPath: /data - mountPath: /data
name: data name: data
envFrom: envFrom:
- secretRef: - secretRef:
name: hoarder-secrets name: karakeep-secrets
volumes: volumes:
- name: data - name: data
persistentVolumeClaim: persistentVolumeClaim:

View File

@@ -2,10 +2,10 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: web name: web
namespace: hoarder namespace: karakeep
spec: spec:
selector: selector:
app: hoarder-web app: karakeep-web
ports: ports:
- protocol: TCP - protocol: TCP
port: 3000 port: 3000

View File

@@ -0,0 +1,23 @@
apiVersion: v1
data:
admin-password: ENC[AES256_GCM,data:FXusij+QSZCfG5Cp1VFTsDXmzYc=,iv:KuscQB1tHeTY4d7EPEozOO9FqlhBwZL2hNix7gGpu6s=,tag:wX7us8uCsHlfudM6sx/vAw==,type:str]
admin-user: ENC[AES256_GCM,data:aOqM1iNeX30=,iv:iwxNPSNsrxEr7zTmKRWmLK3BNu5UIj055l1p3I24xKo=,tag:eUfhUyD8vHh8YKFZpAX2ww==,type:str]
kind: Secret
metadata:
name: admin-secret
namespace: kube-prometheus-stack
sops:
age:
- recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyU2FJWjVseDY5ZGlJd2xs
OHBPQUpiS1ZocTZVeWVOVFdEaGt3dkN4OFFJCmd4M1lYbGYzelNhaDl0Tm5IUGww
OVc3M2Z5U3JGYVpuV21UQnJlZzM3Nk0KLS0tIDlma0J4amZKYWo4enpMdTI1YUZJ
aXBLVnBtMFpLc3B3djdzZDBiWXhwdmMKSlkc7MFkV6lDJ0J+k2GdIlpbNa438bre
2QOOgd3QeomniAmM0pemCR9PIVA3Uf+3DhMs1foZ6uYugJMMsd6esQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-19T20:36:08Z"
mac: ENC[AES256_GCM,data:KocjA27Zp0Y/DVemOVvjOATT7QIQjydpJIYQpjr1UnB8l748E+VGkvra2vLyV11BQz3uLija/2v0WNmQs5f+ZLvoTuQro6l9HxSk4zkkgfMzkqzlWIVFsj2Z0SrNtLl+bQMkDeOuMeeB+hAtOtwoc04X9n78PIW+2SGsq2Z94Co=,iv:KfRKGFC0geEburKxnXJJJqZUmVXhET2WnEON+gxlQp8=,tag:cTnOwHZNcP3Z5aCvF+IS3Q==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: grafana.michaelthomson.dev
namespace: kube-prometheus-stack
spec:
endpoints:
- dnsName: grafana.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: prometheus.michaelthomson.dev
namespace: kube-prometheus-stack
spec:
endpoints:
- dnsName: prometheus.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -7,37 +7,47 @@ spec:
chart: chart:
spec: spec:
chart: kube-prometheus-stack chart: kube-prometheus-stack
version: 63.x version: 79.x
sourceRef: sourceRef:
kind: HelmRepository kind: HelmRepository
name: prometheus-community name: prometheus-community
interval: 15m interval: 15m
timeout: 5m
releaseName: kube-prometheus-stack releaseName: kube-prometheus-stack
values: values:
grafana: grafana:
admin:
existingSecret: admin-secret
userKey: admin-user
passwordKey: admin-password
ingress: ingress:
enabled: true enabled: true
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
hosts: hosts:
- grafana.michaelthomson.dev - grafana.michaelthomson.dev
path: / path: /
tls: tls:
- secretName: letsencrypt-wildcard-cert-michaelthomson.dev - secretName: grafana-tls
hosts: hosts:
- grafana.michaelthomson.dev - grafana.michaelthomson.dev
prometheus: prometheus:
prometheusSpec:
podMonitorSelectorNilUsesHelmValues: false
ruleSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
probeSelectorNilUsesHelmValues: false
ingress: ingress:
enabled: true enabled: true
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
hosts: hosts:
- prometheus.michaelthomson.dev - prometheus.michaelthomson.dev
path: / path: /
tls: tls:
- secretName: letsencrypt-wildcard-cert-michaelthomson.dev - secretName: prometheus-tls
hosts: hosts:
- prometheus.michaelthomson.dev - prometheus.michaelthomson.dev

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: bazarr.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: bazarr.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -4,6 +4,7 @@ metadata:
name: bazarr name: bazarr
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
# traefik.ingress.kubernetes.io/router.middlewares: authentik-bazarr@kubernetescrd # traefik.ingress.kubernetes.io/router.middlewares: authentik-bazarr@kubernetescrd
@@ -22,4 +23,4 @@ spec:
tls: tls:
- hosts: - hosts:
- bazarr.michaelthomson.dev - bazarr.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: bazarr-tls

View File

@@ -1,8 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: jellyfin-config
namespace: media
data:
NVIDIA_VISIBLE_DEVICES: all
NVIDIA_DRIVER_CAPABILITIES: all

View File

@@ -12,7 +12,6 @@ spec:
labels: labels:
app: jellyfin app: jellyfin
spec: spec:
runtimeClassName: nvidia
containers: containers:
- name: jellyfin - name: jellyfin
image: lscr.io/linuxserver/jellyfin:latest image: lscr.io/linuxserver/jellyfin:latest
@@ -29,16 +28,12 @@ spec:
- mountPath: /data/media - mountPath: /data/media
name: data name: data
subPath: media subPath: media
# - name: dev-dri - name: transcode
# mountPath: /dev/dri mountPath: /transcode
env: - name: cache
- name: NVIDIA_VISIBLE_DEVICES mountPath: /cache
value: all - name: dev-dri
- name: NVIDIA_DRIVER_CAPABILITIES mountPath: /dev/dri
value: all
resources:
limits:
nvidia.com/gpu: 1
volumes: volumes:
- name: config - name: config
persistentVolumeClaim: persistentVolumeClaim:
@@ -46,6 +41,13 @@ spec:
- name: data - name: data
persistentVolumeClaim: persistentVolumeClaim:
claimName: media-data claimName: media-data
# - name: dev-dri - name: transcode
# hostPath: emptyDir:
# path: /dev/dri sizeLimit: 50Gi
- name: cache
emptyDir:
medium: Memory
sizeLimit: 2Gi
- name: dev-dri
hostPath:
path: /dev/dri

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: jellyfin.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: jellyfin.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -4,6 +4,9 @@ metadata:
name: jellyfin name: jellyfin
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
@@ -21,4 +24,4 @@ spec:
tls: tls:
- hosts: - hosts:
- jellyfin.michaelthomson.dev - jellyfin.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: jellyfin-tls

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: jellyseerr.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: jellyseerr.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -4,6 +4,9 @@ metadata:
name: jellyseerr name: jellyseerr
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
@@ -21,4 +24,4 @@ spec:
tls: tls:
- hosts: - hosts:
- jellyseerr.michaelthomson.dev - jellyseerr.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: jellyseerr-tls

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: prowlarr.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: prowlarr.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -4,6 +4,7 @@ metadata:
name: prowlarr name: prowlarr
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
# traefik.ingress.kubernetes.io/router.middlewares: authentik-prowlarr@kubernetescrd # traefik.ingress.kubernetes.io/router.middlewares: authentik-prowlarr@kubernetescrd
@@ -22,4 +23,4 @@ spec:
tls: tls:
- hosts: - hosts:
- prowlarr.michaelthomson.dev - prowlarr.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: prowlarr-tls

View File

@@ -1,69 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: qbittorrent
namespace: media
spec:
selector:
matchLabels:
app: qbittorrent
template:
metadata:
labels:
app: qbittorrent
spec:
securityContext:
sysctls:
- name: net.ipv4.conf.all.src_valid_mark
value: "1"
containers:
- name: qbittorrent
image: lscr.io/linuxserver/qbittorrent:libtorrentv1
envFrom:
- configMapRef:
name: qbittorrent-config
optional: false
ports:
- containerPort: 8080
name: http
protocol: TCP
volumeMounts:
- name: qbittorrent-config
mountPath: /config
- name: data
mountPath: /data/downloads
subPath: downloads
- name: wireguard
image: lscr.io/linuxserver/wireguard:latest
envFrom:
- configMapRef:
name: wireguard-config
securityContext:
capabilities:
add:
- NET_ADMIN
volumeMounts:
- name: wireguard-config-secret
mountPath: /config/wg_confs
- name: wireguard-config
mountPath: /config
- name: natpmp-script
mountPath: /custom-services.d/natpmp.sh
subPath: natpmp.sh
readOnly: true
volumes:
- name: qbittorrent-config
persistentVolumeClaim:
claimName: qbittorrent-config
- name: data
persistentVolumeClaim:
claimName: media-data
- name: wireguard-config
persistentVolumeClaim:
claimName: wireguard-config
- name: wireguard-config-secret
secret:
secretName: wireguard-config-secret
- name: natpmp-script
configMap:
name: natpmp-script

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: qbittorrent.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: qbittorrent.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: qbittorrent
namespace: media
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: qbittorrent.michaelthomson.dev
http:
paths:
- pathType: ImplementationSpecific
path: /
backend:
service:
name: qbittorrent
port:
name: http
tls:
- hosts:
- qbittorrent.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev

View File

@@ -1,35 +0,0 @@
apiVersion: v1
data:
natpmp.sh: |
#!/bin/sh
while true; do
date
natpmpc -a 1 0 udp 60 -g 10.2.0.1 && natpmpc -a 1 0 tcp 60 -g 10.2.0.1 > /tmp/natpmpc_output || {
echo -e "ERROR with natpmpc command \a"
break
}
port=$(grep 'TCP' /tmp/natpmpc_output | grep -o 'Mapped public port [0-9]*' | awk '{print $4}')
currentPort=$(curl -XGET 'http://127.0.0.1:8080/api/v2/app/preferences' | jq '.listen_port')
echo "Opened port: $port"
echo "Current port: $currentPort"
if [ "$currentPort" != "$port" ]; then
echo "Current port is different. Changing from $currentPort to $port"
code=$(curl --write-out '%{http_code}' --silent --output /dev/null -XPOST -d "json={\"listen_port\":$port}" "http://127.0.0.1:8080/api/v2/app/setPreferences")
if [ "$code" != "200" ]; then
echo "ERROR: port change failed with status code $code"
else
echo "Port changed to $port successfully"
fi
fi
sleep 45
done
kind: ConfigMap
metadata:
creationTimestamp: null
name: natpmp-script
namespace: media

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: qbittorrent-config
namespace: media
spec:
resources:
requests:
storage: 1Gi
storageClassName: longhorn
accessModes:
- ReadWriteOnce

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wireguard-config
namespace: media
spec:
resources:
requests:
storage: 1Gi
storageClassName: longhorn
accessModes:
- ReadWriteOnce

View File

@@ -1,8 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: qbittorrent-config
namespace: media
data:
PUID: "1000"
PGID: "1000"

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: qbittorrent
namespace: media
spec:
selector:
app: qbittorrent
ports:
- port: 80
targetPort: http
name: http

View File

@@ -1,21 +0,0 @@
{
"kind": "SealedSecret",
"apiVersion": "bitnami.com/v1alpha1",
"metadata": {
"name": "wireguard-config-secret",
"namespace": "media",
"creationTimestamp": null
},
"spec": {
"template": {
"metadata": {
"name": "wireguard-config-secret",
"namespace": "media",
"creationTimestamp": null
}
},
"encryptedData": {
"wg0.conf": "AgClUxLYCyjV/nHiKlwxkOiGXNIRFe8hRi/6uRJZsyXf5PcUe2bh8ubCPEg+7wmF5r/ZDMbfQnJHwzHFu4fSdSXNbJELMVO4kjyFPsH3f5N2iSBzxBaEeARGHd4ijOsOJvevpw5UW+R+aWnGpY+L09Rcbla5Ak/xRgTfCLaHn+AFC7G5FigvxLLXuJZRYPWvrUSK2P3ZQLc4xGjRHD3xDCrb5gjrzdt3ZqyaMqpufdQRaMnsqY1BqHzqHR11l5MhwK7jb/Ge+aNgRckheKqwlCL2aebSciFzdzr0Ve4oJN0neNiK7P8r0BjRSnHfeyhzmed8DwcTej1xJFt/mX+h8XrUS0i7ioPaUc/t159bPdjZuXdGFPtTGg66nUzKeLm1DOyB+sn80d5M9X4rDe5Poyyff56XxtLd1XCDuuPL9YZDTuETupaLm+57hsnHYIoCe7rmTg0pH5iZzO3p+pwplZMIB/VCDKM1HW6b91Yn1CqGOHfNM3qrrxgppz97G1568cDII+W5F5MZXPCb8ENZGzjm6FVDrHrLiYqAP+j6lTNN0WqNclnsLlcyckzXNpickdMeDRU/rnzNrpT1VDRgaCuU2vnZ91bh9ZcUBfm0aWcNl9wves8FHH+yt4YzKLVXG8Sm4sYRkeqEmrMUwrXbcG0l+b0tunT2QOZHNf5lUgHPjoyfp8ynpFrEsrZF9FH7/tB2Z6whbjYo1LDGunQ0aBCqfx2n4xNAb9urfh/fTxjT28PCGzYp9snCtmfGPcvCtkBy9cJeDiX4AE9PZsFTUzRjZUqRqKg+6QK4fZHkxYzpuzgH3cAsgG97RIcllNLA4fhN66SIAXjSrfVg8XYwXgHeyoRpcwhJ7WhiOaFSCccbXxEUVgzJ7O8KpCpbQlaYWbXbtpptAkBbNzPJ9kF+baOgD6SxbgFdc9V+oSM8sX/FubfK8Spm9fqu0slQaygvZX1ote67WWNK2uy8W82hymYS96g2FWghFnSbYEgrDUO8ASF4zhtPWyTWr45+Ba4WfQ3hZApTW5jJczjAn7w95ySt4gHFRxVmvbV8topVz8jO2V8t//OuRaQMpBLYjQVSGo60vuWIxFcgKqb2UxXiEqRWxhDWkjHx9RX9pCR9St0p6u/WL8Iwemq5a7RIedHQkuKmorOP100zCp4njsuRfN+kodtk0PjtZNJaVdbAVn9TYyY="
}
}
}

View File

@@ -1,12 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: wireguard-config
namespace: media
data:
PUID: "1000"
GUID: "1000"
TZ: America/Toronto
DOCKER_MODS: linuxserver/mods:universal-package-install
INSTALL_PACKAGES: libnatpmp|jq
# DOCKER_MODS: ghcr.io/fusetim/external_natpmp_qbittorrent:ecf567b21e5f079762e36c9cee9afaf86fcb22be

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: radarr.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: radarr.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -4,6 +4,7 @@ metadata:
name: radarr name: radarr
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
# traefik.ingress.kubernetes.io/router.middlewares: authentik-radarr@kubernetescrd # traefik.ingress.kubernetes.io/router.middlewares: authentik-radarr@kubernetescrd
@@ -22,4 +23,4 @@ spec:
tls: tls:
- hosts: - hosts:
- radarr.michaelthomson.dev - radarr.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: radarr-tls

View File

@@ -1,8 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: readarr-config
namespace: media
data:
PUID: "1000"
PGID: "1000"

View File

@@ -1,40 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: readarr
namespace: media
spec:
selector:
matchLabels:
app: readarr
template:
metadata:
labels:
app: readarr
spec:
containers:
- name: readarr
image: lscr.io/linuxserver/readarr:nightly
imagePullPolicy: Always
envFrom:
- configMapRef:
name: readarr-config
optional: false
ports:
- containerPort: 8787
name: http
protocol: TCP
volumeMounts:
- name: config
mountPath: /config
- mountPath: /data
name: data
volumes:
- name: config
persistentVolumeClaim:
claimName: readarr-config
- name: data
persistentVolumeClaim:
claimName: media-data

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: readarr.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: readarr.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: readarr
namespace: media
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: readarr.michaelthomson.dev
http:
paths:
- pathType: ImplementationSpecific
path: /
backend:
service:
name: readarr
port:
name: http
tls:
- hosts:
- readarr.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: sabnzbd.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: sabnzbd.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -4,6 +4,7 @@ metadata:
name: sabnzbd name: sabnzbd
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
@@ -21,4 +22,4 @@ spec:
tls: tls:
- hosts: - hosts:
- sabnzbd.michaelthomson.dev - sabnzbd.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: sabnzbd-tls

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: sonarr.michaelthomson.dev
namespace: media
spec:
endpoints:
- dnsName: sonarr.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

View File

@@ -4,6 +4,7 @@ metadata:
name: sonarr name: sonarr
namespace: media namespace: media
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
# traefik.ingress.kubernetes.io/router.middlewares: authentik-sonarr@kubernetescrd # traefik.ingress.kubernetes.io/router.middlewares: authentik-sonarr@kubernetescrd
@@ -22,4 +23,4 @@ spec:
tls: tls:
- hosts: - hosts:
- sonarr.michaelthomson.dev - sonarr.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: sonarr-tls

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: michaelthomson.dev
namespace: michaelthomson
spec:
endpoints:
- dnsName: michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -4,6 +4,9 @@ metadata:
name: michaelthomson.dev name: michaelthomson.dev
namespace: michaelthomson namespace: michaelthomson
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
spec: spec:
@@ -21,4 +24,4 @@ spec:
tls: tls:
- hosts: - hosts:
- michaelthomson.dev - michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: michaelthomson-tls

View File

@@ -0,0 +1,50 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: minecraft
namespace: minecraft
spec:
chart:
spec:
chart: minecraft
version: 5.x
sourceRef:
kind: HelmRepository
name: minecraft
interval: 15m
releaseName: minecraft
values:
serviceAnnotations:
metallb.io/loadBalancerIPs: 192.168.18.201
minecraftServer:
# This must be overridden, since we can't accept this for the user.
eula: true
# One of: LATEST, SNAPSHOT, or a specific version (ie: "1.7.9").
version: "LATEST"
## The type of Minecraft server to run, check for related settings below
## Common types: "VANILLA", "FABRIC", "FORGE", "SPIGOT", "BUKKIT", "PAPER",
## "FTBA", "SPONGEVANILLA", "AUTO_CURSEFORGE"
## ref: https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms
type: "VANILLA"
# One of: peaceful, easy, normal, and hard
difficulty: normal
# A comma-separated list of player names to whitelist.
whitelist: DrDeww,lolobinbolo
# A comma-separated list of player names who should be admins.
ops: DrDeww
# A server icon URL for server listings. Auto-scaled and transcoded.
icon:
# Message of the Day
motd: "Welcome to Michael's Minecraft Server"
worldSaveName: world
# If you adjust this, you may need to adjust resources.requests above to match.
memory: 1024M
serviceType: LoadBalancer
persistence:
dataDir:
enabled: true
Size: 8Gi
accessModes:
- ReadWriteOnce

View File

@@ -0,0 +1,9 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: minecraft
namespace: minecraft
spec:
interval: 15m
url: https://itzg.github.io/minecraft-server-charts/

View File

@@ -1,16 +1,23 @@
--- apiVersion: v1
apiVersion: bitnami.com/v1alpha1 data:
kind: SealedSecret password: ENC[AES256_GCM,data:jFpz9bSZvldMHrXZWPEFLCZk+WU=,iv:Gr01uTyy1LLodCrr+e+QPCaosA0ad9qg+51vxQKu7nM=,tag:mQC7HYeycSdnVi8QXKgqhA==,type:str]
username: ENC[AES256_GCM,data:ODJU7cK+lrQ=,iv:biwQxLX4xjZMVWF2phEuOrR0s+oWoiTw6at1YlLIdGU=,tag:oA3/NPM/tFJBfclJDJUP6A==,type:str]
kind: Secret
metadata: metadata:
creationTimestamp: null name: collabora-secret
name: collabora-secret namespace: nextcloud
namespace: nextcloud sops:
spec: age:
encryptedData: - recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
password: AgBgaJPlIiKl7lAZDAF50rM+BQdpb+wH8W19Eu5nh6U7G8kxI5s1FsSlBVUQKuBwcPQQT1WUOI2G3JgMNuuqvQ8afPsikL2f+YUo7iuLAaopToY8bHQK4WCjEtDy3U1w3p8hVLsJzFiV8+2Inot4N5GtQCFkHoeqnUgOpYOrbqtx6ZFJNZDt9xxi1szfdk7rjAzaiOLUwfzggtkralYGKdFQMd3V5xlMm126UNjA9PH65NWKOshlA07gsyc+iyk2/ICcO85Q5N1Q+zlui3kYRc2Y8uPLkKM4XV+ms9X27w10dsiRkjShU93sNQtGEYJSKCwLS/BQecQyej9JH/Lj4sy2fSXjKWMgbHp3Nmck7cHTUnrs/CKG/Isl2B2dnKB0zgHlXScCxgVw9KR0xxjcoOXTLO8nap9H/uOOu8cwCoBAWHkl5YNxgnK/UCEd1oenbabE8QqSX3RKp3Cp+ewWIHf3VhC/XI9LZrv/6rRLveZRUMBHQPVCI7okCAujfUKwYIPA2bNFrMypqiwhSyve8WwvtiXS6BPXEef2q/gKOy8s0WgFvSwGBYF4xwI88ZjaFdEuKgb05pVFRMLHLBz43rfDcRnZI5y6721dxSfg//UV4ugbmljfqD4E6aShSY2Y01Mh0icddpMNn66wDYlEzwfI5kx7TG2XJAwtRZLcSiTtCZUiuEdCQEbG+1MAUH+lmZV5Mha18ARqMA1XYrfT enc: |
username: AgBx59yYqCazJM1iApbasAi8piOxEaiRMOEoqEf5gStXDLlZHayb48jp4MqTm0cGRok0+R9iHRO9JnW68mRexu+uQaPgOZWTVFTmtzkgMqiRAio79ivCDxZfK+s507J4LzAOzjLs1rtMSHoqA6YJw/vz30oQrsthtBrLnj0CGvcLqCjKbIOE75IypJBBXCyLts6Ndh4NXTch3eyr40qHo3ABZ5zSCOpives3AUo6gI+tr4zVLQXYEt3hsahcaQtm3um4PozgJlC4zIsfpGq111issXo3SCT7Ag2zn/8HO2D3olss36HzQMgVzs+hAC89wRX7CvV3q84/jrZSJ4Ymc163e7JWnbZz7d9npxcr0dXCPiJQXqJ2uIW6ByKupGxpVxGisUnG8UJv1Cj0xd8+nGXpxMsNm2VgdVPsqxct47XEyl/K1/6Tdc4IlNEcNIjASrI8+QOF3ceaP/3tx+lGVB+fGh3OJ8mTaJlEd5vXPum5LB71SiVHyxXP8VHUGka+Kth3H3wq8CT2Bu9sPrZ8FVng6ars8qd0pZt7pd6LoHLFiJ4FEt60LXX3fbzizG1vdHoth3hIiHF2wXQahh+FHT2HYXvVZpHPydajZzE3sDE4sJXAW/VDKg2y4ZobC+jp4uPIQxuZmSCkbt90W+9FiifsccB3mgWe/PK9NxS7RW1hjwv7U1jPFQW3i7EeiEzRwsAfJJ8chg== -----BEGIN AGE ENCRYPTED FILE-----
template: YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFdm9XakdSZFF3ZWhsaktu
metadata: Tm9aWU45ekhQeTdEc2FXbmVZZ2FYa3hrTWowCnkrM1hxSkNkTTFuVlh1NEZDbHBp
creationTimestamp: null cWppL1lCMlpaZ3I3ZHVmRS9kQkwxM2MKLS0tIGF2bFh3SzJ3azVpWlhHOUo1Zzhp
name: collabora-secret QVhKelUvY1hiR2FiR004YnQzMEFIN1EKa1JN+ra3csHPICDfyOS/DtE6SyRrGveW
namespace: nextcloud 9KigyHoAzOAjvr7Cjzirl9J7tgA9iasfbVE4mfcuqwJGR14ANJ7OPw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:sFjlG7K93WOS4QZXV/bcdVC2YwcCzzZ2lS6vtsR6v6SK0Lmw2neR5rc5SF6IESrUU4G3M/Y4VFTmb8Zttk0Tlk2nRlqXo35MIN6S+KTL/ssiCHSN4+J20Yp7HeQ+3DkLLY5+RiYAhrfzy/yUVRPWeAF3KKGwwfjknCR+avtLL44=,iv:QmesKHhkXUAD+lFS/ijYmsNVF8FFnmxiHk7IDJF5kmk=,tag:K4COX2z99gGuO2PBKUz7Zw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: collabora.michaelthomson.dev
namespace: nextcloud
spec:
endpoints:
- dnsName: collabora.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -1,15 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: nextcloud.michaelthomson.dev
namespace: nextcloud
spec:
endpoints:
- dnsName: nextcloud.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- michaelthomson.ddns.net
providerSpecific:
- name: external-dns.alpha.kubernetes.io/cloudflare-proxied
value: "true"

View File

@@ -1,21 +1,22 @@
{ apiVersion: v1
"kind": "SealedSecret", data:
"apiVersion": "bitnami.com/v1alpha1", password: ENC[AES256_GCM,data:sczdgF2gOu+NkUmPPS3ipwRPSkgsL69QwA4zUFGV70GRTpC+,iv:0sA/fN7M4Gg7FuOAH/+j8PhY26wT94UNCfbdJ36JKg0=,tag:V3G9nSJOtVh0yzNZkX3Uzg==,type:str]
"metadata": { kind: Secret
"name": "nextcloud-redis-secret", metadata:
"namespace": "nextcloud", name: nextcloud-redis-secret
"creationTimestamp": null namespace: nextcloud
}, sops:
"spec": { age:
"template": { - recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
"metadata": { enc: |
"name": "nextcloud-redis-secret", -----BEGIN AGE ENCRYPTED FILE-----
"namespace": "nextcloud", YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1aDEzNEFlUUNIekRib1hv
"creationTimestamp": null NGZITHZMTjhlWlQ3MHk1djlUVk1GeFRVRzBNCm12bWhPaHk2REo1RCtZUDhnLzF3
} SXFOMzlVaDdyZk9FQVhiZmV3ZEo3RlkKLS0tIHVrZGZ4cFp2SkVubCtxUWQ1aXBw
}, Y095N2YrRTZBdFBlOWlPYXpWS0R3dk0KTUGr2gfHK5NszjDWSJObcGNdvjiBQ0lt
"encryptedData": { ujeskIYbKzRoY8cCRxiGc17SFTYnp+2q0hBm8V9H+ywI74Chc1gOgA==
"password": "AgBKouCi+6E0aBUR1n/j8mvq5PUJb42wuR3q4JWLDgLYf+3MzVRUYPHh6bkN/aYtVpmRNOC8w9SjnJ3FTOwrgt4xsBP6faNcRoRPN1VjxQk68oWlExIIbZWkEAeyn2L0lwSkPV8aTfaEIFhBPPj2NaHyGJQ0uDWPc68ZVpmukuxkTuhQ3hm/8JDDTOe216Dc8FUpsEwr7AN0s+ZdDHFdi+opIjYs39cg4QyQ+YrIqRBK6oS1TrKtPJSmQEKPIOXyRqY7TxTc9t8NGLE3WKY26SSNFB9AHYaqhZFn3MDHg350g0KdXgxycxVuOLnxGnW+aEmQC58QCwxvZUcR+oapzDnJ8QnHv3vbtCdICBjSEF+Lq9vGYBMhqlI9zJ9SLj7WmG21rxxLFAscHPU7yzcowcWgGLpjndkmTvO//wXXPXcgYzJiIrBrxHiFRhwyNsTrEYI4+8CX8KHtcYYL+p/GUVJQ3YQSZc1IlzXnhutsniZb7jSOyrBIzvObhc+0pvOWh4GzBHX0rUUaU1PdvxUITNzVwZOrLLiKUxlPXqgOMijFcHlmxiWTD2U291NqKCdKDbnMKNKjWR9EgOR7GM6/OMWzAIaAlULw69DMnDZsoEQHkJbuQmmABQJE2HinY7Kt6EFKX3KueCN8gHIA1rpKEbahsl9cwnKIkLVSif0HkOibifV28MUhtVNLON5qjE7hvitEyOZoQgxXTw76gMMSBufjiWLUuDyl7ada" -----END AGE ENCRYPTED FILE-----
} lastmodified: "2025-12-17T20:36:08Z"
} mac: ENC[AES256_GCM,data:wISm9FeJ4cyF0I+QAMjte3/nwzwtk8c5VQltYzPlcsqUqOjLkmD6iLqtaOteZ3pZQOf9AylRTGaoow1kZ44X5dk/fx6Sy/JrQuhuc2JK7llgBqITp3S/sRK1Dtvb4r0y8x6iiKs8+sd/PA9TUqekPtmrC4dVcHKGzd1bX0DopU8=,iv:2bmJIOt1JUUk2TJbcQIg6/FwpvLpYTwpzKaSd39Lo9c=,tag:FbURmraQwP2NaB8CEVArww==,type:str]
} encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -1,16 +1,23 @@
--- apiVersion: v1
apiVersion: bitnami.com/v1alpha1 data:
kind: SealedSecret password: ENC[AES256_GCM,data:+gp5N+elMS/vn3N6u8z7+/IDVl6w3VDnE6UrIsRMak3f1qag,iv:TY+iRf28IvZzpc3wJtIVkflgzuSyQxpucUttce71iTo=,tag:A/LsCq31oVsjINhi2BH7Cw==,type:str]
username: ENC[AES256_GCM,data:LFfYK587FmlJy8Gl,iv:CtTz38aswJ87iWp8GslxFH6PMS9ZJ7puGprrURhidSE=,tag:5vSMUAyjjxpbHlx1/2h9IA==,type:str]
kind: Secret
metadata: metadata:
creationTimestamp: null name: postgres-secret
name: postgres-secret namespace: nextcloud
namespace: nextcloud sops:
spec: age:
encryptedData: - recipient: age1s0206tnfaaw849x5xmt95axgu8qhxzlu5ywrwz09tpt8lwpx858q089nq9
password: AgAx4sGDsXEHDTu0lTvW0E9KFgouJKiQvP8eIeUq7lkrNMDJ1+3KW98yiZ8PFeSSlcOqmW8M8K13pOvGXvmkYKHA2uV0FCO3UwAVxxmllMZytDM4FYxXhGCWUV3XC7fuIUkFGLF8BgGyNNZkZmDfmrEczfqmAjIze3WlQrWpqBkp4tGtgLpqZaKpmyTvnEtkH5WUwbg/uupmwqUV8cNCmzczfEEhtWHq45w6Zov6kaYNXimVgKJCHCGGcrskE2MbdpYnJ2Me8Bs6HpjV6tlDVLMoaxlr/sc1sN7XyNQBjiApjT0S8iPhaUdEsTgFZa36X3ReWoZvBVoge6kyT7GKC0DzzVShLD/BJ5zdWMt31K+J+7jFuLpLeFlSHoMNpkhlb3J28GI/RGYvdPWkQT0kXkIvmXt/l9XoFvKKKwhe6UQ7ULGBN9cWTySoqr9/9G0eYqxZ9WQ2h9WjuOiZd14J2opjGzfIJB20YMMBLoJ+QCZINvRRS8rKBw7hrDK6hDP3mIocLz66OnNWhptLZjDxfAYg0FQE2CwYkgdFaGdkX33AcYmTtNPP1qYw/MQkUfEE7MMR5/ABtXDBQQrnK54KAa1EEZ94C2JElceQBeFajNWIllFpl/S3QiIFr8OrOtzN4hPkGfNi5TQ1hRNNxKCOMimxhS3c8+tvvLEZDI8w0gFxO++WITC75mPTbwlTzYkovskKGvectx3rm+V4ideHOeiDow2OmNE2GEka enc: |
username: AgAcnwH13ZVW+QfveKCC4uRwjXmq0KWSdQrdNezse+w/h8rYReFbhG+3JV2Q0jkovU2jdVY8hQGTQsXLH824KeMYJN2d3MJhsN9GuTmskqp6ALyRhsneQyTyzgscb8lQQrUsQQ3kZmhtr+FWJBgyqRZtYUKihU7NEHN6HZ0XBKbQ0Mu7uq5K2mu9emhYHf0AkiAzVmMIMWt1xvOefkyH2mojHXgglo4MHzglkxxS/8jy9pTXfhr2dGRwyViS4HyVTEAD+Z1VaLX3uhghrEWGKnEyGcZF8Nto3FJXwEtCJH0KPFpSnPmu3jsq4EkQ94abAVe0/tT1lEAilYFlZL7SkDd28QD6dkBZCxqNukW8mst7xf9CsvLaJ+SkZsSnT0J6hQ/Gl8GbcrIYazxTaVutZ37h2io+tcQ8rWLF3U9/1fStpPr2Z/rEUdDgw/urYGCYwsQZAb9Ta1tG/5YjXrJUGQlKpntECtiLEMBQvbzgGqhYvnPlVoUneeVCEzx1dWci7jPWZ94cjZTYubi3Q5Wm5jeaeST34FLn+s56zVfDJ7CttN9Rv/lytkhYd7Tmv2ILpf9eyDePK0+WSrdaDF2W7NjAeEpQbt/+2WpCxc+KoHPZ7HA2DO3922gCrbaKoQ7bcais39+q9qrGvVSdUlNkLdpqQ6lycwbtqIgov9OludiOMhetGig6OO3TNkagNxgup5rj/B0RKXgyRjY= -----BEGIN AGE ENCRYPTED FILE-----
template: YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRemtSSkl2K01QSUlSbDha
metadata: dEdsa0JEWVZUeEtYSXM1OXRDQ3R1U01Zd0RNCnFKOWJRTElZRWxvdW94ZWRvUmNY
creationTimestamp: null Y1IxM216MUhLWjhKcFJJSE1YQjlTTlUKLS0tIExFSDdnVWZEZG43VFJwUGVPT1Bu
name: postgres-secret ZWljcWVZcXpOUjJnOStvbmgwVHRsT28KMF4lDFhHbI+yqXDhiIuDe2NeuhPaReS9
namespace: nextcloud Z6wiLrOWcXfbNN6DnLSBNAt0IqQzIYWHAlZayGPqA+JJCS/gkZnA1Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-17T20:36:08Z"
mac: ENC[AES256_GCM,data:TTAiIjKHCnA+mQ1fM0J3TEdqZkTRZKSHjRI4SsaiUut+uwWxN3nxUUlcBpyo3m62ff9WkyYvGtxfLsOXevrshN8WFB2H49NYA6TjyQgAzJ1XFeJZhFfSLM1nd/46a5KU/6mSBN9ZqUmnhXmBNo7wZdDKSJUlZ8tFwTtwDJve2o4=,iv:2idsk3hZOOWKGVZ+4Z9C82/+lF/tjokm3uBPMsE+WEw=,tag:UxQ6XtP9+iNaAn++IDYaHQ==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.11.0

View File

@@ -7,12 +7,11 @@ spec:
chart: chart:
spec: spec:
chart: nextcloud chart: nextcloud
version: 6.x version: 8.x
sourceRef: sourceRef:
kind: HelmRepository kind: HelmRepository
name: nextcloud name: nextcloud
interval: 15m interval: 15m
timeout: 5m
releaseName: nextcloud releaseName: nextcloud
values: values:
image: image:
@@ -22,12 +21,15 @@ spec:
enabled: true enabled: true
className: traefik className: traefik
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
tls: tls:
- hosts: - hosts:
- nextcloud.michaelthomson.dev - nextcloud.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: nextclout-tls
labels: {} labels: {}
path: / path: /
pathType: Prefix pathType: Prefix
@@ -90,6 +92,8 @@ spec:
postgresql: postgresql:
enabled: true enabled: true
image:
tag: 16.6.0
global: global:
postgresql: postgresql:
auth: auth:
@@ -148,6 +152,9 @@ spec:
ingress: ingress:
enabled: true enabled: true
annotations: annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.tls: "true"
hosts: hosts:
@@ -158,7 +165,7 @@ spec:
tls: tls:
- hosts: - hosts:
- collabora.michaelthomson.dev - collabora.michaelthomson.dev
secretName: letsencrypt-wildcard-cert-michaelthomson.dev secretName: collabora-tls
cronjob: cronjob:
enabled: true enabled: true

47
apps/ntfy/deployment.yaml Normal file
View File

@@ -0,0 +1,47 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ntfy
namespace: ntfy
labels:
app: ntfy
spec:
revisionHistoryLimit: 1
replicas: 1
selector:
matchLabels:
app: ntfy
template:
metadata:
labels:
app: ntfy
spec:
containers:
- name: ntfy
image: binwiederhier/ntfy:v1.28.0
args: ["serve"]
env:
- name: TZ
value: America/Toronto
- name: NTFY_DEBUG
value: "false"
- name: NTFY_LOG_LEVEL
value: INFO
- name: NTFY_BASE_URL
value: https://ntfy.michaelthomson.dev
ports:
- containerPort: 80
name: http
volumeMounts:
- mountPath: /etc/ntfy
subPath: server.yml
name: config-volume
- mountPath: /var/cache/ntfy
name: cache-volume
volumes:
- name: config-volume
configMap:
name: server-config
- name: cache-volume
persistentVolumeClaim:
claimName: pvc

27
apps/ntfy/ingress.yaml Normal file
View File

@@ -0,0 +1,27 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ntfy
namespace: ntfy
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
external-dns.alpha.kubernetes.io/target: michaelthomson.ddns.net
external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: ntfy.michaelthomson.dev
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: service
port:
name: http
tls:
- hosts:
- ntfy.michaelthomson.dev
secretName: ntfy-tls

View File

@@ -1,12 +1,12 @@
apiVersion: v1 apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: readarr-config name: pvc
namespace: media namespace: ntfy
spec: spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources: resources:
requests: requests:
storage: 1Gi storage: 1Gi
storageClassName: longhorn
accessModes:
- ReadWriteOnce

View File

@@ -0,0 +1,9 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: server-config
namespace: ntfy
data:
server.yml: |
cache-file: "/var/cache/ntfy/cache.db"
attachment-cache-dir: "/var/cache/ntfy/attachments"

14
apps/ntfy/service.yaml Normal file
View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: service
namespace: ntfy
spec:
type: ClusterIP
selector:
app: ntfy
ports:
- name: http
protocol: TCP
port: 80
targetPort: http

View File

@@ -1,12 +0,0 @@
apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
name: pihole.michaelthomson.dev
namespace: pihole
spec:
endpoints:
- dnsName: pihole.michaelthomson.dev
recordTTL: 180
recordType: CNAME
targets:
- server.michaelthomson.dev

Some files were not shown because too many files have changed in this diff Show More