Initial commit: k3s homelab infrastructure
Helm charts for media stack (Plex, Sonarr, Radarr, etc.), dashboards (Glance, Homepage), paperless-ngx, mealie, traefik ingress, MetalLB, and utilities. Includes SOPS-encrypted secrets and bootstrap script.
This commit is contained in:
commit
e07a5e1dfa
6
.sops.yaml
Normal file
6
.sops.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
creation_rules:
|
||||
- path_regex: secrets/.*\.yaml$
|
||||
age: >-
|
||||
age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
# Replace the above with your actual age public key from:
|
||||
# grep 'public key' /etc/sops/age/keys.txt
|
||||
6
AGENTS.md
Normal file
6
AGENTS.md
Normal file
@ -0,0 +1,6 @@
|
||||
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
|
||||
dogbox Ready control-plane 3h31m v1.34.6+k3s1 10.0.1.2 <none> Fedora Linux 40 (Server Edition) 6.9.6-200.fc40.x86_64 containerd://2.2.2-bd1.34
|
||||
mac-worker Ready <none> 3h13m v1.34.6+k3s1 192.168.139.12 <none> Ubuntu 25.10 6.17.8-orbstack-00308-g8f9c941121b1 containerd://2.2.2-bd1.34
|
||||
|
||||
|
||||
The mac-worker is running inside orbstack linux VM if that matters.
|
||||
152
README.md
Normal file
152
README.md
Normal file
@ -0,0 +1,152 @@
|
||||
# Homelab — k3s Cluster
|
||||
|
||||
2-node k3s cluster (1 manager, 1 worker) running a self-hosted homelab stack.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Manager Node Worker Node
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ k3s server │────────────│ k3s agent │
|
||||
│ Traefik │ │ │
|
||||
│ Longhorn │ │ Longhorn │
|
||||
└──────┬───────┘ └──────┬───────┘
|
||||
│ │
|
||||
└───────── NFS ─────────────┘
|
||||
/dogstore
|
||||
```
|
||||
|
||||
**Storage strategy:**
|
||||
|
||||
- `/dogstore` (NFS) — mounted on both nodes, used via hostPath for large media/data volumes
|
||||
- Longhorn — replicated block storage for small config/state volumes
|
||||
|
||||
**Ingress:** k3s built-in Traefik with Let's Encrypt via Cloudflare DNS challenge.
|
||||
|
||||
**Secrets:** SOPS + age encryption. Secrets live in `secrets/secrets.enc.yaml`, encrypted at rest.
|
||||
|
||||
## Services
|
||||
|
||||
|
||||
| Chart | Namespace | Services |
|
||||
| -------------- | ----------- | -------------------------------------------------------------- |
|
||||
| traefik-config | kube-system | Traefik HelmChartConfig overlay |
|
||||
| media | media | Plex, Sonarr, Radarr, Bazarr, Prowlarr, qBittorrent, unpackerr |
|
||||
| paperless | paperless | Paperless-ngx, Redis, PostgreSQL |
|
||||
| mealie | apps | Mealie |
|
||||
| dashboards | apps | Homepage, Glance |
|
||||
| utils | apps | Zerobyte, Seerr |
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Two Linux machines with NFS `/dogstore` mounted on both
|
||||
- `curl`, `helm`, `kubectl`, `sops`, `age` installed
|
||||
|
||||
## Bootstrap
|
||||
|
||||
### 1. Install k3s server (manager node)
|
||||
|
||||
```bash
|
||||
./scripts/bootstrap.sh server
|
||||
```
|
||||
|
||||
This prints the worker join command at the end.
|
||||
|
||||
### 2. Install k3s agent (worker node)
|
||||
|
||||
```bash
|
||||
K3S_URL="https://<manager-ip>:6443" K3S_TOKEN="<token>" ./scripts/bootstrap.sh agent
|
||||
```
|
||||
|
||||
### 3. Install Longhorn
|
||||
|
||||
```bash
|
||||
./scripts/bootstrap.sh longhorn
|
||||
```
|
||||
|
||||
### 4. Set up SOPS encryption
|
||||
|
||||
Generate an age keypair (run on each node):
|
||||
|
||||
```bash
|
||||
./scripts/bootstrap.sh sops-keygen
|
||||
```
|
||||
|
||||
Copy the public key into `.sops.yaml`, replacing the placeholder. Then encrypt your secrets:
|
||||
|
||||
```bash
|
||||
# Edit secrets/secrets.enc.yaml — replace REPLACE_WITH_* placeholders with real values
|
||||
sops -e -i secrets/secrets.enc.yaml
|
||||
```
|
||||
|
||||
### 5. Apply secrets
|
||||
|
||||
```bash
|
||||
./scripts/bootstrap.sh apply-secrets
|
||||
```
|
||||
|
||||
### 6. Deploy all charts
|
||||
|
||||
```bash
|
||||
./scripts/bootstrap.sh deploy
|
||||
```
|
||||
|
||||
Or deploy individually:
|
||||
|
||||
```bash
|
||||
kubectl create namespace media
|
||||
helm upgrade --install media charts/media -n media
|
||||
|
||||
kubectl create namespace paperless
|
||||
helm upgrade --install paperless charts/paperless -n paperless
|
||||
|
||||
kubectl create namespace apps
|
||||
helm upgrade --install mealie charts/mealie -n apps
|
||||
helm upgrade --install dashboards charts/dashboards -n apps
|
||||
helm upgrade --install utils charts/utils -n apps
|
||||
|
||||
# Traefik config goes in kube-system (managed by k3s)
|
||||
helm upgrade --install traefik-config charts/traefik-config -n kube-system
|
||||
```
|
||||
|
||||
## Verifying
|
||||
|
||||
```bash
|
||||
# Check all pods
|
||||
kubectl get pods -A
|
||||
|
||||
# Check ingress routes
|
||||
kubectl get ingress -A
|
||||
|
||||
# Test a specific service
|
||||
curl -I https://mealie.ratboo.me
|
||||
```
|
||||
|
||||
## Secret Rotation
|
||||
|
||||
1. Decrypt: `sops secrets/secrets.enc.yaml` (opens in `$EDITOR`)
|
||||
2. Change the values
|
||||
3. Save and close (SOPS re-encrypts automatically)
|
||||
4. Apply: `./scripts/bootstrap.sh apply-secrets`
|
||||
5. Restart affected pods: `kubectl rollout restart deployment/<name> -n <namespace>`
|
||||
|
||||
## Repo Structure
|
||||
|
||||
```
|
||||
homelab/
|
||||
├── README.md
|
||||
├── .sops.yaml
|
||||
├── scripts/
|
||||
│ └── bootstrap.sh
|
||||
├── charts/
|
||||
│ ├── traefik-config/
|
||||
│ ├── media/
|
||||
│ ├── paperless/
|
||||
│ ├── mealie/
|
||||
│ ├── dashboards/
|
||||
│ └── utils/
|
||||
└── secrets/
|
||||
└── secrets.enc.yaml
|
||||
```
|
||||
|
||||
5
charts/dashboards/Chart.yaml
Normal file
5
charts/dashboards/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: dashboards
|
||||
description: Homepage and Glance dashboard services
|
||||
version: 0.1.0
|
||||
type: application
|
||||
15
charts/dashboards/templates/glance-ingressroute.yaml
Normal file
15
charts/dashboards/templates/glance-ingressroute.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: glance
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik-internal
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
routes:
|
||||
- match: PathPrefix(`/`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: glance
|
||||
port: 8082
|
||||
57
charts/dashboards/templates/glance.yaml
Normal file
57
charts/dashboards/templates/glance.yaml
Normal file
@ -0,0 +1,57 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: glance
|
||||
labels:
|
||||
app: glance
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: glance
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: glance
|
||||
spec:
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/control-plane: "true"
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: glance
|
||||
image: {{ .Values.glance.image }}
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: DOMAIN
|
||||
value: {{ .Values.domain }}
|
||||
- name: HOST_IP
|
||||
value: {{ .Values.hostIp | quote }}
|
||||
- name: ADGUARD_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.glance.secretName }}
|
||||
key: ADGUARD_PASSWORD
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
volumes:
|
||||
- name: config
|
||||
hostPath:
|
||||
path: /dogstore/service-data/glance/config
|
||||
type: Directory
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: glance
|
||||
spec:
|
||||
selector:
|
||||
app: glance
|
||||
ports:
|
||||
- port: 8082
|
||||
targetPort: 8080
|
||||
50
charts/dashboards/templates/homepage.yaml
Normal file
50
charts/dashboards/templates/homepage.yaml
Normal file
@ -0,0 +1,50 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: homepage
|
||||
labels:
|
||||
app: homepage
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: homepage
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: homepage
|
||||
spec:
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/control-plane: "true"
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: homepage
|
||||
image: {{ .Values.homepage.image }}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: HOMEPAGE_ALLOWED_HOSTS
|
||||
value: "*"
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
volumes:
|
||||
- name: config
|
||||
hostPath:
|
||||
path: /dogstore/service-data/homepage/config
|
||||
type: Directory
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: homepage
|
||||
spec:
|
||||
selector:
|
||||
app: homepage
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
10
charts/dashboards/values.yaml
Normal file
10
charts/dashboards/values.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
domain: ratboo.me
|
||||
hostIp: "10.0.1.2"
|
||||
|
||||
|
||||
homepage:
|
||||
image: ghcr.io/gethomepage/homepage:latest
|
||||
|
||||
glance:
|
||||
image: glanceapp/glance
|
||||
secretName: glance-secrets
|
||||
5
charts/mealie/Chart.yaml
Normal file
5
charts/mealie/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: mealie
|
||||
description: Mealie recipe manager
|
||||
version: 0.1.0
|
||||
type: application
|
||||
101
charts/mealie/templates/mealie.yaml
Normal file
101
charts/mealie/templates/mealie.yaml
Normal file
@ -0,0 +1,101 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: mealie-data
|
||||
labels:
|
||||
app: mealie
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.storageSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mealie
|
||||
labels:
|
||||
app: mealie
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mealie
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mealie
|
||||
spec:
|
||||
containers:
|
||||
- name: mealie
|
||||
image: {{ .Values.image }}
|
||||
ports:
|
||||
- containerPort: 9000
|
||||
resources:
|
||||
limits:
|
||||
memory: {{ .Values.resources.limits.memory }}
|
||||
env:
|
||||
- name: PUID
|
||||
value: {{ .Values.puid | quote }}
|
||||
- name: PGID
|
||||
value: {{ .Values.pgid | quote }}
|
||||
- name: TZ
|
||||
value: {{ .Values.tz | quote }}
|
||||
- name: MAX_WORKERS
|
||||
value: "1"
|
||||
- name: WEB_CONCURRENCY
|
||||
value: "1"
|
||||
- name: ALLOW_SIGNUP
|
||||
value: "false"
|
||||
- name: BASE_URL
|
||||
value: https://mealie.{{ .Values.domain }}
|
||||
- name: OPENAI_BASE_URL
|
||||
value: {{ .Values.ai.baseUrl }}
|
||||
- name: OPENAI_MODEL
|
||||
value: {{ .Values.ai.model }}
|
||||
- name: OPENAI_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secretName }}
|
||||
key: OPENAI_API_KEY
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /app/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: mealie-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mealie
|
||||
spec:
|
||||
selector:
|
||||
app: mealie
|
||||
ports:
|
||||
- port: 9000
|
||||
targetPort: 9000
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: mealie
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls.certresolver: {{ .Values.certResolver }}
|
||||
spec:
|
||||
rules:
|
||||
- host: mealie.{{ .Values.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: mealie
|
||||
port:
|
||||
number: 9000
|
||||
19
charts/mealie/values.yaml
Normal file
19
charts/mealie/values.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
domain: ratboo.me
|
||||
certResolver: myresolver
|
||||
tz: America/Los_Angeles
|
||||
puid: "1000"
|
||||
pgid: "1000"
|
||||
|
||||
image: ghcr.io/mealie-recipes/mealie:v3.14.0
|
||||
|
||||
secretName: mealie-secrets
|
||||
storageClass: longhorn
|
||||
storageSize: 5Gi
|
||||
|
||||
resources:
|
||||
limits:
|
||||
memory: 1000Mi
|
||||
|
||||
ai:
|
||||
baseUrl: https://generativelanguage.googleapis.com/v1beta
|
||||
model: gemini-2.0-flash
|
||||
5
charts/media/Chart.yaml
Normal file
5
charts/media/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: media
|
||||
description: Media stack -- Plex, Sonarr, Radarr, Bazarr, Prowlarr, qBittorrent, unpackerr
|
||||
version: 0.1.0
|
||||
type: application
|
||||
13
charts/media/templates/_helpers.tpl
Normal file
13
charts/media/templates/_helpers.tpl
Normal file
@ -0,0 +1,13 @@
|
||||
{{- define "media.labels" -}}
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/part-of: media
|
||||
{{- end -}}
|
||||
|
||||
{{- define "media.commonEnv" -}}
|
||||
- name: PUID
|
||||
value: {{ .Values.puid | quote }}
|
||||
- name: PGID
|
||||
value: {{ .Values.pgid | quote }}
|
||||
- name: TZ
|
||||
value: {{ .Values.tz | quote }}
|
||||
{{- end -}}
|
||||
72
charts/media/templates/bazarr.yaml
Normal file
72
charts/media/templates/bazarr.yaml
Normal file
@ -0,0 +1,72 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: bazarr-config
|
||||
labels:
|
||||
app: bazarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.bazarr.configSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: bazarr
|
||||
labels:
|
||||
app: bazarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: bazarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: bazarr
|
||||
spec:
|
||||
containers:
|
||||
- name: bazarr
|
||||
image: {{ .Values.bazarr.image }}
|
||||
ports:
|
||||
- containerPort: 6767
|
||||
env:
|
||||
{{- include "media.commonEnv" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: movies
|
||||
mountPath: /movies
|
||||
- name: tv
|
||||
mountPath: /tv
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: bazarr-config
|
||||
- name: movies
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/sonarr/data/radarr-library
|
||||
type: DirectoryOrCreate
|
||||
- name: tv
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/sonarr/data/library
|
||||
type: DirectoryOrCreate
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: bazarr
|
||||
labels:
|
||||
app: bazarr
|
||||
spec:
|
||||
selector:
|
||||
app: bazarr
|
||||
ports:
|
||||
- port: 6767
|
||||
targetPort: 6767
|
||||
108
charts/media/templates/plex.yaml
Normal file
108
charts/media/templates/plex.yaml
Normal file
@ -0,0 +1,108 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: plex-config
|
||||
labels:
|
||||
app: plex
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.plex.configSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: plex
|
||||
labels:
|
||||
app: plex
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: plex
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: plex
|
||||
spec:
|
||||
containers:
|
||||
- name: plex
|
||||
image: {{ .Values.plex.image }}
|
||||
ports:
|
||||
- containerPort: 32400
|
||||
protocol: TCP
|
||||
env:
|
||||
{{- include "media.commonEnv" . | nindent 12 }}
|
||||
- name: PLEX_CLAIM
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secretName }}
|
||||
key: PLEX_CLAIM
|
||||
- name: ADVERTISE_IP
|
||||
value: {{ .Values.plex.advertiseIp | quote }}
|
||||
- name: VERSION
|
||||
value: docker
|
||||
- name: NVIDIA_VISIBLE_DEVICES
|
||||
value: all
|
||||
- name: NVIDIA_DRIVER_CAPABILITIES
|
||||
value: compute,video,utility
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: transcode
|
||||
mountPath: /transcode
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: plex-config
|
||||
- name: transcode
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/plex/transcode
|
||||
type: DirectoryOrCreate
|
||||
- name: data
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}
|
||||
type: Directory
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: plex
|
||||
labels:
|
||||
app: plex
|
||||
spec:
|
||||
selector:
|
||||
app: plex
|
||||
ports:
|
||||
- name: web
|
||||
port: 32400
|
||||
targetPort: 32400
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: plex
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls.certresolver: {{ .Values.certResolver }}
|
||||
spec:
|
||||
rules:
|
||||
- host: plex.{{ .Values.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: plex
|
||||
port:
|
||||
number: 32400
|
||||
60
charts/media/templates/prowlarr.yaml
Normal file
60
charts/media/templates/prowlarr.yaml
Normal file
@ -0,0 +1,60 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: prowlarr-config
|
||||
labels:
|
||||
app: prowlarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.prowlarr.configSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: prowlarr
|
||||
labels:
|
||||
app: prowlarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: prowlarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: prowlarr
|
||||
spec:
|
||||
containers:
|
||||
- name: prowlarr
|
||||
image: {{ .Values.prowlarr.image }}
|
||||
ports:
|
||||
- containerPort: 9696
|
||||
env:
|
||||
{{- include "media.commonEnv" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: prowlarr-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: prowlarr
|
||||
labels:
|
||||
app: prowlarr
|
||||
spec:
|
||||
selector:
|
||||
app: prowlarr
|
||||
ports:
|
||||
- port: 9696
|
||||
targetPort: 9696
|
||||
82
charts/media/templates/qbittorrent.yaml
Normal file
82
charts/media/templates/qbittorrent.yaml
Normal file
@ -0,0 +1,82 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: qbittorrent-config
|
||||
labels:
|
||||
app: qbittorrent
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.qbittorrent.configSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: qbittorrent
|
||||
labels:
|
||||
app: qbittorrent
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: qbittorrent
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: qbittorrent
|
||||
spec:
|
||||
containers:
|
||||
- name: qbittorrent
|
||||
image: {{ .Values.qbittorrent.image }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.qbittorrent.webuiPort }}
|
||||
protocol: TCP
|
||||
- containerPort: 34034
|
||||
protocol: TCP
|
||||
- containerPort: 34034
|
||||
protocol: UDP
|
||||
env:
|
||||
{{- include "media.commonEnv" . | nindent 12 }}
|
||||
- name: WEBUI_PORTS
|
||||
value: "{{ .Values.qbittorrent.webuiPort }}/tcp"
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: qbittorrent-config
|
||||
- name: data
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/sonarr/data
|
||||
type: DirectoryOrCreate
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: qbittorrent
|
||||
labels:
|
||||
app: qbittorrent
|
||||
spec:
|
||||
selector:
|
||||
app: qbittorrent
|
||||
ports:
|
||||
- name: webui
|
||||
port: {{ .Values.qbittorrent.webuiPort }}
|
||||
targetPort: {{ .Values.qbittorrent.webuiPort }}
|
||||
- name: bt-tcp
|
||||
port: 34034
|
||||
targetPort: 34034
|
||||
protocol: TCP
|
||||
- name: bt-udp
|
||||
port: 34034
|
||||
targetPort: 34034
|
||||
protocol: UDP
|
||||
86
charts/media/templates/radarr.yaml
Normal file
86
charts/media/templates/radarr.yaml
Normal file
@ -0,0 +1,86 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: radarr-config
|
||||
labels:
|
||||
app: radarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.radarr.configSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: radarr
|
||||
labels:
|
||||
app: radarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: radarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: radarr
|
||||
spec:
|
||||
containers:
|
||||
- name: radarr
|
||||
image: {{ .Values.radarr.image }}
|
||||
ports:
|
||||
- containerPort: 7878
|
||||
env:
|
||||
{{- include "media.commonEnv" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: radarr-config
|
||||
- name: data
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/sonarr/data
|
||||
type: DirectoryOrCreate
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: radarr
|
||||
labels:
|
||||
app: radarr
|
||||
spec:
|
||||
selector:
|
||||
app: radarr
|
||||
ports:
|
||||
- port: 7878
|
||||
targetPort: 7878
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: radarr
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls.certresolver: {{ .Values.certResolver }}
|
||||
spec:
|
||||
rules:
|
||||
- host: radarr.{{ .Values.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: radarr
|
||||
port:
|
||||
number: 7878
|
||||
86
charts/media/templates/sonarr.yaml
Normal file
86
charts/media/templates/sonarr.yaml
Normal file
@ -0,0 +1,86 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: sonarr-config
|
||||
labels:
|
||||
app: sonarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.sonarr.configSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sonarr
|
||||
labels:
|
||||
app: sonarr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: sonarr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: sonarr
|
||||
spec:
|
||||
containers:
|
||||
- name: sonarr
|
||||
image: {{ .Values.sonarr.image }}
|
||||
ports:
|
||||
- containerPort: 8989
|
||||
env:
|
||||
{{- include "media.commonEnv" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: sonarr-config
|
||||
- name: data
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/sonarr/data
|
||||
type: DirectoryOrCreate
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: sonarr
|
||||
labels:
|
||||
app: sonarr
|
||||
spec:
|
||||
selector:
|
||||
app: sonarr
|
||||
ports:
|
||||
- port: 8989
|
||||
targetPort: 8989
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: sonarr
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls.certresolver: {{ .Values.certResolver }}
|
||||
spec:
|
||||
rules:
|
||||
- host: sonarr.{{ .Values.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: sonarr
|
||||
port:
|
||||
number: 8989
|
||||
93
charts/media/templates/unpackerr.yaml
Normal file
93
charts/media/templates/unpackerr.yaml
Normal file
@ -0,0 +1,93 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: unpackerr
|
||||
labels:
|
||||
app: unpackerr
|
||||
{{- include "media.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: unpackerr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: unpackerr
|
||||
spec:
|
||||
containers:
|
||||
- name: unpackerr
|
||||
image: {{ .Values.unpackerr.image }}
|
||||
env:
|
||||
- name: UN_DEBUG
|
||||
value: "false"
|
||||
- name: UN_LOG_FILE
|
||||
value: /logs/log.txt
|
||||
- name: UN_LOG_FILES
|
||||
value: "10"
|
||||
- name: UN_LOG_FILE_MB
|
||||
value: "10"
|
||||
- name: UN_INTERVAL
|
||||
value: 1m
|
||||
- name: UN_START_DELAY
|
||||
value: 1m
|
||||
- name: UN_RETRY_DELAY
|
||||
value: 5m
|
||||
- name: UN_MAX_RETRIES
|
||||
value: "3"
|
||||
- name: UN_PARALLEL
|
||||
value: "1"
|
||||
- name: UN_FILE_MODE
|
||||
value: "0644"
|
||||
- name: UN_DIR_MODE
|
||||
value: "0755"
|
||||
- name: UN_SONARR_0_URL
|
||||
value: http://sonarr:8989
|
||||
- name: UN_SONARR_0_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secretName }}
|
||||
key: SONARR_API_KEY
|
||||
- name: UN_SONARR_0_PATHS_0
|
||||
value: /data/library
|
||||
- name: UN_SONARR_0_PROTOCOLS
|
||||
value: torrent
|
||||
- name: UN_SONARR_0_TIMEOUT
|
||||
value: 10s
|
||||
- name: UN_SONARR_0_DELETE_ORIG
|
||||
value: "false"
|
||||
- name: UN_SONARR_0_DELETE_DELAY
|
||||
value: 5m
|
||||
- name: UN_RADARR_0_URL
|
||||
value: http://radarr:7878
|
||||
- name: UN_RADARR_0_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secretName }}
|
||||
key: RADARR_API_KEY
|
||||
- name: UN_RADARR_0_PATHS_0
|
||||
value: /data/radarr-library
|
||||
- name: UN_RADARR_0_PROTOCOLS
|
||||
value: torrent
|
||||
- name: UN_RADARR_0_TIMEOUT
|
||||
value: 10s
|
||||
- name: UN_RADARR_0_DELETE_ORIG
|
||||
value: "false"
|
||||
- name: UN_RADARR_0_DELETE_DELAY
|
||||
value: 5m
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
- name: logs
|
||||
mountPath: /logs
|
||||
volumes:
|
||||
- name: data
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/sonarr/data
|
||||
type: DirectoryOrCreate
|
||||
- name: logs
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/logs/unpackerr
|
||||
type: DirectoryOrCreate
|
||||
41
charts/media/values.yaml
Normal file
41
charts/media/values.yaml
Normal file
@ -0,0 +1,41 @@
|
||||
domain: ratboo.me
|
||||
certResolver: myresolver
|
||||
tz: America/Los_Angeles
|
||||
puid: "1000"
|
||||
pgid: "1000"
|
||||
|
||||
dogstore: /dogstore
|
||||
|
||||
secretName: media-secrets
|
||||
|
||||
storageClass: longhorn
|
||||
configStorageSize: 2Gi
|
||||
|
||||
plex:
|
||||
image: plexinc/pms-docker:latest
|
||||
advertiseIp: "https://plex.ratboo.me:443"
|
||||
configSize: 20Gi
|
||||
|
||||
sonarr:
|
||||
image: ghcr.io/hotio/sonarr:latest
|
||||
configSize: 2Gi
|
||||
|
||||
radarr:
|
||||
image: ghcr.io/hotio/radarr:latest
|
||||
configSize: 2Gi
|
||||
|
||||
bazarr:
|
||||
image: lscr.io/linuxserver/bazarr:latest
|
||||
configSize: 1Gi
|
||||
|
||||
prowlarr:
|
||||
image: ghcr.io/hotio/prowlarr:latest
|
||||
configSize: 1Gi
|
||||
|
||||
qbittorrent:
|
||||
image: ghcr.io/hotio/qbittorrent:latest
|
||||
configSize: 1Gi
|
||||
webuiPort: 9191
|
||||
|
||||
unpackerr:
|
||||
image: golift/unpackerr
|
||||
6
charts/metallb/Chart.lock
Normal file
6
charts/metallb/Chart.lock
Normal file
@ -0,0 +1,6 @@
|
||||
dependencies:
|
||||
- name: metallb
|
||||
repository: https://metallb.github.io/metallb
|
||||
version: 0.15.3
|
||||
digest: sha256:e449dd234fcbd51b21a6e63f8725dc609ab762d41db733ea7302ec44a1fb52f0
|
||||
generated: "2026-04-19T18:30:19.754244737-04:00"
|
||||
9
charts/metallb/Chart.yaml
Normal file
9
charts/metallb/Chart.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
apiVersion: v2
|
||||
name: metallb
|
||||
description: MetalLB load balancer for internal services
|
||||
version: 0.1.0
|
||||
type: application
|
||||
dependencies:
|
||||
- name: metallb
|
||||
version: "0.15.3"
|
||||
repository: "https://metallb.github.io/metallb"
|
||||
BIN
charts/metallb/charts/metallb-0.15.3.tgz
Normal file
BIN
charts/metallb/charts/metallb-0.15.3.tgz
Normal file
Binary file not shown.
19
charts/metallb/templates/pool.yaml
Normal file
19
charts/metallb/templates/pool.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
{{- if .Values.pool.enabled }}
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: IPAddressPool
|
||||
metadata:
|
||||
name: {{ .Values.pool.name }}
|
||||
spec:
|
||||
addresses:
|
||||
{{- range .Values.pool.addresses }}
|
||||
- {{ . }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: metallb.io/v1beta1
|
||||
kind: L2Advertisement
|
||||
metadata:
|
||||
name: {{ .Values.pool.name }}
|
||||
spec:
|
||||
ipAddressPools:
|
||||
- {{ .Values.pool.name }}
|
||||
{{- end }}
|
||||
13
charts/metallb/values.yaml
Normal file
13
charts/metallb/values.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
metallb:
|
||||
controller:
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/control-plane: "true"
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
effect: NoSchedule
|
||||
|
||||
pool:
|
||||
enabled: false
|
||||
name: internal
|
||||
addresses:
|
||||
- "10.0.1.250-10.0.1.250"
|
||||
5
charts/paperless/Chart.yaml
Normal file
5
charts/paperless/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: paperless
|
||||
description: Paperless-ngx with Redis broker and PostgreSQL database
|
||||
version: 0.1.0
|
||||
type: application
|
||||
64
charts/paperless/templates/postgres.yaml
Normal file
64
charts/paperless/templates/postgres.yaml
Normal file
@ -0,0 +1,64 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: paperless-postgres-data
|
||||
labels:
|
||||
app: paperless-postgres
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.postgres.storageSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: paperless-postgres
|
||||
labels:
|
||||
app: paperless-postgres
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: paperless-postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: paperless-postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: {{ .Values.postgres.image }}
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgres.database }}
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgres.user }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secretName }}
|
||||
key: POSTGRES_PASSWORD
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: paperless-postgres-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: paperless-postgres
|
||||
spec:
|
||||
selector:
|
||||
app: paperless-postgres
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
54
charts/paperless/templates/redis.yaml
Normal file
54
charts/paperless/templates/redis.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: paperless-redis-data
|
||||
labels:
|
||||
app: paperless-redis
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.redis.storageSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: paperless-redis
|
||||
labels:
|
||||
app: paperless-redis
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: paperless-redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: paperless-redis
|
||||
spec:
|
||||
containers:
|
||||
- name: redis
|
||||
image: {{ .Values.redis.image }}
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: paperless-redis-data
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: paperless-redis
|
||||
spec:
|
||||
selector:
|
||||
app: paperless-redis
|
||||
ports:
|
||||
- port: 6379
|
||||
targetPort: 6379
|
||||
113
charts/paperless/templates/webserver.yaml
Normal file
113
charts/paperless/templates/webserver.yaml
Normal file
@ -0,0 +1,113 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: paperless-webserver
|
||||
labels:
|
||||
app: paperless-webserver
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: paperless-webserver
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: paperless-webserver
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: {{ int .Values.puid }}
|
||||
runAsGroup: {{ int .Values.pgid }}
|
||||
containers:
|
||||
- name: paperless
|
||||
image: {{ .Values.webserver.image }}
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
env:
|
||||
- name: PAPERLESS_REDIS
|
||||
value: redis://paperless-redis:6379
|
||||
- name: PAPERLESS_DBHOST
|
||||
value: paperless-postgres
|
||||
- name: PAPERLESS_DBPASS
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.secretName }}
|
||||
key: PAPERLESS_DB_PASS
|
||||
- name: PAPERLESS_CSRF_TRUSTED_ORIGINS
|
||||
value: {{ .Values.webserver.csrfTrustedOrigins | quote }}
|
||||
- name: USERMAP_UID
|
||||
value: {{ .Values.puid | quote }}
|
||||
- name: USERMAP_GID
|
||||
value: {{ .Values.pgid | quote }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 8000
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 3
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /usr/src/paperless/data
|
||||
- name: media
|
||||
mountPath: /usr/src/paperless/media
|
||||
- name: export
|
||||
mountPath: /usr/src/paperless/export
|
||||
- name: consume
|
||||
mountPath: /usr/src/paperless/consume
|
||||
volumes:
|
||||
- name: data
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/paperless/data
|
||||
type: DirectoryOrCreate
|
||||
- name: media
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/paperless/media
|
||||
type: DirectoryOrCreate
|
||||
- name: export
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/paperless/export
|
||||
type: DirectoryOrCreate
|
||||
- name: consume
|
||||
hostPath:
|
||||
path: {{ .Values.dogstore }}/paperless/consume
|
||||
type: DirectoryOrCreate
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: paperless-webserver
|
||||
spec:
|
||||
selector:
|
||||
app: paperless-webserver
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: paperless
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls.certresolver: {{ .Values.certResolver }}
|
||||
spec:
|
||||
rules:
|
||||
- host: paperless.{{ .Values.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: paperless-webserver
|
||||
port:
|
||||
number: 8000
|
||||
24
charts/paperless/values.yaml
Normal file
24
charts/paperless/values.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
domain: ratboo.me
|
||||
certResolver: myresolver
|
||||
tz: America/Los_Angeles
|
||||
puid: "1000"
|
||||
pgid: "1000"
|
||||
|
||||
dogstore: /dogstore
|
||||
|
||||
secretName: paperless-secrets
|
||||
storageClass: longhorn
|
||||
|
||||
webserver:
|
||||
image: ghcr.io/paperless-ngx/paperless-ngx:latest
|
||||
csrfTrustedOrigins: "https://paperless.ratboo.me"
|
||||
|
||||
redis:
|
||||
image: docker.io/library/redis:7
|
||||
storageSize: 1Gi
|
||||
|
||||
postgres:
|
||||
image: docker.io/library/postgres:15
|
||||
storageSize: 5Gi
|
||||
database: paperless
|
||||
user: paperless
|
||||
5
charts/traefik-config/Chart.yaml
Normal file
5
charts/traefik-config/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: traefik-config
|
||||
description: Traefik ingress configuration for k3s (HelmChartConfig overlay + Cloudflare DNS challenge)
|
||||
version: 0.1.0
|
||||
type: application
|
||||
41
charts/traefik-config/templates/helmchartconfig.yaml
Normal file
41
charts/traefik-config/templates/helmchartconfig.yaml
Normal file
@ -0,0 +1,41 @@
|
||||
apiVersion: helm.cattle.io/v1
|
||||
kind: HelmChartConfig
|
||||
metadata:
|
||||
name: traefik
|
||||
namespace: kube-system
|
||||
spec:
|
||||
valuesContent: |-
|
||||
service:
|
||||
spec:
|
||||
loadBalancerClass: io.k3s.klipper
|
||||
logs:
|
||||
general:
|
||||
level: WARN
|
||||
ports:
|
||||
web:
|
||||
redirections:
|
||||
entryPoint:
|
||||
to: websecure
|
||||
scheme: https
|
||||
permanent: true
|
||||
websecure:
|
||||
tls:
|
||||
certResolver: {{ .Values.certResolver }}
|
||||
certResolvers:
|
||||
{{ .Values.certResolver }}:
|
||||
acme:
|
||||
email: {{ .Values.acmeEmail }}
|
||||
storage: {{ .Values.letsencrypt.storagePath }}
|
||||
caServer: {{ .Values.acmeServer }}
|
||||
dnsChallenge:
|
||||
provider: cloudflare
|
||||
env:
|
||||
- name: CF_DNS_API_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.cloudflare.secretName }}
|
||||
key: {{ .Values.cloudflare.secretKey }}
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: longhorn
|
||||
size: 128Mi
|
||||
9
charts/traefik-config/templates/middleware-redirect.yaml
Normal file
9
charts/traefik-config/templates/middleware-redirect.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: redirect-https
|
||||
namespace: kube-system
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
12
charts/traefik-config/values.yaml
Normal file
12
charts/traefik-config/values.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
domain: ratboo.me
|
||||
acmeEmail: alvin7@gmail.com
|
||||
|
||||
certResolver: myresolver
|
||||
acmeServer: https://acme-v02.api.letsencrypt.org/directory
|
||||
|
||||
cloudflare:
|
||||
secretName: cloudflare-api-token
|
||||
secretKey: CF_DNS_API_TOKEN
|
||||
|
||||
letsencrypt:
|
||||
storagePath: /data/acme.json
|
||||
5
charts/traefik-internal/Chart.yaml
Normal file
5
charts/traefik-internal/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: traefik-internal
|
||||
description: Internal Traefik instance for LAN-only services
|
||||
version: 0.1.0
|
||||
type: application
|
||||
91
charts/traefik-internal/templates/traefik-internal.yaml
Normal file
91
charts/traefik-internal/templates/traefik-internal.yaml
Normal file
@ -0,0 +1,91 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: traefik-internal
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: traefik-internal
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: [services, endpoints, secrets, nodes]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [discovery.k8s.io]
|
||||
resources: [endpointslices]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [traefik.io]
|
||||
resources: [ingressroutes, ingressroutetcps, ingressrouteudps, middlewares, middlewaretcps, tlsoptions, tlsstores, traefikservices, serverstransports, serverstransporttcps]
|
||||
verbs: [get, list, watch]
|
||||
- apiGroups: [traefik.io]
|
||||
resources: [ingressroutes/status, ingressroutetcps/status, ingressrouteudps/status]
|
||||
verbs: [update]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: traefik-internal
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: traefik-internal
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: traefik-internal
|
||||
namespace: {{ .Release.Namespace }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: traefik-internal
|
||||
labels:
|
||||
app: traefik-internal
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: traefik-internal
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: traefik-internal
|
||||
spec:
|
||||
serviceAccountName: traefik-internal
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/control-plane: "true"
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: traefik
|
||||
image: {{ .Values.image }}
|
||||
args:
|
||||
- --entrypoints.web.address=:{{ .Values.port }}
|
||||
- --providers.kubernetescrd
|
||||
- --providers.kubernetescrd.ingressClass={{ .Values.ingressClass }}
|
||||
- --api.insecure=true
|
||||
- --log.level=WARN
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: {{ .Values.port }}
|
||||
- name: dashboard
|
||||
containerPort: 8080
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: traefik-internal
|
||||
annotations:
|
||||
metallb.io/address-pool: internal
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
loadBalancerIP: {{ .Values.loadBalancerIP }}
|
||||
selector:
|
||||
app: traefik-internal
|
||||
ports:
|
||||
- name: web
|
||||
port: {{ .Values.port }}
|
||||
targetPort: {{ .Values.port }}
|
||||
- name: dashboard
|
||||
port: 9095
|
||||
targetPort: 8080
|
||||
4
charts/traefik-internal/values.yaml
Normal file
4
charts/traefik-internal/values.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
image: traefik:v3.3
|
||||
port: 8082
|
||||
ingressClass: traefik-internal
|
||||
loadBalancerIP: "10.0.1.250"
|
||||
5
charts/utils/Chart.yaml
Normal file
5
charts/utils/Chart.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v2
|
||||
name: utils
|
||||
description: Utility services -- Zerobyte backup and Seerr media requests
|
||||
version: 0.1.0
|
||||
type: application
|
||||
91
charts/utils/templates/seerr.yaml
Normal file
91
charts/utils/templates/seerr.yaml
Normal file
@ -0,0 +1,91 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: seerr-config
|
||||
labels:
|
||||
app: seerr
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.seerr.storageSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: seerr
|
||||
labels:
|
||||
app: seerr
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: seerr
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: seerr
|
||||
spec:
|
||||
containers:
|
||||
- name: seerr
|
||||
image: {{ .Values.seerr.image }}
|
||||
ports:
|
||||
- containerPort: 5055
|
||||
env:
|
||||
- name: TZ
|
||||
value: {{ .Values.tz | quote }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/settings/public
|
||||
port: 5055
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /api/v1/settings/public
|
||||
port: 5055
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 3
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
volumes:
|
||||
- name: config
|
||||
persistentVolumeClaim:
|
||||
claimName: seerr-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: seerr
|
||||
spec:
|
||||
selector:
|
||||
app: seerr
|
||||
ports:
|
||||
- port: 5055
|
||||
targetPort: 5055
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: seerr
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls.certresolver: {{ .Values.certResolver }}
|
||||
spec:
|
||||
rules:
|
||||
- host: watch.{{ .Values.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: seerr
|
||||
port:
|
||||
number: 5055
|
||||
71
charts/utils/templates/zerobyte.yaml
Normal file
71
charts/utils/templates/zerobyte.yaml
Normal file
@ -0,0 +1,71 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: zerobyte-data
|
||||
labels:
|
||||
app: zerobyte
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: {{ .Values.storageClass }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.zerobyte.storageSize }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: zerobyte
|
||||
labels:
|
||||
app: zerobyte
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: zerobyte
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: zerobyte
|
||||
spec:
|
||||
containers:
|
||||
- name: zerobyte
|
||||
image: {{ .Values.zerobyte.image }}
|
||||
ports:
|
||||
- containerPort: 4096
|
||||
env:
|
||||
- name: TZ
|
||||
value: {{ .Values.tz | quote }}
|
||||
- name: BASE_URL
|
||||
value: http://{{ .Values.hostIp }}:4096
|
||||
- name: APP_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.zerobyte.secretName }}
|
||||
key: APP_SECRET
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/zerobyte
|
||||
- name: localtime
|
||||
mountPath: /etc/localtime
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: zerobyte-data
|
||||
- name: localtime
|
||||
hostPath:
|
||||
path: /etc/localtime
|
||||
type: File
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: zerobyte
|
||||
spec:
|
||||
selector:
|
||||
app: zerobyte
|
||||
ports:
|
||||
- port: 4096
|
||||
targetPort: 4096
|
||||
14
charts/utils/values.yaml
Normal file
14
charts/utils/values.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
domain: ratboo.me
|
||||
certResolver: myresolver
|
||||
tz: America/Los_Angeles
|
||||
hostIp: "10.0.1.2"
|
||||
storageClass: longhorn
|
||||
|
||||
zerobyte:
|
||||
image: ghcr.io/nicotsx/zerobyte:v0.33
|
||||
storageSize: 1Gi
|
||||
secretName: zerobyte-secrets
|
||||
|
||||
seerr:
|
||||
image: ghcr.io/seerr-team/seerr:latest
|
||||
storageSize: 1Gi
|
||||
144
scripts/bootstrap.sh
Executable file
144
scripts/bootstrap.sh
Executable file
@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# ─── Configuration ───────────────────────────────────────────────────────────
|
||||
K3S_VERSION="v1.31.4+k3s1"
|
||||
LONGHORN_VERSION="1.7.2"
|
||||
LONGHORN_REPO="https://charts.longhorn.io"
|
||||
|
||||
# ─── Helper ──────────────────────────────────────────────────────────────────
|
||||
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
|
||||
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
|
||||
error() { printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2; exit 1; }
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") <command>
|
||||
|
||||
Commands:
|
||||
server Install k3s server (manager node)
|
||||
agent Install k3s agent (worker node)
|
||||
longhorn Install Longhorn via Helm
|
||||
sops-keygen Generate an age keypair for SOPS
|
||||
apply-secrets Decrypt and apply SOPS secrets to the cluster
|
||||
deploy Helm-install all charts
|
||||
all Run: server → longhorn → sops-keygen → apply-secrets → deploy
|
||||
EOF
|
||||
}
|
||||
|
||||
# ─── k3s server ──────────────────────────────────────────────────────────────
|
||||
cmd_server() {
|
||||
info "Installing k3s server ${K3S_VERSION} …"
|
||||
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="${K3S_VERSION}" sh -s - server \
|
||||
--write-kubeconfig-mode 644
|
||||
|
||||
info "Waiting for node to be Ready …"
|
||||
until kubectl get node "$(hostname)" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null | grep -q True; do
|
||||
sleep 2
|
||||
done
|
||||
info "Server node is Ready."
|
||||
|
||||
local token
|
||||
token=$(cat /var/lib/rancher/k3s/server/node-token)
|
||||
local ip
|
||||
ip=$(hostname -I | awk '{print $1}')
|
||||
info "Worker join command:"
|
||||
echo " curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=\"${K3S_VERSION}\" K3S_URL=\"https://${ip}:6443\" K3S_TOKEN=\"${token}\" sh -"
|
||||
}
|
||||
|
||||
# ─── k3s agent ───────────────────────────────────────────────────────────────
|
||||
cmd_agent() {
|
||||
if [[ -z "${K3S_URL:-}" || -z "${K3S_TOKEN:-}" ]]; then
|
||||
error "Set K3S_URL and K3S_TOKEN environment variables first.\n K3S_URL=https://<manager-ip>:6443 K3S_TOKEN=<token> $0 agent"
|
||||
fi
|
||||
info "Installing k3s agent ${K3S_VERSION} …"
|
||||
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION="${K3S_VERSION}" K3S_URL="${K3S_URL}" K3S_TOKEN="${K3S_TOKEN}" sh -
|
||||
info "Agent installed. It will appear as a node shortly."
|
||||
}
|
||||
|
||||
# ─── Longhorn ────────────────────────────────────────────────────────────────
|
||||
cmd_longhorn() {
|
||||
info "Installing Longhorn ${LONGHORN_VERSION} via Helm …"
|
||||
helm repo add longhorn "${LONGHORN_REPO}" 2>/dev/null || true
|
||||
helm repo update longhorn
|
||||
kubectl create namespace longhorn-system 2>/dev/null || true
|
||||
helm upgrade --install longhorn longhorn/longhorn \
|
||||
--namespace longhorn-system \
|
||||
--version "${LONGHORN_VERSION}" \
|
||||
--set defaultSettings.defaultReplicaCount=2 \
|
||||
--wait
|
||||
info "Longhorn installed."
|
||||
}
|
||||
|
||||
# ─── SOPS / age ─────────────────────────────────────────────────────────────
|
||||
cmd_sops_keygen() {
|
||||
local keydir="/etc/sops/age"
|
||||
local keyfile="${keydir}/keys.txt"
|
||||
if [[ -f "${keyfile}" ]]; then
|
||||
warn "Age key already exists at ${keyfile} — skipping generation."
|
||||
else
|
||||
info "Generating age keypair …"
|
||||
sudo mkdir -p "${keydir}"
|
||||
age-keygen -o "${keyfile}" 2>&1
|
||||
sudo chmod 600 "${keyfile}"
|
||||
info "Key written to ${keyfile}"
|
||||
fi
|
||||
info "Public key (put this in .sops.yaml):"
|
||||
grep 'public key' "${keyfile}" | awk '{print $NF}'
|
||||
}
|
||||
|
||||
cmd_apply_secrets() {
|
||||
local secrets_dir
|
||||
secrets_dir="$(cd "$(dirname "$0")/.." && pwd)/secrets"
|
||||
info "Decrypting and applying secrets …"
|
||||
local decrypted
|
||||
decrypted="$(sops -d "${secrets_dir}/secrets.enc.yaml")"
|
||||
|
||||
local ns
|
||||
for ns in $(printf '%s\n' "${decrypted}" | grep '^\s*namespace:' | awk '{print $2}' | sort -u); do
|
||||
kubectl create namespace "${ns}" 2>/dev/null || true
|
||||
done
|
||||
|
||||
printf '%s\n' "${decrypted}" | kubectl apply -f -
|
||||
info "Secrets applied."
|
||||
}
|
||||
|
||||
# ─── Deploy all charts ──────────────────────────────────────────────────────
|
||||
cmd_deploy() {
|
||||
local charts_dir
|
||||
charts_dir="$(cd "$(dirname "$0")/.." && pwd)/charts"
|
||||
|
||||
local -a chart_order=(traefik-config media paperless mealie dashboards utils)
|
||||
local -A chart_ns=(
|
||||
[traefik-config]=kube-system
|
||||
[media]=media
|
||||
[paperless]=paperless
|
||||
[mealie]=apps
|
||||
[dashboards]=apps
|
||||
[utils]=apps
|
||||
)
|
||||
|
||||
for chart in "${chart_order[@]}"; do
|
||||
local ns="${chart_ns[$chart]}"
|
||||
info "Deploying ${chart} → namespace ${ns} …"
|
||||
kubectl create namespace "${ns}" 2>/dev/null || true
|
||||
helm upgrade --install "${chart}" "${charts_dir}/${chart}" \
|
||||
--namespace "${ns}" \
|
||||
--wait --timeout 5m
|
||||
done
|
||||
info "All charts deployed."
|
||||
}
|
||||
|
||||
# ─── Main ────────────────────────────────────────────────────────────────────
|
||||
[[ $# -lt 1 ]] && { usage; exit 1; }
|
||||
|
||||
case "$1" in
|
||||
server) cmd_server ;;
|
||||
agent) cmd_agent ;;
|
||||
longhorn) cmd_longhorn ;;
|
||||
sops-keygen) cmd_sops_keygen ;;
|
||||
apply-secrets) cmd_apply_secrets ;;
|
||||
deploy) cmd_deploy ;;
|
||||
all) cmd_server; cmd_longhorn; cmd_sops_keygen; cmd_apply_secrets; cmd_deploy ;;
|
||||
*) usage; exit 1 ;;
|
||||
esac
|
||||
158
secrets/secrets.enc.yaml
Normal file
158
secrets/secrets.enc.yaml
Normal file
@ -0,0 +1,158 @@
|
||||
#ENC[AES256_GCM,data:1wyYmxw5bF4pkfLGKuBx7V0KqV9MOj+WEcNkTLX2o8cjN7k/NJg2YhPkDKbxQhalm5RccC3vCCgmaeJzjExt,iv:v/VlwHMwJSHfevf2sN8Sq9dMUdah3cNWitmWR6OUJm8=,tag:Q/M3rkS+NLlHCT0Mnu1TLA==,type:comment]
|
||||
#ENC[AES256_GCM,data:ZL4tevfMjoN4RMiNz1zQHAiZ3cpcfPKFwirJWPwf7qWf7fd8jWGr1Fr/KuFiIzSkny3n9nC3Vwg=,iv:YKPVLd4zxA7wMFx0jd917W4pHSRtcXP93rcBz/0jyso=,tag:G3Hi0oXtz+/9tE4zRYPUMA==,type:comment]
|
||||
#ENC[AES256_GCM,data:IQpAXI8AERzfGJSWcnGnBKustu2wkhf7CtehJLk2qhOj9R5X8QoIb7AEfhy0ONi8EpZSfKIQ5AbYom+ZjB9vUiDKeCmtae1RpQVXHVu7jmh9OI212+8VkUyi3PDMN3wH7NIQ1zX8h5PxYFUuKvWgx4hHCYESwgfkW49fSTfwxeeWjSbyNOM=,iv:69fsTOQ5LJ3s4KRwaOb676dAOaujpWx3Ah+q8mlzzf0=,tag:b/nxflYxTCaiInYsb7Szpw==,type:comment]
|
||||
#ENC[AES256_GCM,data:Rd8TnilJ/5Ak7egTQsvVeXgCx7Gx3EmYMptVWqhtb6hVJ5I0uHNdMlBe1YGCPfic8F0fYfzBlgJaNz1ycfooQfF/lYfBxGx9EARSGznEsg==,iv:0SRR76k5qnbu4j+dMuUf2kLMeZAkerBmej0gR8/Wpfg=,tag:HMaPbx1ExnzRoiq6DlxYIw==,type:comment]
|
||||
#
|
||||
#ENC[AES256_GCM,data:y3lu8sygTZJ+TSJOyrFXShJGBu5gHYLT4A==,iv:xmugUAyc116U4nESzKAYcvz76BBGwHLK7HE61gnS2gE=,tag:1LTSMRi+Aat4hk2N7c+2gw==,type:comment]
|
||||
#ENC[AES256_GCM,data:/ny7h4o0XSF1kROKuEUD9xrZJYOJ7mTZGIgTtIWHdclmdd9vYTLNl2+Hb9kHzCCWUgPXRg6pOww=,iv:47xT9Fct8sJrfIf8qRGD1xUTEkgdGf+KC9hWQ3XJG44=,tag:yix6VVO+g10cLbUwLWdTeA==,type:comment]
|
||||
#ENC[AES256_GCM,data:du0a4InEiMTw4mg5EqVPpANM3j0FNpDSle2na/7Q0vM1Z4SE52Jvvz3ZIV99b1pY30QlFdnTGO/4grVJd7xiUYC5wCUNY/uGNYGX2HzOWZjByEb5p9VCOPS2Czl/pPGM9+9d08mn2u1Ww4Wt6a/hrFOUWQddjTNz7HwG66xT/YVTnCN++mTnkCbgQKIjV1YhpSQKWA5jNfgSqSVKwbEA60JvESavT51HSZnrAGKWIepaJc7S14jTp+tUdqA=,iv:SZKsksvhtXCcKByjV85stfmt/DGHSsSh+PTGuCfe874=,tag:IQWtYVrLFx8EfPtKb1tK9g==,type:comment]
|
||||
apiVersion: ENC[AES256_GCM,data:3lY=,iv:MBpXRZ3rElkVBxAlvxmzORMCq0G87jB3Ik11tWMfz64=,tag:oPPwCxOiK3ePCWRhtHmN2w==,type:str]
|
||||
kind: ENC[AES256_GCM,data:8+Toxlr5,iv:DTaS/GEKGLtZsHQBYTGaQZYSp9mr/A5Vbuqi7uq46rU=,tag:1YvMaF1/eLNkZv0F3Du0zA==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:RgUAwk6jY7DHv+CbTtyXx5nzEQQ=,iv:FeAx14K1od0ehMnbcpnD4FW1bpEF/3M+dq8NGoJwTJA=,tag:SziXyyeAgShOgsandPQD7A==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:IgxkBPTfQ8rEWzA=,iv:56aP5rBeH9aupBi338/9r4fXZ1ova8ubO7N8elr2/qM=,tag:vfFTXJrQ2J5vln/rBGl/og==,type:str]
|
||||
type: ENC[AES256_GCM,data:Efo/5l3N,iv:moQ775VrJkfQFO3YPM3ZT77i0IzcWy/G7b5E4/XOyJY=,tag:zfEMZgXgO+qMQIvPrLeMsA==,type:str]
|
||||
stringData:
|
||||
CF_DNS_API_TOKEN: ENC[AES256_GCM,data:74wQ12RQ9M7BckVfPjbRUnEbeaFB0aOPIhZHrFo=,iv:SIS0dJBpXkcJLjqEGnM1mtD1CB76MN2rZObyG8bCVe4=,tag:Rac0lPa5J2JSkdKcVc1PtQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWFcrTlYrOW1Tb0xGUmVS
|
||||
Q3VPb3VPMS9hRWQ4aDQzRGtFTXp4SU90YWlrCng5NkN3TUFEUGIrWkRCK1NMeVND
|
||||
Z2RwV0JKVnRTMWUvWlpDRzhBQWtsNVkKLS0tIHZ2NkZaVTJSaE1vTjVVMXhzTmYz
|
||||
eGZTZ0VSUElFZVpqWlVISjNYdnA4UFUK/uOyj7CKU0XLHHdPNKByO2c56JWQfhk5
|
||||
oauimeYrkNE+06dhXgVcJiQH+HcB33tB9u3YS9LxFYs3R98zKAHG6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-19T21:05:51Z"
|
||||
mac: ENC[AES256_GCM,data:GQx4YuPIIfZxRpWtHCa8pCtidtmdYoIdMsK0dQJO42XT9KR5lbwNaP3v4GoaDoeM+L7iAn2OprpE54KkwIwRfb3NAjTeUvXO+J/Yi4ZJnLtuTOlAZrC8YvjmiZ6DaL8pvpRz7VUCfzNOoyrbjSJ2Qv/PWAUENcDEU7yOHNv7RBA=,iv:FqYd2F4vBqSCeKPsrWY/a8RePgkU2aP9cadB6nMyWaQ=,tag:FC75r3bMOQDZZwO0qJi4xg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.2
|
||||
---
|
||||
#ENC[AES256_GCM,data:ibx/1sx8LotfzeKT/rRsedIOoYD+F6aXbrA3QEqjfSrFAXWchGiLX9ddAY0q0DOGi7tFcty1rwWUj1Iiy+vd88zZDRhLSVgs0hIdqqPaHVubOWA7gAmxvZdb1faLU4cOAe7gL9bUdaBlGzQKat6miytnWBXL8qidoFl/Ps1wNNDXRBpe+TsQfVAp5T5jirq35s7GTeXUbQO3bNkKx/ZNHmV7ASctKeRv5TLuAJIwyU6UIGSSnx6Sdr43mZlm6iJjdoT6jQxeH7yB1Gut7g==,iv:wAtBwQNTI56JLHISsA1W00M3X+v6R6vEkNK1SVULsTg=,tag:Jk/4OdnXyV6/5VwFcXpX/A==,type:comment]
|
||||
apiVersion: ENC[AES256_GCM,data:jNM=,iv:dt+kXGEjK6yS09KRE5I3uAXNLGN05RbO0GyjNTHYHtk=,tag:7z93Yh4m2SpZLHdxVIr1hw==,type:str]
|
||||
kind: ENC[AES256_GCM,data:ORSVG3Tn,iv:gqhsNppUalHTDcKa7q/P3TR5t4VZC1gLc2MgY8V6xEw=,tag:vr764iOVWPJujZd4rxRYKA==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:1ngffZeDVnrLbux2pg==,iv:OXYS/A5PBvmIVw5qDu+Um7J/JhM8shVfP3KDIXNBCU0=,tag:wfmayiCBy22O+WIPBC3PPQ==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:xCM+W3I=,iv:0KLfoYx8Q+NVsm84KZX3tClbWdwuTpI6/pD7HQMK3Fk=,tag:hSFwqHfnHWOPvesUhWyo+Q==,type:str]
|
||||
type: ENC[AES256_GCM,data:K3TlGbY8,iv:ZKm+PyQ4IAP0K1ymcMvWPOEUgUGzH93UkmH+rheJk7A=,tag:8tMEVI895tOOt8/tjiKRuw==,type:str]
|
||||
stringData:
|
||||
PLEX_CLAIM: ENC[AES256_GCM,data:A+dwGU//qfy6sBoww5c36xs2WcwdbQY=,iv:S6wOadxaC4ITyZN/7u5Lcu8AeBFdQLRqRlCHH3oSj28=,tag:hlNKdZGzURuFgcSrUrZyJA==,type:str]
|
||||
SONARR_API_KEY: ENC[AES256_GCM,data:VvU91ZNxv6tauBEyK9j8THxT8zw0mTLEmTTSRgYDEek=,iv:DZr5JL9T4f7XwQ03jkwVKfWA/xyAZlo4f/BKAzIIsQo=,tag:mCh8ExJvuoltcMlzAk6jpw==,type:str]
|
||||
RADARR_API_KEY: ENC[AES256_GCM,data:UJr87uk6V8sYT3kIp8dzevE8xA55QN4Aop6nP3uMBbc=,iv:Z0NicMtVOBxEwXtcBjqfMZKuTrPjqi3H1vIYu6llHHo=,tag:Xz88jgAwwK/ekh+8udlCjQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWFcrTlYrOW1Tb0xGUmVS
|
||||
Q3VPb3VPMS9hRWQ4aDQzRGtFTXp4SU90YWlrCng5NkN3TUFEUGIrWkRCK1NMeVND
|
||||
Z2RwV0JKVnRTMWUvWlpDRzhBQWtsNVkKLS0tIHZ2NkZaVTJSaE1vTjVVMXhzTmYz
|
||||
eGZTZ0VSUElFZVpqWlVISjNYdnA4UFUK/uOyj7CKU0XLHHdPNKByO2c56JWQfhk5
|
||||
oauimeYrkNE+06dhXgVcJiQH+HcB33tB9u3YS9LxFYs3R98zKAHG6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-19T21:05:51Z"
|
||||
mac: ENC[AES256_GCM,data:GQx4YuPIIfZxRpWtHCa8pCtidtmdYoIdMsK0dQJO42XT9KR5lbwNaP3v4GoaDoeM+L7iAn2OprpE54KkwIwRfb3NAjTeUvXO+J/Yi4ZJnLtuTOlAZrC8YvjmiZ6DaL8pvpRz7VUCfzNOoyrbjSJ2Qv/PWAUENcDEU7yOHNv7RBA=,iv:FqYd2F4vBqSCeKPsrWY/a8RePgkU2aP9cadB6nMyWaQ=,tag:FC75r3bMOQDZZwO0qJi4xg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.2
|
||||
---
|
||||
#ENC[AES256_GCM,data:rmGnwFT8rj+qcuyiuf4VdY5KJP5m4bMt9a1znHpQ+uYyrfzNoAH0eqn6yHMB3xAwFJtFOkzEdd0E1PaL5C30UbqtpwDNyzD0QYipIwDkQBGwRnkXXI8xw1ftE1zHcFWnPmnSH70hCJa+/Xu425pIyJeVlJhUqoOGkG5/gV0DQoVMnJXFXnh5a64Ggv7UzB92o9/iyUFMgi/7j4ePNQCc7Um1VePXc5mkRl8cQBbvwAgyMZo+IxDJ8hpS2HgbRGey5/RAxaDvRbwkyRU=,iv:Cl77wg8+J3D6QrIgbjRS/lzbJLf2qGkK/AtnIOoKG+E=,tag:m4TfMvHm5W612rrJJ+ytkA==,type:comment]
|
||||
apiVersion: ENC[AES256_GCM,data:fyA=,iv:lkH+XfaHDNUNE3+oUW5lkA3ev0AEQZGe2y/J5H5G4AI=,tag:QCGr4Ia7Ea+CRWWoWSFaug==,type:str]
|
||||
kind: ENC[AES256_GCM,data:GS9uiEv6,iv:9VAdvjoF7thUVtJRpyaDnBOVlZ9so1p5f4iaw1WxJ0w=,tag:gDCWZfn4zCdyRdMup9Vs3Q==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:XLV37KdISRoLUp4yo44=,iv:Hb2AQVYhhu5erfg+41edOfB4cT6O6e2k1ytEixVaZDk=,tag:2qP4C7sxSdkdnsTVRhsXcg==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:S/sYVQ==,iv:SuUw6GPbT7YF66+O2w8al89NcJBr3oi8C12nZIbNWWc=,tag:NBVJrXnAhVJqx325MQnOTQ==,type:str]
|
||||
type: ENC[AES256_GCM,data:suP66pVq,iv:RrLuX+MOixEaR3iw4EMBCqkT03TW3xvmzdXsTf8kl2c=,tag:Id8xGXmFcmN+gYyZsohp3g==,type:str]
|
||||
stringData:
|
||||
OPENAI_API_KEY: ENC[AES256_GCM,data:1QtOURL+C0DcB4AQhvmQP2PqeNQm2VQWTr/alY4FQzbhCnpxSFLS,iv:hy+a7cAcUNYr1XkKK1JoG8imjh5kT7B2tr5FWfHgAds=,tag:72zQFszAQpPEzZ0v24V5yg==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWFcrTlYrOW1Tb0xGUmVS
|
||||
Q3VPb3VPMS9hRWQ4aDQzRGtFTXp4SU90YWlrCng5NkN3TUFEUGIrWkRCK1NMeVND
|
||||
Z2RwV0JKVnRTMWUvWlpDRzhBQWtsNVkKLS0tIHZ2NkZaVTJSaE1vTjVVMXhzTmYz
|
||||
eGZTZ0VSUElFZVpqWlVISjNYdnA4UFUK/uOyj7CKU0XLHHdPNKByO2c56JWQfhk5
|
||||
oauimeYrkNE+06dhXgVcJiQH+HcB33tB9u3YS9LxFYs3R98zKAHG6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-19T21:05:51Z"
|
||||
mac: ENC[AES256_GCM,data:GQx4YuPIIfZxRpWtHCa8pCtidtmdYoIdMsK0dQJO42XT9KR5lbwNaP3v4GoaDoeM+L7iAn2OprpE54KkwIwRfb3NAjTeUvXO+J/Yi4ZJnLtuTOlAZrC8YvjmiZ6DaL8pvpRz7VUCfzNOoyrbjSJ2Qv/PWAUENcDEU7yOHNv7RBA=,iv:FqYd2F4vBqSCeKPsrWY/a8RePgkU2aP9cadB6nMyWaQ=,tag:FC75r3bMOQDZZwO0qJi4xg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.2
|
||||
---
|
||||
#ENC[AES256_GCM,data:3I2e5Uv2dvWtDWXnVh0AULaS9z2Pcd/iUHjvycTsfxhDpzEJfc0a0dISctuLpELEyBv1PtYemFZ/XeTqGJswTF4vvzM7UL6scPezIm674aOtjVqPj7/C3nQgfnuY1qgVY7duawWZeaozf8hBKef1JJ1qR1T3Mati3YBIaw3fp1qjYyKo47/F19UT/qtL6mlu8CE3/zIVbzZGsKwfqhYf6oLg2I7aNlvJ0/yWz8RSjwmtWj8WzUD1wZh+DnFRiTlbE+kLdgw=,iv:i+4OhA58TOv1pzPInqu9qi9zunYzpNbvHrELXVsXis8=,tag:XJyBP8nci2u5X7THGox3CQ==,type:comment]
|
||||
apiVersion: ENC[AES256_GCM,data:RdI=,iv:YlI7VI5Tk6f99ZhiJEI/LaGgmYejt6/8k0wo+n8G19E=,tag:WY473Ft6vXo0NkpGlnGq/w==,type:str]
|
||||
kind: ENC[AES256_GCM,data:5fh5Zy1D,iv:1qApXn+j2LFNs1fzrH8j6M84espcQz4cHwquEmsHDSU=,tag:MnWyue/omxF6Emrpsz9eEw==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:ZYLasrZQ1Bu0jcLbRQjmjCo=,iv:O0uBw2j+X0CPaUkYQvnTVRgl9nNZBDF058/hZB/WFwY=,tag:xuwCgyi5VT9enQ3HlYzW1g==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:Xr9+LDzWK7z+,iv:6iXdpkcUho23jU2BZLHKkxONTtQIYkZem9NVlyB/Ltk=,tag:3wV3EMtmqXr0yTUcfbqxCA==,type:str]
|
||||
type: ENC[AES256_GCM,data:+5bc8NF8,iv:JpVUvDJZdk++m1K5pyuPTF1p17X62Mlwv6GKK9Hqoz8=,tag:Kdihg3qXXHD0ieypkcvWSg==,type:str]
|
||||
stringData:
|
||||
PAPERLESS_DB_PASS: ENC[AES256_GCM,data:5/oF170q34nO,iv:y09u1KOZaIoUNtDog0sEbkj5gKD8C3JQyvNDSy0ElkI=,tag:WvIMb0Z0l7XXC6wB59ZTtg==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWFcrTlYrOW1Tb0xGUmVS
|
||||
Q3VPb3VPMS9hRWQ4aDQzRGtFTXp4SU90YWlrCng5NkN3TUFEUGIrWkRCK1NMeVND
|
||||
Z2RwV0JKVnRTMWUvWlpDRzhBQWtsNVkKLS0tIHZ2NkZaVTJSaE1vTjVVMXhzTmYz
|
||||
eGZTZ0VSUElFZVpqWlVISjNYdnA4UFUK/uOyj7CKU0XLHHdPNKByO2c56JWQfhk5
|
||||
oauimeYrkNE+06dhXgVcJiQH+HcB33tB9u3YS9LxFYs3R98zKAHG6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-19T21:05:51Z"
|
||||
mac: ENC[AES256_GCM,data:GQx4YuPIIfZxRpWtHCa8pCtidtmdYoIdMsK0dQJO42XT9KR5lbwNaP3v4GoaDoeM+L7iAn2OprpE54KkwIwRfb3NAjTeUvXO+J/Yi4ZJnLtuTOlAZrC8YvjmiZ6DaL8pvpRz7VUCfzNOoyrbjSJ2Qv/PWAUENcDEU7yOHNv7RBA=,iv:FqYd2F4vBqSCeKPsrWY/a8RePgkU2aP9cadB6nMyWaQ=,tag:FC75r3bMOQDZZwO0qJi4xg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.2
|
||||
---
|
||||
#ENC[AES256_GCM,data:txDOIoubztyTgbgUC4MMNxNIwDkjtF/m+H5YAZ6hdaHTCBjVZSVKhHjYJzLFPeHE2EL02SEgJaXSkyF0bWwWw/QfR/yCkiGPdZ0fAFDKtJJBtITkM4O5rwRCTEXsQXleWK5NM6M55s5ElWIlBE//uLt2+hPlDQv26EOwwAa9I7kW2bUPDGvYNJVc7mJSfjMQb6aOx1MzrA+PUryeBVdK0xdmBmiQaZyGC0MexEjBwAycVnCM,iv:u4rMeGWy1J779Z7JNFvWTsxDREbTWAS+bXFxQhPTyGA=,tag:mVoS7lSVAHcqPcQ6iqhjvA==,type:comment]
|
||||
apiVersion: ENC[AES256_GCM,data:JGU=,iv:vr1Lkm9BBG2u8Ay0PGAIMTYUUKhMHIho3mVP1lY6it0=,tag:12JH+n4nUsYqmiy1+CnwfA==,type:str]
|
||||
kind: ENC[AES256_GCM,data:VLdoeXnN,iv:eH+/KpTMtpclAxFnjX5mXxkF73HUMJlskNSS/iW+g+U=,tag:NE/Xdc9qsfFmXAyZ4y+3HQ==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:dKvmrGqwCK+KvfdBxcs=,iv:3B71qX/mVAJGMcKlxTrnfub3rp/o7PJ+mquxo+V6svY=,tag:gnvbDBvZexdbOHkQQNUInw==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:93lKXQ==,iv:TQq2ZC7l1uQBc0FNRg6sQRfLuLIokQHpgAzRTcFmGsE=,tag:Mv+ih+YMDfYIihWNgnztow==,type:str]
|
||||
type: ENC[AES256_GCM,data:Ep25FUNF,iv:ZCzL99uhG0SYRXlu9j3GmgWtIxcfe6C9lEkP5EFr6SY=,tag:ANEtn7vXJisqoUlX7rEBAQ==,type:str]
|
||||
stringData:
|
||||
ADGUARD_PASSWORD: ENC[AES256_GCM,data:Keh2GHhvfSyp9Q==,iv:bJ2CdmjqMZUSVw2T1jerqT1gkiP6k+aL9VyGCVJ10wI=,tag:cfR6jRn6NyrZ3/2WM5SdKg==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWFcrTlYrOW1Tb0xGUmVS
|
||||
Q3VPb3VPMS9hRWQ4aDQzRGtFTXp4SU90YWlrCng5NkN3TUFEUGIrWkRCK1NMeVND
|
||||
Z2RwV0JKVnRTMWUvWlpDRzhBQWtsNVkKLS0tIHZ2NkZaVTJSaE1vTjVVMXhzTmYz
|
||||
eGZTZ0VSUElFZVpqWlVISjNYdnA4UFUK/uOyj7CKU0XLHHdPNKByO2c56JWQfhk5
|
||||
oauimeYrkNE+06dhXgVcJiQH+HcB33tB9u3YS9LxFYs3R98zKAHG6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-19T21:05:51Z"
|
||||
mac: ENC[AES256_GCM,data:GQx4YuPIIfZxRpWtHCa8pCtidtmdYoIdMsK0dQJO42XT9KR5lbwNaP3v4GoaDoeM+L7iAn2OprpE54KkwIwRfb3NAjTeUvXO+J/Yi4ZJnLtuTOlAZrC8YvjmiZ6DaL8pvpRz7VUCfzNOoyrbjSJ2Qv/PWAUENcDEU7yOHNv7RBA=,iv:FqYd2F4vBqSCeKPsrWY/a8RePgkU2aP9cadB6nMyWaQ=,tag:FC75r3bMOQDZZwO0qJi4xg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.2
|
||||
---
|
||||
#ENC[AES256_GCM,data:CXcPJbTR4tVVRGK6l0NBowzab2DHaufhxX++4dQ9/S3Q9V0Me/kA0xBoR4PlfFRVG6QgsIeEK1ysx3d5qOy6/VcS9HFibUv8lTx0X8EonLNgsc2Qc4V526eJ3tByTyqRw780YsTVZFHZ+ofJBNPAcB4Rls1G8214E/kfyWxKWdHB7Joy83SQeWgL6On2oEdeWnpyp+E7FTqk2SXR+/YLVnNbixeirjpRCWlcnPXxhoSlRzcxUmAWTPT8zWicoUo5AiSh2C/DNw==,iv:lZ1ffJ4ixyhY829s2EiJlcF18fK1RDSUZ1F1Lw+YG14=,tag:dfn5m/iYHvzO7BE+ZygMMw==,type:comment]
|
||||
apiVersion: ENC[AES256_GCM,data:F6o=,iv:8McPTAtRKlG0wpF1DUXRrhkzNuoD97Vu4OFyI8Opy28=,tag:DgEjMs6yXKFEv6Uu8A8WDg==,type:str]
|
||||
kind: ENC[AES256_GCM,data:eVSn4ODQ,iv:iDOb7kRnWbW1CYKILAZwbtlhbAqwi/I+YXFbHsmz2KI=,tag:dcWY/PdP2eMRv1HxmfyHoQ==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:JffgDJUP/W+tue33DF91Ug==,iv:pXq1HZ2azFQSYP1LKYl94q8f1srLOH7GJw1cW6p+yrI=,tag:Dh6BCtR0gxqnb+c20RrKLA==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:O6kz8Q==,iv:ZMv7m+YLaIChgNTM4Riopt2VUNg5HwUwdLR6bRA1Nf0=,tag:undk4ODEabPJbQKoa1He7A==,type:str]
|
||||
type: ENC[AES256_GCM,data:YMUJyMI2,iv:o++4jFOch8C8g5iKCzot/AcHnERRO/Yqn/uHuCAIFEI=,tag:ReJgAAajctyGo7xYr2Yc8w==,type:str]
|
||||
stringData:
|
||||
ZEROBYTE_APP_SECRET: ENC[AES256_GCM,data:cqkj4VGIbbV9pvkZf+GHC9WWB07I/4pyu3ML7Ld/CiTaJB04WzsTwTi2bzxrfZopJc76gvXe1d55Kkm34fQ=,iv:w7WgywKZfMLcgexyJUvhpXnIhc+Xns1RDJXhHx/vBKc=,tag:X/Xx9PSs69gGY9LIkstB5g==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age12gv2cu66v80khwse5jgwcaukf3juvufkm2kw507gfnvecdpwt3hsjra7te
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNWFcrTlYrOW1Tb0xGUmVS
|
||||
Q3VPb3VPMS9hRWQ4aDQzRGtFTXp4SU90YWlrCng5NkN3TUFEUGIrWkRCK1NMeVND
|
||||
Z2RwV0JKVnRTMWUvWlpDRzhBQWtsNVkKLS0tIHZ2NkZaVTJSaE1vTjVVMXhzTmYz
|
||||
eGZTZ0VSUElFZVpqWlVISjNYdnA4UFUK/uOyj7CKU0XLHHdPNKByO2c56JWQfhk5
|
||||
oauimeYrkNE+06dhXgVcJiQH+HcB33tB9u3YS9LxFYs3R98zKAHG6g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-19T21:05:51Z"
|
||||
mac: ENC[AES256_GCM,data:GQx4YuPIIfZxRpWtHCa8pCtidtmdYoIdMsK0dQJO42XT9KR5lbwNaP3v4GoaDoeM+L7iAn2OprpE54KkwIwRfb3NAjTeUvXO+J/Yi4ZJnLtuTOlAZrC8YvjmiZ6DaL8pvpRz7VUCfzNOoyrbjSJ2Qv/PWAUENcDEU7yOHNv7RBA=,iv:FqYd2F4vBqSCeKPsrWY/a8RePgkU2aP9cadB6nMyWaQ=,tag:FC75r3bMOQDZZwO0qJi4xg==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.2
|
||||
Loading…
x
Reference in New Issue
Block a user