Compare commits
78
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3b911e4ab
|
||
|
|
820340455d | ||
|
|
bb8da2f3ba | ||
|
|
d26f4821de | ||
|
|
5910d406bf | ||
|
|
a7d27804e2 | ||
|
|
5e79bad09e | ||
|
|
7c95f2191c | ||
|
|
3951ecae96 | ||
|
|
82ad813a1c | ||
|
|
5db7c87292 | ||
|
|
10ee6528fd | ||
|
|
57f9f3883b | ||
|
|
352059fbbc | ||
|
|
a913e10a42 | ||
|
|
2cab677ef9 | ||
|
|
3f4269511c | ||
|
|
2ecc949323 | ||
|
|
cc0d255b99 | ||
|
|
98a8a469c4 | ||
|
|
03a062c649 | ||
|
|
c38cf40898 | ||
|
|
fe3bd8e56a | ||
|
|
04a3aa1d54 | ||
|
|
212b0bdbf3 | ||
|
|
93fb70770b | ||
|
|
a46aab984c | ||
|
|
6bbe3afbdd | ||
|
|
144fb51126
|
||
|
|
5b6bb444ad | ||
|
|
f8fb3c59ad | ||
|
|
107d352036 | ||
|
|
bcb4ebbbb8 | ||
|
|
95b25cacc5 | ||
|
|
f01ac8f468 | ||
|
|
2756b38ec3
|
||
|
|
728221523f | ||
|
|
820ce00535 | ||
|
|
96bfd53907
|
||
|
|
ec757b8b48 | ||
|
|
ca4cf45e7a | ||
|
|
07960e0c92
|
||
|
|
7afeb02b4d | ||
|
|
ecc38d207c | ||
|
|
d082a82e73 | ||
|
|
8f914714cb
|
||
|
|
ea2a2d53ef
|
||
|
|
6cc59537c0
|
||
|
|
a181d45ee8
|
||
|
|
e662c59cd5
|
||
|
|
1577313de5
|
||
|
|
498330b752
|
||
|
|
6002b003a0
|
||
|
|
4468b3e590 | ||
|
|
ab73f9c35c | ||
|
|
b990b898c7 | ||
|
|
2b3845e18c | ||
|
|
d9e8e946ac | ||
|
|
03b393bbae | ||
|
|
451f19f082 | ||
|
|
3c1c4bfffc | ||
|
|
c0141082bc | ||
|
|
6eb8e0aba2 | ||
|
|
7ea92e8cec
|
||
|
|
e34da438a6 | ||
|
|
595d4841d5 | ||
|
|
85a0dfabeb | ||
|
|
1d5ef1dd60 | ||
|
|
4e82d683d6
|
||
|
|
c7745ceb37 | ||
|
|
555246f00e
|
||
|
|
f2f3711faa
|
||
|
|
9fc2c8d90b | ||
|
|
0564cb1242 | ||
|
|
1221d4e318 | ||
|
|
7d233c126b | ||
|
|
bac0fc2cdd
|
||
|
|
fabbbf6073 |
@@ -62,6 +62,8 @@ homelab-v2/
|
|||||||
| **Archmirror** | Local Arch Linux package repository mirror |
|
| **Archmirror** | Local Arch Linux package repository mirror |
|
||||||
| **Blog** | Personal static blog served via git-sync + nginx (gh-pages branch) |
|
| **Blog** | Personal static blog served via git-sync + nginx (gh-pages branch) |
|
||||||
| **Vikunja** | To-do list and task management, SSO via Authelia OIDC |
|
| **Vikunja** | To-do list and task management, SSO via Authelia OIDC |
|
||||||
|
| **Reitti** | Personal location history and timeline (PostGIS), SSO via Authelia OIDC |
|
||||||
|
| **Dawarich** | Location history and timeline (PostGIS + Sidekiq), evaluated as a Reitti replacement; SSO via Authelia OIDC |
|
||||||
|
|
||||||
## Infrastructure Stack
|
## Infrastructure Stack
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ spec:
|
|||||||
value: ":514"
|
value: ":514"
|
||||||
useRemoteIP: true
|
useRemoteIP: true
|
||||||
useLocalTimestamp: true
|
useLocalTimestamp: true
|
||||||
|
# Scraped by the stack's vmagent so ingestion stalls can alert.
|
||||||
|
vmServiceScrape:
|
||||||
|
enabled: true
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
|
|||||||
@@ -59,10 +59,49 @@ spec:
|
|||||||
vmalert:
|
vmalert:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
# Telegram + email wired later (see monitoring-rpi5-setup.md step 11).
|
# k3s runs scheduler/controller-manager in one binary with no separate
|
||||||
# Default config uses a blackhole receiver until then.
|
# scrape endpoints, and uses kine instead of etcd — disabling these drops
|
||||||
|
# the empty scrape pools and their always-firing rules.
|
||||||
|
kubeScheduler:
|
||||||
|
enabled: false
|
||||||
|
kubeControllerManager:
|
||||||
|
enabled: false
|
||||||
|
kubeEtcd:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
alertmanager:
|
alertmanager:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
spec:
|
||||||
|
# Mounted at /etc/vm/secrets/alertmanager-telegram/ (bot_token, chat_id).
|
||||||
|
secrets:
|
||||||
|
- alertmanager-telegram
|
||||||
|
config:
|
||||||
|
route:
|
||||||
|
receiver: telegram
|
||||||
|
group_by: ["alertname", "job"]
|
||||||
|
group_wait: 30s
|
||||||
|
group_interval: 5m
|
||||||
|
repeat_interval: 12h
|
||||||
|
routes:
|
||||||
|
- receiver: blackhole
|
||||||
|
matchers:
|
||||||
|
- alertname=~"Watchdog|InfoInhibitor"
|
||||||
|
- receiver: blackhole
|
||||||
|
matchers:
|
||||||
|
- severity="info"
|
||||||
|
inhibit_rules:
|
||||||
|
- source_matchers:
|
||||||
|
- severity="critical"
|
||||||
|
target_matchers:
|
||||||
|
- severity="warning"
|
||||||
|
equal: ["alertname", "job"]
|
||||||
|
receivers:
|
||||||
|
- name: blackhole
|
||||||
|
- name: telegram
|
||||||
|
telegram_configs:
|
||||||
|
- bot_token_file: /etc/vm/secrets/alertmanager-telegram/bot_token
|
||||||
|
chat_id_file: /etc/vm/secrets/alertmanager-telegram/chat_id
|
||||||
|
send_resolved: true
|
||||||
|
|
||||||
grafana:
|
grafana:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: alertmanager-telegram
|
||||||
|
namespace: monitoring
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
bot_token: ENC[AES256_GCM,data:V/SDGyp/M7Qqa22fiKYMZ2CzkivNBl24hv9cVEFPl50NySKY0jqIPnVWLtm11g==,iv:UfHMfvu9b2CaXhImng5OLVej13zHrptKQOaPUbjXiw0=,tag:SFAGUaM0XYvbVc1CRrJepQ==,type:str]
|
||||||
|
chat_id: ENC[AES256_GCM,data:HRDHrCMMurk=,iv:hP7UB23qWZ+YukoP3B7QolUIfv2FgJtTfM1OLe/nMMY=,tag:JTwjQwDLQaG5LfKQGV73iw==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwNXF4V1N3bmpxbWN5YUVR
|
||||||
|
UDNNdm1IL2hHWGgzRENvK0xWdkhFc1drRGhBCjdQc3hydG1RN3ZocUZnZGpKRG5i
|
||||||
|
K1RXUTdiZ29hWWdjLzZVMCtMb1NZbjQKLS0tIHpDcTNDeFpJUU5CeU5PSFNWWnBo
|
||||||
|
UmJNT1hVL0h3c3hWOGQxM21uWk14amsKIyFxmszp94FteSUXyAh4hrDNbPBja4dT
|
||||||
|
QL6wFw8GkYtFeucIgnvbjHWWi98QMwE1xEt930uMeNyRnLFqFfUtWw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1jetw4h63gq4uzyk08znynw4h852nexdmtkdz4kwxj5ew5st32vnspmtag2
|
||||||
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
|
lastmodified: "2026-10-03T20:07:21Z"
|
||||||
|
mac: ENC[AES256_GCM,data:k7rBxhWrC2DFvFcoB6Wqufzk6vLtWFypITl/JK2qd6Vj9m7XKBZdiH5mCSDNfo4UK+ygFnGQ8oidkgcCrbGYqKFK8Q67+LQ9o1OMOXcZDkz6UzNRaLh3aO5NqbdleV36cICX6qpG1uO6GL6p5g121vRztQT+Qg1L0BkIMrF+sJQ=,iv:y8figgbzUg1gf0zug534Fvd9jdB00JiA7LoWXUm3/Lw=,tag:ccP3IKdWwMIJqP0s/U7NQA==,type:str]
|
||||||
|
version: 3.13.3
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
apiVersion: operator.victoriametrics.com/v1beta1
|
||||||
|
kind: VMRule
|
||||||
|
metadata:
|
||||||
|
name: homelab
|
||||||
|
namespace: monitoring
|
||||||
|
spec:
|
||||||
|
groups:
|
||||||
|
- name: unifi-gateway
|
||||||
|
rules:
|
||||||
|
# Baseline load is 2–5; the 2026-09-26 memory-pressure incident sat at 15–25.
|
||||||
|
- alert: UnifiGatewayHighLoad
|
||||||
|
expr: avg_over_time(unpoller_device_load_average_1{type="udm"}[15m]) > 10
|
||||||
|
for: 15m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "UniFi gateway load is {{ $value | humanize }} (15m avg)"
|
||||||
|
# Baseline is 84–92% and creeps up ~1%/3 days until something restarts.
|
||||||
|
- alert: UnifiGatewayMemoryHigh
|
||||||
|
expr: avg_over_time(unpoller_device_memory_utilization_ratio{type="udm"}[30m]) > 0.93
|
||||||
|
for: 30m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "UniFi gateway memory at {{ $value | humanizePercentage }} (30m avg)"
|
||||||
|
- name: victoria-logs
|
||||||
|
rules:
|
||||||
|
# The gateway alone logs DHCP chatter every few minutes, so zero rows
|
||||||
|
# means the syslog path is broken (e.g. the 2026-09-22 IP change).
|
||||||
|
- alert: SyslogIngestionStalled
|
||||||
|
expr: sum(rate(vl_rows_ingested_total{type="syslog_udp"}[30m])) == 0
|
||||||
|
for: 15m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "VictoriaLogs has received no syslog for 45m"
|
||||||
@@ -6,6 +6,8 @@ metadata:
|
|||||||
namespace: archmirror
|
namespace: archmirror
|
||||||
data:
|
data:
|
||||||
nginx.conf: |
|
nginx.conf: |
|
||||||
|
worker_processes auto;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 1024;
|
worker_connections 1024;
|
||||||
}
|
}
|
||||||
@@ -15,6 +17,8 @@ data:
|
|||||||
default_type application/octet-stream;
|
default_type application/octet-stream;
|
||||||
|
|
||||||
sendfile on;
|
sendfile on;
|
||||||
|
# NFS reads block the worker; offload them so /health keeps answering
|
||||||
|
aio threads;
|
||||||
gzip on;
|
gzip on;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dawarich-redis
|
||||||
|
namespace: dawarich
|
||||||
|
labels:
|
||||||
|
app: dawarich-redis
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dawarich-redis
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999 # redis user in the alpine image
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: redis:7.4.11-alpine
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
# Sidekiq job queue. Snapshots (as in upstream compose) survive container restarts;
|
||||||
|
# the emptyDir is lost with the pod, which only drops queued jobs.
|
||||||
|
args: ["--save", "900", "1", "--save", "300", "10", "--appendonly", "no"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
name: redis
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 30
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 10
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 20m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: dawarich
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny-ingress
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-controller
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: traefik
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-app-to-db
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-db
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-backup-to-db
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-db
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-backup
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-backup-egress
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-backup
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 8888
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 443
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 5432
|
||||||
|
protocol: TCP
|
||||||
|
to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-db
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-app-to-redis
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-redis
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||||
|
kind: HelmRelease
|
||||||
|
metadata:
|
||||||
|
name: dawarich
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
chart:
|
||||||
|
spec:
|
||||||
|
chart: dawarich
|
||||||
|
version: 2.9.3
|
||||||
|
reconcileStrategy: ChartVersion
|
||||||
|
sourceRef:
|
||||||
|
kind: HelmRepository
|
||||||
|
name: cogitri
|
||||||
|
namespace: flux-system
|
||||||
|
targetNamespace: dawarich
|
||||||
|
interval: 1m0s
|
||||||
|
install:
|
||||||
|
remediation:
|
||||||
|
retries: 3
|
||||||
|
upgrade:
|
||||||
|
remediation:
|
||||||
|
retries: 3
|
||||||
|
# The chart hardcodes an unpinned busybox wait-for-postgres init container, no deployment
|
||||||
|
# strategy, and a 130s web startupProbe — too short for the first start, which runs every
|
||||||
|
# migration and seeds the countries table before Puma listens.
|
||||||
|
postRenderers:
|
||||||
|
- kustomize:
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
kind: Deployment
|
||||||
|
name: dawarich
|
||||||
|
patch: |
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dawarich
|
||||||
|
spec:
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: wait-for-postgres
|
||||||
|
image: busybox:1.37
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
containers:
|
||||||
|
- name: dawarich
|
||||||
|
startupProbe:
|
||||||
|
failureThreshold: 60
|
||||||
|
livenessProbe:
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 10
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
timeoutSeconds: 5
|
||||||
|
- target:
|
||||||
|
kind: Deployment
|
||||||
|
name: dawarich-sidekiq
|
||||||
|
patch: |
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: dawarich-sidekiq
|
||||||
|
spec:
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: wait-for-postgres
|
||||||
|
image: busybox:1.37
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
values:
|
||||||
|
# Release name is dawarich-dawarich (targetNamespace prefix); keep resource names short.
|
||||||
|
fullnameOverride: dawarich
|
||||||
|
|
||||||
|
image:
|
||||||
|
# renovate: datasource=docker depName=freikin/dawarich
|
||||||
|
tag: "1.21.0"
|
||||||
|
|
||||||
|
keyBase:
|
||||||
|
existingSecret: dawarich-credentials # key: value
|
||||||
|
|
||||||
|
# Every key is rendered into the ConfigMap as UPPER_SNAKE_CASE.
|
||||||
|
env:
|
||||||
|
timeZone: Europe/Kyiv
|
||||||
|
# TLS terminates at Traefik; "https" here turns on Rails force_ssl.
|
||||||
|
applicationProtocol: http
|
||||||
|
distanceUnit: km
|
||||||
|
# Upstream compose default; each thread holds an import batch in memory.
|
||||||
|
backgroundProcessingConcurrency: "3"
|
||||||
|
# OIDC-only login (blocks the web form and the API password sign-in since 1.14.4).
|
||||||
|
allowEmailPasswordLogin: "false"
|
||||||
|
|
||||||
|
# Authentication against Authelia over OIDC only. Unknown Authelia users are auto-created
|
||||||
|
# as regular (non-admin) users.
|
||||||
|
oidc:
|
||||||
|
enabled: true
|
||||||
|
providerName: Authelia
|
||||||
|
clientId:
|
||||||
|
existingSecret: dawarich-credentials
|
||||||
|
existingSecretKeyName: OIDC_CLIENT_ID
|
||||||
|
clientSecret:
|
||||||
|
existingSecret: dawarich-credentials
|
||||||
|
existingSecretKeyName: OIDC_CLIENT_SECRET
|
||||||
|
issuer: https://auth.${AUTHELIA_DOMAIN}
|
||||||
|
redirectUri: https://${DAWARICH_HOST}/users/auth/openid_connect/callback
|
||||||
|
autoRegister: true
|
||||||
|
allowEmailPasswordRegistration: false
|
||||||
|
|
||||||
|
dawarich:
|
||||||
|
hosts:
|
||||||
|
- ${DAWARICH_HOST}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 512Mi
|
||||||
|
limits:
|
||||||
|
memory: 2Gi
|
||||||
|
|
||||||
|
sidekiq:
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 512Mi
|
||||||
|
limits:
|
||||||
|
memory: 4Gi # imports parse whole files in memory (Google Records.json)
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
host: dawarich-db
|
||||||
|
auth:
|
||||||
|
database: dawarich
|
||||||
|
existingSecret: dawarich-credentials # keys: username, password
|
||||||
|
|
||||||
|
# Own single Redis (deployment-redis.yaml) instead of the bundled 3-node redis-ha.
|
||||||
|
redis:
|
||||||
|
enabled: false
|
||||||
|
host: dawarich-redis
|
||||||
|
auth: false
|
||||||
|
|
||||||
|
# RWO volumes shared by web and sidekiq — fine on the single node.
|
||||||
|
persistence:
|
||||||
|
public:
|
||||||
|
# Static assets, re-synced from the image on every web start.
|
||||||
|
storageClass: nfs-synology-ssd
|
||||||
|
size: 1Gi
|
||||||
|
watched:
|
||||||
|
# Drop folder: <user-email>/<file> is auto-imported.
|
||||||
|
storageClass: nfs-synology-ssd
|
||||||
|
size: 1Gi
|
||||||
|
storage:
|
||||||
|
# ActiveStorage: uploaded imports, exports, videos.
|
||||||
|
storageClass: nfs-synology-ssd
|
||||||
|
size: 10Gi
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
automount: false
|
||||||
|
|
||||||
|
podLabels:
|
||||||
|
app: dawarich
|
||||||
|
|
||||||
|
# The image starts as root only to chown volumes and gosu-drop when PUID/PGID are set.
|
||||||
|
# Running as 1000 directly skips that; tmp/ is 0777 in the image and the NFS subdir
|
||||||
|
# provisioner creates directories 0777.
|
||||||
|
podSecurityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
# No Authelia forward-auth middleware — Dawarich authenticates against Authelia
|
||||||
|
# natively over OIDC. A middleware here would break the OIDC callback and the
|
||||||
|
# api_key-authenticated /api ingest endpoints (OwnTracks, Overland, mobile app).
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt
|
||||||
|
hosts:
|
||||||
|
- host: ${DAWARICH_HOST}
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: dawarich-tls
|
||||||
|
hosts:
|
||||||
|
- ${DAWARICH_HOST}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"kubernetes": {
|
||||||
|
"fileMatch": ["kubernetes/app/dawarich/.+\\.yaml$"]
|
||||||
|
},
|
||||||
|
"customManagers": [
|
||||||
|
{
|
||||||
|
"customType": "regex",
|
||||||
|
"fileMatch": ["kubernetes/app/dawarich/release\\.yaml$"],
|
||||||
|
"matchStrings": [
|
||||||
|
"#\\s*renovate:\\s*datasource=(?<datasource>\\S+)\\s+depName=(?<depName>\\S+)\\s*\\n\\s*tag:\\s*[\"']?(?<currentValue>[^\\s\"']+)"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchFileNames": ["kubernetes/app/dawarich/**"],
|
||||||
|
"semanticCommitScope": "k8s/dawarich"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchFileNames": ["kubernetes/app/dawarich/**"],
|
||||||
|
"matchPackageNames": ["freikin/dawarich"],
|
||||||
|
"matchUpdateTypes": ["patch", "minor"],
|
||||||
|
"automerge": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchFileNames": ["kubernetes/app/dawarich/**"],
|
||||||
|
"matchPackageNames": ["freikin/dawarich"],
|
||||||
|
"matchUpdateTypes": ["major"],
|
||||||
|
"automerge": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Ignore infrastructure images",
|
||||||
|
"matchFileNames": ["kubernetes/app/dawarich/**"],
|
||||||
|
"matchPackageNames": ["postgis/postgis", "redis", "creativeprojects/resticprofile"],
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: source.toolkit.fluxcd.io/v1
|
||||||
|
kind: HelmRepository
|
||||||
|
metadata:
|
||||||
|
name: cogitri
|
||||||
|
namespace: flux-system
|
||||||
|
spec:
|
||||||
|
interval: 1m0s
|
||||||
|
url: https://charts.cogitri.dev
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: dawarich-credentials
|
||||||
|
namespace: dawarich
|
||||||
|
stringData:
|
||||||
|
#ENC[AES256_GCM,data:3gPe9ezMvEnV02kKbZkjtsq2FmJJzXmhtp6CfwYh8icAv/PdAwa3DQCu0oRbgkIV9claZCqDSrhPIaYy5wsQUshL8hyGUYDm/mLNVDsAl9HPz6MlDA==,iv:QOG8JpMEA3IYlcLyrWM8yH9ZHbpwNM1EpC+02J8PCDU=,tag:eIGomi40Pe+7MSOU8POO4w==,type:comment]
|
||||||
|
username: ENC[AES256_GCM,data:Tpj/Iq4oLlg=,iv:9RORl+XlNqG87y3qsqCNj/oRrLzmdVlZCAXD4R1RfXY=,tag:67MSd0HIYEhTqQYfDNUJ2g==,type:str]
|
||||||
|
password: ENC[AES256_GCM,data:BhB59Y5J5pKobyKWOsIWP8jMxPzkL12TkFrTJuCGexw=,iv:VDJdyx7dyHgZh/doBTxBfAiN3NqzmvdCz3Hpxwsafac=,tag:AUtd1ubgOWMbgxm2FzfDpw==,type:str]
|
||||||
|
value: ENC[AES256_GCM,data:Ok4GM6+qnZSQ3c9fyedlXE+LlAoSzIvIQMrCSKLPGp3TQT6PpbouXbR0QveZWZgROmexn0YMs62WCkCdfNfv2DC7SooJ+EksWHKi/m8UTWay7X/WYBlMmSClS3/MeFwsRz5/G4MayIT166C6OhXKB2rPicRMzlU+3dbL9MBDLpw=,iv:gi6C0rbYy3Ie6ati6ACnlqeXjONR/HC3o8xmPGUIF/Y=,tag:jcAQ3YSWZ1DZqr8u+KIBWg==,type:str]
|
||||||
|
OIDC_CLIENT_ID: ENC[AES256_GCM,data:qddOrkEvw0g=,iv:NrS1vRqZG3/4cQyWtEONu16GbFlHJplcHVc75h7+CpQ=,tag:l5Fu5vsPiU6rFGFWziCnzg==,type:str]
|
||||||
|
OIDC_CLIENT_SECRET: ENC[AES256_GCM,data:uisMM3Gd6ChnLvg/eyxff9ZGq6uAfs9fryuVOgf+ZGVexKoRn0NT1Ic7rpJ9pUwzhTAO6WGo941MdJmkSxbxXw==,iv:HNZhiPMTMk/aG7Z9hr0r97CFzo8C0PKRL3FtIW2vGns=,tag:+sbLFE2zbdn4M4eyWrvqTA==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTSUdIeXZKNDBVcXVURWpz
|
||||||
|
Wmwrd1hWb0tTcDFmMWZHVG4vZmFmUDNZUnhjCk1PVzQ2RG5Qa2VQZk5PV1VwS09M
|
||||||
|
YUdzVWtsc3dJY256dzRkUTMxdG83OGsKLS0tIERBVVRXTTBsYk1jTTRadmNoOHM0
|
||||||
|
c1F5Q1RsQ1Y1SW9rQUw1ZkwrVVREV1UKI0bO6Nq92fPVPqImWMtWCe5s4r5pLGAf
|
||||||
|
6FWWzTkerOnQ4n7iGoAPtnuFbo6wUBypm4yirbgX6ErzU5vTWJWHWw==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
|
lastmodified: "2026-10-08T10:16:10Z"
|
||||||
|
mac: ENC[AES256_GCM,data:HcMG1/LqcljJ6b6LZvXZqKdT3LGFNikH/1PQKzxL+71lwSqlg3k5L0pDNObSfRZeYMeCQTMJWCzgt2qlUlpML58DFTRC0B6K3bofHJixhJT1cS62rzngR0iRY4KVepI6qZACfTh8mwzt15Zrpy9ZMRvV1GSwnxpgaXJVyCMqWnw=,iv:7GHyXB1nA1WAbkI396l4Vw5RtcsYW9n70b+ybOUo6ds=,tag:YbqsKjek9ZnExzghSupuDw==,type:str]
|
||||||
|
version: 3.13.3
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dawarich-db
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
clusterIP: None
|
||||||
|
selector:
|
||||||
|
app: dawarich-db
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: dawarich-redis
|
||||||
|
namespace: dawarich
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: dawarich-redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
|
name: redis
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: dawarich-db
|
||||||
|
namespace: dawarich
|
||||||
|
labels:
|
||||||
|
app: dawarich-db
|
||||||
|
spec:
|
||||||
|
serviceName: dawarich-db
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: dawarich-db
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: dawarich-db
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
fsGroup: 999
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
# Dawarich requires PostGIS; the Debian variant keeps the postgres user at UID 999
|
||||||
|
# (the alpine variant upstream uses has 70). The image creates the postgis extension in POSTGRES_DB.
|
||||||
|
image: postgis/postgis:17-3.5
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dawarich-credentials
|
||||||
|
key: username
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: dawarich-credentials
|
||||||
|
key: password
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: dawarich
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
startupProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 5432
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 30
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 5432
|
||||||
|
periodSeconds: 30
|
||||||
|
failureThreshold: 5
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 5432
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
memory: 2Gi # includes the 1Gi /dev/shm below
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
- name: shm
|
||||||
|
mountPath: /dev/shm
|
||||||
|
volumes:
|
||||||
|
# Upstream compose sets shm_size: 1G — parallel queries over the points table
|
||||||
|
# exceed the 64M container default.
|
||||||
|
- name: shm
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
sizeLimit: 1Gi
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: data
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
storageClassName: nfs-synology-ssd
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
@@ -26,7 +26,7 @@ spec:
|
|||||||
|
|
||||||
image:
|
image:
|
||||||
# renovate: datasource=docker depName=fireflyiii/core
|
# renovate: datasource=docker depName=fireflyiii/core
|
||||||
tag: version-6.6.6
|
tag: version-6.7.9
|
||||||
|
|
||||||
podSecurityContext:
|
podSecurityContext:
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
|
|||||||
@@ -25,8 +25,10 @@ spec:
|
|||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
|
set -e
|
||||||
apk add --no-cache sqlite
|
apk add --no-cache sqlite
|
||||||
sqlite3 /db-local/grocy.db ".backup /backup/grocy.db"
|
sqlite3 "file:/db-local/grocy.db?mode=ro" ".backup /backup/grocy.db"
|
||||||
|
[ "$(sqlite3 /backup/grocy.db 'PRAGMA integrity_check')" = ok ]
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: db
|
- name: db
|
||||||
mountPath: /db-local
|
mountPath: /db-local
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ data:
|
|||||||
type: jellyfin
|
type: jellyfin
|
||||||
url: https://${JELLYFIN_HOST}
|
url: https://${JELLYFIN_HOST}
|
||||||
key: "{{HOMEPAGE_VAR_JELLYFIN_API_KEY}}"
|
key: "{{HOMEPAGE_VAR_JELLYFIN_API_KEY}}"
|
||||||
|
version: 2 # Jellyfin 12 dropped /emby paths and ?api_key auth
|
||||||
enableBlocks: true
|
enableBlocks: true
|
||||||
enableUser: true
|
enableUser: true
|
||||||
enableMediaControl: false
|
enableMediaControl: false
|
||||||
@@ -94,6 +95,10 @@ data:
|
|||||||
icon: vikunja.png
|
icon: vikunja.png
|
||||||
href: https://${VIKUNJA_HOST}/
|
href: https://${VIKUNJA_HOST}/
|
||||||
description: Task management
|
description: Task management
|
||||||
|
- Reitti:
|
||||||
|
icon: mdi-map-marker-path
|
||||||
|
href: https://${REITTI_HOST}/
|
||||||
|
description: Location history
|
||||||
|
|
||||||
widgets.yaml: |
|
widgets.yaml: |
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: homepage
|
- name: homepage
|
||||||
image: ghcr.io/gethomepage/homepage:v2.3.0
|
image: ghcr.io/gethomepage/homepage:v2.7.0
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 3000
|
- containerPort: 3000
|
||||||
name: http
|
name: http
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ spec:
|
|||||||
main:
|
main:
|
||||||
image:
|
image:
|
||||||
repository: ghcr.io/immich-app/immich-server
|
repository: ghcr.io/immich-app/immich-server
|
||||||
tag: v3.2.0
|
tag: v3.3.6
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
# The volume is mounted read-write on purpose: jellyfin.db is in WAL mode, and
|
# The volume is mounted read-write on purpose: jellyfin.db is in WAL mode, and
|
||||||
# SQLite cannot open a WAL database from a read-only filesystem once Jellyfin has
|
# SQLite cannot open a WAL database from a read-only filesystem once Jellyfin has
|
||||||
# closed it and removed the -wal/-shm files (e.g. while scaled to zero).
|
# closed it and removed the -wal/-shm files (e.g. while scaled to zero).
|
||||||
|
# The connection itself is read-only (?mode=ro). A read-write connection that
|
||||||
|
# believes it is the last one checkpoints and deletes -wal/-shm on close; when
|
||||||
|
# Jellyfin had lost its POSIX locks this deleted them under the running server
|
||||||
|
# and corrupted jellyfin.db (2026-09-16). The copy is integrity-checked so a
|
||||||
|
# broken snapshot fails the job instead of landing in restic.
|
||||||
apiVersion: batch/v1
|
apiVersion: batch/v1
|
||||||
kind: CronJob
|
kind: CronJob
|
||||||
metadata:
|
metadata:
|
||||||
@@ -34,7 +39,8 @@ spec:
|
|||||||
- |
|
- |
|
||||||
set -e
|
set -e
|
||||||
apk add --no-cache sqlite
|
apk add --no-cache sqlite
|
||||||
sqlite3 /db-local/jellyfin.db ".backup /backup/jellyfin.db"
|
sqlite3 "file:/db-local/jellyfin.db?mode=ro" ".backup /backup/jellyfin.db"
|
||||||
|
[ "$(sqlite3 /backup/jellyfin.db 'PRAGMA integrity_check')" = ok ]
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: db
|
- name: db
|
||||||
mountPath: /db-local
|
mountPath: /db-local
|
||||||
@@ -84,7 +90,8 @@ spec:
|
|||||||
# media files and the metadata providers.
|
# media files and the metadata providers.
|
||||||
# Intro Skipper keeps its results in two live WAL-mode SQLite databases, so they
|
# Intro Skipper keeps its results in two live WAL-mode SQLite databases, so they
|
||||||
# are snapshotted with sqlite3 ".backup" rather than copied as files (which could
|
# are snapshotted with sqlite3 ".backup" rather than copied as files (which could
|
||||||
# capture a torn page mid-write). Read-write mount for the same reason as above.
|
# capture a torn page mid-write). Read-write mount and read-only connection for
|
||||||
|
# the same reasons as above.
|
||||||
apiVersion: batch/v1
|
apiVersion: batch/v1
|
||||||
kind: CronJob
|
kind: CronJob
|
||||||
metadata:
|
metadata:
|
||||||
@@ -116,7 +123,8 @@ spec:
|
|||||||
apk add --no-cache sqlite
|
apk add --no-cache sqlite
|
||||||
mkdir -p /backup/introskipper
|
mkdir -p /backup/introskipper
|
||||||
for db in introskipper.db introskipper-cache.db; do
|
for db in introskipper.db introskipper-cache.db; do
|
||||||
sqlite3 "/config/data/introskipper/$db" ".backup /backup/introskipper/$db"
|
sqlite3 "file:/config/data/introskipper/$db?mode=ro" ".backup /backup/introskipper/$db"
|
||||||
|
[ "$(sqlite3 "/backup/introskipper/$db" 'PRAGMA integrity_check')" = ok ]
|
||||||
done
|
done
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: config
|
- name: config
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ spec:
|
|||||||
mountPath: /db-local
|
mountPath: /db-local
|
||||||
containers:
|
containers:
|
||||||
- name: jellyfin
|
- name: jellyfin
|
||||||
image: jellyfin/jellyfin:12.0
|
image: jellyfin/jellyfin:12.4
|
||||||
env:
|
env:
|
||||||
- name: JELLYFIN_PublishedServerUrl
|
- name: JELLYFIN_PublishedServerUrl
|
||||||
value: https://${JELLYFIN_HOST}
|
value: https://${JELLYFIN_HOST}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ spec:
|
|||||||
values:
|
values:
|
||||||
image:
|
image:
|
||||||
# renovate: datasource=docker depName=ghcr.io/hargata/lubelogger
|
# renovate: datasource=docker depName=ghcr.io/hargata/lubelogger
|
||||||
tag: "v1.7.3"
|
tag: "v1.7.4"
|
||||||
|
|
||||||
updateStrategy:
|
updateStrategy:
|
||||||
type: RollingUpdate
|
type: RollingUpdate
|
||||||
|
|||||||
@@ -45,10 +45,13 @@ spec:
|
|||||||
- psql -d postgres -c 'CREATE DATABASE "prowlarr-log"' || true
|
- psql -d postgres -c 'CREATE DATABASE "prowlarr-log"' || true
|
||||||
containers:
|
containers:
|
||||||
- name: prowlarr
|
- name: prowlarr
|
||||||
image: lscr.io/linuxserver/prowlarr:2.5.2
|
image: lscr.io/linuxserver/prowlarr:2.7.0
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: media-common-env
|
name: media-common-env
|
||||||
|
env:
|
||||||
|
- name: PROWLARR__SERVER__TRUSTEDNETWORKS
|
||||||
|
value: ${POD_CIDR}
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9696
|
- containerPort: 9696
|
||||||
name: http
|
name: http
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ spec:
|
|||||||
mountPath: /media
|
mountPath: /media
|
||||||
containers:
|
containers:
|
||||||
- name: qbittorrent
|
- name: qbittorrent
|
||||||
image: lscr.io/linuxserver/qbittorrent:5.2.3
|
image: lscr.io/linuxserver/qbittorrent:5.3.0
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: media-common-env
|
name: media-common-env
|
||||||
|
|||||||
@@ -54,10 +54,13 @@ spec:
|
|||||||
- psql -d postgres -c 'CREATE DATABASE "radarr-log"' || true
|
- psql -d postgres -c 'CREATE DATABASE "radarr-log"' || true
|
||||||
containers:
|
containers:
|
||||||
- name: radarr
|
- name: radarr
|
||||||
image: lscr.io/linuxserver/radarr:6.3.0
|
image: lscr.io/linuxserver/radarr:6.4.4
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: media-common-env
|
name: media-common-env
|
||||||
|
env:
|
||||||
|
- name: RADARR__SERVER__TRUSTEDNETWORKS
|
||||||
|
value: ${POD_CIDR}
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 7878
|
- containerPort: 7878
|
||||||
name: http
|
name: http
|
||||||
|
|||||||
@@ -54,10 +54,13 @@ spec:
|
|||||||
- psql -d postgres -c 'CREATE DATABASE "sonarr-log"' || true
|
- psql -d postgres -c 'CREATE DATABASE "sonarr-log"' || true
|
||||||
containers:
|
containers:
|
||||||
- name: sonarr
|
- name: sonarr
|
||||||
image: lscr.io/linuxserver/sonarr:4.0.19
|
image: lscr.io/linuxserver/sonarr:4.0.20
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: media-common-env
|
name: media-common-env
|
||||||
|
env:
|
||||||
|
- name: SONARR__SERVER__TRUSTEDNETWORKS
|
||||||
|
value: ${POD_CIDR}
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8989
|
- containerPort: 8989
|
||||||
name: http
|
name: http
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ spec:
|
|||||||
targetNamespace: media
|
targetNamespace: media
|
||||||
values:
|
values:
|
||||||
image:
|
image:
|
||||||
tag: v3.4.1
|
tag: v3.5.1
|
||||||
podLabels:
|
podLabels:
|
||||||
app: seerr
|
app: seerr
|
||||||
extraEnv:
|
extraEnv:
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: tika
|
- name: tika
|
||||||
image: apache/tika:3.3.1.0
|
image: apache/tika:3.3.3.0
|
||||||
env:
|
env:
|
||||||
- name: TZ
|
- name: TZ
|
||||||
value: Europe/Kyiv
|
value: Europe/Kyiv
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: paperless
|
- name: paperless
|
||||||
image: ghcr.io/paperless-ngx/paperless-ngx:3.1
|
image: ghcr.io/paperless-ngx/paperless-ngx:3.4
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
name: http
|
name: http
|
||||||
@@ -86,6 +86,31 @@ spec:
|
|||||||
value: allauth.socialaccount.providers.openid_connect
|
value: allauth.socialaccount.providers.openid_connect
|
||||||
- name: PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS
|
- name: PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS
|
||||||
value: "false"
|
value: "false"
|
||||||
|
- name: PAPERLESS_AI_ENABLED
|
||||||
|
value: "true"
|
||||||
|
- name: PAPERLESS_AI_LLM_BACKEND
|
||||||
|
value: openai-like
|
||||||
|
- name: PAPERLESS_AI_LLM_ENDPOINT
|
||||||
|
value: https://api.anthropic.com/v1/
|
||||||
|
- name: PAPERLESS_AI_LLM_MODEL
|
||||||
|
value: claude-haiku-5-5
|
||||||
|
- name: PAPERLESS_AI_LLM_API_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: paperless-ai
|
||||||
|
key: anthropic-api-key
|
||||||
|
# Haiku 5.5 only accepts temperature 1; llama-index defaults to 0.1
|
||||||
|
- name: PAPERLESS_AI_LLM_EXTRA_PARAMS
|
||||||
|
value: '{"temperature": 1}'
|
||||||
|
- name: PAPERLESS_AI_LLM_OUTPUT_LANGUAGE
|
||||||
|
value: Ukrainian
|
||||||
|
- name: PAPERLESS_AI_LLM_EMBEDDING_BACKEND
|
||||||
|
value: huggingface
|
||||||
|
- name: PAPERLESS_AI_LLM_EMBEDDING_MODEL
|
||||||
|
value: intfloat/multilingual-e5-small
|
||||||
|
# matches the embedding model's 512-token input limit
|
||||||
|
- name: PAPERLESS_AI_LLM_EMBEDDING_CHUNK_SIZE
|
||||||
|
value: "512"
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: data
|
- name: data
|
||||||
mountPath: /usr/src/paperless/data
|
mountPath: /usr/src/paperless/data
|
||||||
@@ -110,9 +135,9 @@ spec:
|
|||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
memory: 512Mi
|
memory: 1536Mi
|
||||||
limits:
|
limits:
|
||||||
memory: 5Gi
|
memory: 6Gi
|
||||||
volumes:
|
volumes:
|
||||||
- name: data
|
- name: data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: paperless-ai
|
||||||
|
namespace: paperless
|
||||||
|
stringData:
|
||||||
|
anthropic-api-key: ENC[AES256_GCM,data:kTSTHIO771Zl8/kEyv1seKF1GyodZ4lxhjUSjsyIyCneC+aFdqrq/QYFnqtlQnjBOMq94LQxy0T4Ox2an2+0v2ywP+lIZzYDkE22JdXgbJgCW2aJTBqPtEFV7M2EP0LexDeD2aqebwicxA==,iv:IeO0+Y3jAL0iYM3UbpTtFU7TgqogUYt2gipYUJO2ABQ=,tag:qffHT+GkrNWFmJ1EffHEWg==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4Nzg2Zmc4ZVNvRzhzQmVp
|
||||||
|
Mlp6MXhRUExmOU1yWHRESmhBQWlsczZCZEQ0CmkvZDEzVTFwWmt6N3E5eXlsQ0d5
|
||||||
|
VDU1YWIvRDdocXFQNlhnK29CNDVtME0KLS0tIEMybTgzaGs4cVEyeTdEL1RPUmR3
|
||||||
|
S2VvK2FMZ0JnQWJUZG41MmIrRjkxVHcKzjclDColGY9ciQZPRodQrH8UkmsHTsTC
|
||||||
|
hExT/sbhwIznhryfzw/Wkgrm8bzH4NxEkjOWRXvEEJ7Fp5gkvfo0tQ==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
|
lastmodified: "2026-10-10T18:39:57Z"
|
||||||
|
mac: ENC[AES256_GCM,data:SG3jk09+cI2mYvovl8PvT5Ay8QrD/wWYVJAdJWhE83bI+MgwgoXvkdW9B+3epcIfvNWV4Z83w2vS89+bo5k81CEIu66yAQPDA+wSCReiRalZdHYGidmnW5ZccmfjTGTNRIIY8RbJlB2ZW6EJJnjjT8Bp4wZskIk5EhGhU2+5jg8=,iv:XeyO9yKzZv6qHwe3LfBqqeRJ3gnU1AmGmeVv3Zp/UyY=,tag:xCgbaWR4fd738hF2T/QVAw==,type:str]
|
||||||
|
version: 3.13.3
|
||||||
@@ -27,7 +27,7 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
containers:
|
containers:
|
||||||
- name: pihole
|
- name: pihole
|
||||||
image: pihole/pihole:2026.02.0
|
image: pihole/pihole:2026.07.2
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: pihole-config
|
name: pihole-config
|
||||||
@@ -95,7 +95,7 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
|
|
||||||
- name: dnscrypt-proxy
|
- name: dnscrypt-proxy
|
||||||
image: klutchell/dnscrypt-proxy:v2.1.15
|
image: klutchell/dnscrypt-proxy:v2.1.18
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
env:
|
env:
|
||||||
- name: TZ
|
- name: TZ
|
||||||
|
|||||||
@@ -4,19 +4,19 @@ metadata:
|
|||||||
name: podsync-config
|
name: podsync-config
|
||||||
namespace: podsync
|
namespace: podsync
|
||||||
data:
|
data:
|
||||||
config.toml: ENC[AES256_GCM,data:4C8zSvWM9kMxII0RU9EhfUvQGgZMJTtMUOVM9LGunfpkmZQjH3IrbsytgzZBbw7ha7IHjhLxvdXleHNXbc2ZCbphp/lhIrqOLsa2f8J/P/ppyJVLafEt+bQB4lVXVauhy72bV/9RZYIgCatDYMR7+sJVWGyl1f6ZnJ3S+nVXROXPmlxlDhJnCwPUVj+OVq7OKnDjspZpnlZizr5tRzMMJPVuVTDi9cKDFHnoL2x7iINyzvJk8Wb4N+k481sY7isJ5BJyTno3RNKhcykL8cfZQunQ1mlBodvZiSph1gAxY3H3oljb2uB0Zf4J3FkpSCPkIQBpGec+NiQAjPRk5zot0VCZVvtAEL1UfctvhcnhbMwNQbEfdvewFXbIF6lwuatI/gd2+ICuas19n6luzwAfw+WGOHtEDbsIccl6l9lfphid7TotKs992LqBVL3BuCoGM4kqe/8QZc+iaw2VbjGxJhim9T0NnvvPlj8WJ/hnOy+e4wLmzKZcryUNjqQdpzlPr/CFwlnKgU26zjyb6438vf0mC06Mp1AHCoqznZkLPOeJC7YeEybf0T2Dm1/7e0iBFVFVSX3zCUQ0fS1vCyulszUUNsJtAsgg/KkqDSiqT6YWWsUaDZ5qbkcIsQNBFcQVX3Owm7x2tcppi9xYOCFfIDxAx0ugx6kKTf/4XfZ4yIRyUhIETny3P/4WoHCzIz6Hd65RaxbIwbyRz8U8mFbsDtk3o+7c/6UsX1uEFJjoFFlrOcy9ID1um8LXGxicB6VdrtNfwWiFq9Vwf+eHdKFMC5fSqtuSu/yDHKC8w2eb98IG9k0rf+4NHzRlxYPhCUs8YJsWJYpXC4tK8fPWLg7zuByf8nnUQ405Ga8ZvcuDQ9xDWFtMg8JJoZ1wODHIJiovIxNlZQmuxGrrpI5+S4CZKVjEVgD7GRXn3ewDVMk8Tdaf1iq0x09cxj52rgf3VxeOiVolrNJgzygePvYSxb30nsMpQSmmLCGCp5viJ0FhH6MuccJK9wmzJiEYuC5OkhGHaQLkAUDdroZTBDek/AQGzdu8J+NL+Qk3KuJ1ZQs1xgzpB74vqAdjAUUNzZlDw5hejv7enjstTjU1usy88Y8Lf1AORHiGcLzxpwjdeQQFsTuBqPVCHs7Nt9xYYk5nbv8wXM8Z7gk/+SMJayTOq5PDfLZNd530M1rMBIZ1HSBvYsAQvGVd91xjoMvMs04VCoGZcFZuurukx9Rh6U/5pm5roIXkmWHFp/2S3HfnBqEbQYbqrV5jXGQs6yIEQcRT91UY7csdnDL9fzlR37T21cOXfo2CrCzZyaTfGh+y6GusC9xg9qaBihno+PxOV++h80Nd5MsYSXIjaXTX8CioKaCMCToEXHzWUUsr+tHopMR0fG+QJAiZ2Fa7c5dYAU2EKkyfziuhGPSxHBxrc9W/0VjfB10Vf+iFVGCP2JEm99G7esQNh9kszSkyY2wOycUllqQO3eT9dHsSFdswq/bvKgkvQz0oOmJcubE1jvUn7YW8CF6KABlM5L/hi+ntcNc2YWLWqaNghOQsjCbpiqjdp6pejiM9g+3NbC7O2Z8Nf0zwgka7FRQXaJfl+FHFb3X2Qk4VGiinoK+EVCQX4CCD9EYK065jkdTpqDDESy1n4SUMIkE2iA==,iv:cpa826ZkBPSc/ZX4P6sJ5kgDXMfryd+d3UAsbfb7764=,tag:V3FERsM9ZfNO8TbHEsf86w==,type:str]
|
config.toml: ENC[AES256_GCM,data:MvMimo9Cn94BXQzCQqnlt3z0aSzoDwq5t2I9OHXATGuX2+q7lTksBMh3Vz5CHm5YY9xvXtPqO5kRPtoYuaDwvsM3vWe9zXclThJOQJqND/haV188yvoDw1jCWe7a2zGQ3SsgpJYBncZJ44/cMYn9mWj7wXdUegFOFfi/4g+xGBZ2c4aQmJAD5lHz3PJW9WrDYqlfBbX8Ipt1OQtZd1FKHSTmbifqvzoLv34qUKxz/LY9RiFOpBNXRhH53aDRpiMuHdtl4I9eFZi4B/EXqhdFZXLCTAKMi2bDT2xSHkefAfexvyHzV0Uv2z+ZWdzuUua/S17JHkA53sIxMk60bkE9VU8JDuStqRGj1kZy7dgGoKZceuK7O7SF9RMj6f/zsnmAYhye65T0EziK764TqEMibOL/tgfOMSmQcEae4+YzuD9KepTe0sLjowFRfb7fwCHMU/AO96u0HyWx67mrZwPMCyffCPIZDKPflQ+qPpmcSqGHJ7q7TBiPyPApv/Vp/91oULuwPLlgY7ovLvfV5xsjzKkeFHsYB2G+rgG2qGMvykAwtGaoD65/Cm4PG6rqy9pUKEy3yU+cX6ie2uX1aAKBsBSMgZsT9+fK7Eh/Oq/O9jwiCbDztEQ0CpSAVxwHDEwHa5ibCDFCSw92/JKEu/wy8Mt5xzeXbZt9t9tgB2jrZlYUfRNqlPPjYsLAd4WLSlovqKg7qkn6u96tXaMAagdSXu7P4Su4GjMljai4az5FQRUoIC6t6aPa9pIU+JHmI/UzX6dnrX7RygkfIFZyl2llpmtoICKOZkA58/3arzebkrcpASWn4g3gNIEFUa6Cxev9WAk557LLybJ4bc9meqyZfagsCATk2HfAaVMWvWu+Ul3w2DaXoklbOPlT1Mn+WtpHT1h6wj0h7JDz+WYA88Bk9f+aAxPPSv+JE6lEzrnCtPxFHpNmN6iSvX36S6ZKAJO/djDkHt/A2D52mme6j1GGfwZ3UtKACgDEV6fvw+Rcedu3O9IvyzOQZwxOODasIN4nhPzfyhXvHQT9sjZSMIYoKIlfVEylfEEHtlc3eHc18WUMpFJROUuteDmiAalD+swNBNZ6xEv2KTjkK3kSMvbdkC0ZyFZf43D72JCLwHK4Pcn3vFUeXQ3pZVjSTSnDntcs6HPJvBywxQqUmj02zks47TfOVcdWGSeZ2hmyTqrQfHD/n5ChO2yp0629CqlGtBfnQht+tUo7vnUNiY1+vbCHzAi3D4mBCQs4ftOvPqbWmN/s1NbPG9+TR/BricGoRTr5nNrlgtRBA8DEldpQjEyvrtIEoS/qgKeNFOVBqs8mHBr0fnk4ZQgMJx2KOPxcG210xfvQOOmhUHbdo1fF7K430TsI/PszN2QsI8MgmSoLp0CoeQWdVzWiGbOyww6vdYMgstELWE9YVrr+EXIp2lcwvIZFDApRx9PofArUNEGIiOQJ9BLR9QjFiicLXboz/l6XuQov4nnLJc9oL7Jfyv3zjbnCzzhwFN+bs0RjaBqEv7uA6BAnPre7tSwKqNjTwyPu9DSffGiZFQdjtGZgYyxxGiMAqE++vj5eU8YVkVO9BO7sMfa4pl0GH7g6Lu7MSMv5B4MU79RTjr5E5n/LCIIcWF8PE963NATScK+rh8BmEC6tm3VQ4FFAT+wwX8vGlBIFJ0Xr0hpgr6tnKD9vFMx+wHEvJEydQZgDDmmOyOWHe+eNWdJxSTZBSrteGx62HysjeA0Xivb9dH5qgF/UDNNNDFjrAqyEALfke+XTOX9PkvOwP7S+RcfkfNH2pIALYksSox8+CSUrEfSffFmywn7mrGP5moFHod3kHQumF+/HLAlP6AvU+J1WNrXggNn85mPcFuHhR8tW5JNpvUpDhVzM7Jzb+4ZM3y6ZE3Dk+cdrfBntdh6p6i3VIfX0/pmm8hgzbKn/V77SYEkUaX0n7pjyjYrRMoGOh7qOjKWgxla48LthD4JS8qxIMpmbMy6z1Fy5PY3/gFJ7ATmKgdj2UgB5Wy/48P18HQZ665gnInBLpY01f59XaCVCoPZ0oszzht4Xcyl7mW3a5voh4DTqtKcrPlVKC7Acjuobi16/gtUUOwsCR0AQa9XTqT+yvX0rZwG0TNeLWBOchWX1HGFrrGN/m2GY5LmSXmcIfTb0KVy7ufQWblnbLxmUSvhwtbu2hwc466B2NFijlqJd3fi4Tz9xRdX0JJj0BV4A75agqg==,iv:ArCBeoyoh0RvuQSQ9W6RNF83T5ukZzBUaMZ5QIX9Jmw=,tag:7FFKbTG3iWeADE5fWdo25w==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- enc: |
|
- enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2QTBUbnNBcGFhYjNiNGRG
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaVFQxWG40NEVzcVBVTmp0
|
||||||
T3JqdFY0dTIzWDA3OGNVUkoreVhONXVDeFVVCkR0amlYMThyejlPaWlPSkdGL0xy
|
bXJrWlRmdW0vK0JaaytiamNrVGM0dG9lQkYwCldjSVQ3akhlbTNITUxvTEE1Z2pY
|
||||||
YUN3VEhGajJoQjNiRVV5ckw0cE1JaTAKLS0tIDFSWnpWWVFxQ0VVY2U4bUFtTWVk
|
WGFjQTBoT2w0aXFreFdwcVlVWlBhRGcKLS0tIDBYRnZaK2FkL0YwRkZZb2loRmQx
|
||||||
bkg3K01kWFl4ZWZuK21KRTIxUEhDUEEKPGWzrJlyZGNOsvrVhWKw56y8iAwrqDQK
|
VkZOR2g4bWJQTlRudVoyU01KT3FVREkKgqZ3NJtwtWgYThwdOxrerzl0KlaS5Wve
|
||||||
OWJYIq0gt9NWfNBao8UpiuKJXU4SX01hW4fa1OEfGSDJAjNNxGpFVA==
|
QxiwAtIrK+zXp/JL0q4UEVs5duO8VnrlS8kc1LvxR+uDt9iVpAWyeg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
encrypted_regex: ^(data|stringData|email)$
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
lastmodified: "2026-06-22T19:19:33Z"
|
lastmodified: "2026-09-16T20:20:54Z"
|
||||||
mac: ENC[AES256_GCM,data:Rd0q5r8DA3I7rNNbv9t/5c1LD0Dm1897rGvqhi4l91g9KpSCxQFu0+z6cUH7yhLCopFSWCezQHnBYEGFEkESl04DYkAAj/+ntLSnAhfHijbZshCdHhzr+bxMInajVbDMJTs0DXm2moFMUpcpVn3EHC3UTr/kj/PDfsK9oXugIW0=,iv:ZmlXvPONTD2w+Agh5QqYr8DMMbAeM/QQuWRsFcrw728=,tag:IRoRIxkcQQQuLbG+ccTxuA==,type:str]
|
mac: ENC[AES256_GCM,data:DY3u/NKp/be29EqpFoWE8B+b6t2rjJ4yy+3iONYgG0o04o8FfAr4IsToncdN9p1SZNqtEyxTmogzazRxqp2eTe4TBBg+Uqnpl2yEWhj9+ESIUJs+2YoWHpnB97+VOHy9hN6jDtUWSoIH7B1E4O54u5dISiw35v5O1bEl4Oxk8fk=,iv:9tUIfbmnjJ1D7nDIYoTxtmtA9Wah5wNwnzeZQkNh2U4=,tag:FNYW90bX5zxTBEb5aRBskg==,type:str]
|
||||||
version: 3.13.1
|
version: 3.13.3
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: reitti-db-backup
|
||||||
|
namespace: reitti
|
||||||
|
labels:
|
||||||
|
app: reitti-backup
|
||||||
|
spec:
|
||||||
|
schedule: "30 2 * * *"
|
||||||
|
concurrencyPolicy: Forbid
|
||||||
|
successfulJobsHistoryLimit: 3
|
||||||
|
failedJobsHistoryLimit: 3
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: reitti-backup
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
initContainers:
|
||||||
|
- name: pg-dump
|
||||||
|
image: postgis/postgis:17-3.5
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
env:
|
||||||
|
- name: PGHOST
|
||||||
|
value: reitti-db
|
||||||
|
- name: PGUSER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_USERNAME
|
||||||
|
- name: PGPASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_PASSWORD
|
||||||
|
- name: PGDATABASE
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_DATABASE_NAME
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- pg_dump --clean --if-exists > /backup/dump.sql
|
||||||
|
volumeMounts:
|
||||||
|
- name: backup-tmp
|
||||||
|
mountPath: /backup
|
||||||
|
containers:
|
||||||
|
- name: resticprofile
|
||||||
|
image: creativeprojects/resticprofile:0.32.0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n reitti-db backup
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n reitti-db copy
|
||||||
|
env:
|
||||||
|
- name: B2_ACCOUNT_ID
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-backup-config
|
||||||
|
key: B2_ACCOUNT_ID
|
||||||
|
- name: B2_ACCOUNT_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-backup-config
|
||||||
|
key: B2_ACCOUNT_KEY
|
||||||
|
volumeMounts:
|
||||||
|
- name: secrets
|
||||||
|
mountPath: /secrets
|
||||||
|
readOnly: true
|
||||||
|
- name: backup-tmp
|
||||||
|
mountPath: /backup
|
||||||
|
volumes:
|
||||||
|
- name: secrets
|
||||||
|
secret:
|
||||||
|
secretName: reitti-backup-config
|
||||||
|
- name: backup-tmp
|
||||||
|
emptyDir: {}
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: reitti-files-backup
|
||||||
|
namespace: reitti
|
||||||
|
labels:
|
||||||
|
app: reitti-backup
|
||||||
|
spec:
|
||||||
|
schedule: "30 3 * * *"
|
||||||
|
concurrencyPolicy: Forbid
|
||||||
|
successfulJobsHistoryLimit: 3
|
||||||
|
failedJobsHistoryLimit: 3
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: reitti-backup
|
||||||
|
spec:
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
containers:
|
||||||
|
- name: resticprofile
|
||||||
|
image: creativeprojects/resticprofile:0.32.0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n reitti-files backup
|
||||||
|
resticprofile -c /secrets/profiles.yaml -n reitti-files copy
|
||||||
|
env:
|
||||||
|
- name: B2_ACCOUNT_ID
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-backup-config
|
||||||
|
key: B2_ACCOUNT_ID
|
||||||
|
- name: B2_ACCOUNT_KEY
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-backup-config
|
||||||
|
key: B2_ACCOUNT_KEY
|
||||||
|
volumeMounts:
|
||||||
|
- name: secrets
|
||||||
|
mountPath: /secrets
|
||||||
|
readOnly: true
|
||||||
|
- name: files
|
||||||
|
mountPath: /files
|
||||||
|
readOnly: true
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
|
volumes:
|
||||||
|
- name: secrets
|
||||||
|
secret:
|
||||||
|
secretName: reitti-backup-config
|
||||||
|
- name: files
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: reitti-data
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: reitti-redis
|
||||||
|
namespace: reitti
|
||||||
|
labels:
|
||||||
|
app: reitti-redis
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-redis
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: reitti-redis
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 999 # redis user in the alpine image
|
||||||
|
runAsGroup: 999
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: redis:7.4.11-alpine
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
# Cache only — no persistence, so no PVC.
|
||||||
|
args: ["--save", "", "--appendonly", "no"]
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
name: redis
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 30
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 6379
|
||||||
|
periodSeconds: 10
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 20m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: reitti-tile-cache
|
||||||
|
namespace: reitti
|
||||||
|
labels:
|
||||||
|
app: reitti-tile-cache
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-tile-cache
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: reitti-tile-cache
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
# nginx image starts as root (renders nginx.conf, binds :80) then drops workers to nginx
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: tile-cache
|
||||||
|
image: dedicatedcode/reitti-tile-cache:5.9.1
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
name: http
|
||||||
|
volumeMounts:
|
||||||
|
- name: cache
|
||||||
|
mountPath: /var/cache/nginx
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 80
|
||||||
|
path: /health
|
||||||
|
periodSeconds: 30
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 80
|
||||||
|
path: /health
|
||||||
|
periodSeconds: 10
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 20m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi # keys_zone shared memory: 512m tiles + 128m panoramax
|
||||||
|
volumes:
|
||||||
|
- name: cache
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: reitti-tile-cache
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: reitti
|
||||||
|
namespace: reitti
|
||||||
|
labels:
|
||||||
|
app: reitti
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: reitti
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
# The image starts as root only to remap UID/GID and chown /data, then drops to
|
||||||
|
# reitti (1000). Running as 1000 directly skips that; the NFS subdir provisioner
|
||||||
|
# creates directories 0777, so /data is writable without a chown.
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: reitti
|
||||||
|
image: dedicatedcode/reitti:5.9.1
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
name: http
|
||||||
|
protocol: TCP
|
||||||
|
env:
|
||||||
|
- name: ADVERTISE_URI
|
||||||
|
value: https://${REITTI_HOST}
|
||||||
|
- name: JAVA_OPTS
|
||||||
|
value: -XX:MaxRAMPercentage=75
|
||||||
|
- name: POSTGIS_HOST
|
||||||
|
value: reitti-db
|
||||||
|
- name: POSTGIS_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_USERNAME
|
||||||
|
- name: POSTGIS_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_PASSWORD
|
||||||
|
- name: POSTGIS_DB
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_DATABASE_NAME
|
||||||
|
- name: REDIS_HOST
|
||||||
|
value: reitti-redis
|
||||||
|
# Tiles are proxied server-side through /api/v1/tiles, so the in-cluster URL works.
|
||||||
|
- name: TILES_CACHE
|
||||||
|
value: http://reitti-tile-cache
|
||||||
|
# Authentication against Authelia over OIDC only (redirect URI /login/oauth2/code/oauth).
|
||||||
|
# Unknown Authelia users are auto-created as regular users. With local login disabled,
|
||||||
|
# the next SSO login clears the user's local password and syncs the username.
|
||||||
|
- name: OIDC_ENABLED
|
||||||
|
value: "true"
|
||||||
|
- name: OIDC_ISSUER_URI
|
||||||
|
value: https://auth.${AUTHELIA_DOMAIN}
|
||||||
|
- name: OIDC_CLIENT_ID
|
||||||
|
value: reitti
|
||||||
|
- name: OIDC_CLIENT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: OIDC_CLIENT_SECRET
|
||||||
|
- name: OIDC_SCOPE
|
||||||
|
value: openid,profile,email
|
||||||
|
- name: OIDC_AUTHENTICATION_METHOD
|
||||||
|
value: client_secret_basic
|
||||||
|
- name: OIDC_SIGN_UP_ENABLED
|
||||||
|
value: "true"
|
||||||
|
- name: DISABLE_LOCAL_LOGIN
|
||||||
|
value: "true"
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
startupProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /actuator/health
|
||||||
|
initialDelaySeconds: 20
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 30 # DB migrations on first start / upgrades
|
||||||
|
# Generous timeouts: large imports (Google Timeline, ~500k points) keep the JVM busy
|
||||||
|
# for minutes and /actuator/health answers slowly; a 1s timeout got the pod killed.
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /actuator/health
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 10
|
||||||
|
failureThreshold: 6
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
port: 8080
|
||||||
|
path: /actuator/health
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 1Gi
|
||||||
|
limits:
|
||||||
|
memory: 3Gi # heap = 75%; 1.5Gi ran out of heap processing a large import
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: reitti-data
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: reitti
|
||||||
|
namespace: reitti
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt
|
||||||
|
# No Authelia forward-auth middleware — Reitti authenticates against Authelia
|
||||||
|
# natively over OIDC. A middleware here would break the OIDC callback, the
|
||||||
|
# token-authenticated /api ingest endpoints (OwnTracks, GPSLogger, Overland)
|
||||||
|
# and magic share links.
|
||||||
|
spec:
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- ${REITTI_HOST}
|
||||||
|
secretName: reitti-tls
|
||||||
|
rules:
|
||||||
|
- host: ${REITTI_HOST}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: reitti
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: reitti
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: default-deny-ingress
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector: {}
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-ingress-controller
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
kubernetes.io/metadata.name: traefik
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-app-to-db
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-db
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-backup-to-db
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-db
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-backup
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-backup-egress
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-backup
|
||||||
|
policyTypes:
|
||||||
|
- Egress
|
||||||
|
egress:
|
||||||
|
- ports:
|
||||||
|
- port: 53
|
||||||
|
protocol: UDP
|
||||||
|
- port: 53
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 8888
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 443
|
||||||
|
protocol: TCP
|
||||||
|
- ports:
|
||||||
|
- port: 5432
|
||||||
|
protocol: TCP
|
||||||
|
to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-db
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-app-to-redis
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-redis
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-app-to-tile-cache
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-tile-cache
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: reitti-data
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: nfs-synology-ssd
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 10Gi
|
||||||
|
---
|
||||||
|
# Map tile cache — recreatable, not backed up. nginx caps it at 2g tiles + 1g Panoramax.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: reitti-tile-cache
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
storageClassName: nfs-synology-ssd
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"kubernetes": {
|
||||||
|
"fileMatch": ["kubernetes/app/reitti/.+\\.yaml$"]
|
||||||
|
},
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchFileNames": ["kubernetes/app/reitti/**"],
|
||||||
|
"semanticCommitScope": "k8s/reitti"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchFileNames": ["kubernetes/app/reitti/**"],
|
||||||
|
"matchPackageNames": ["dedicatedcode/reitti", "dedicatedcode/reitti-tile-cache"],
|
||||||
|
"matchUpdateTypes": ["patch", "minor"],
|
||||||
|
"automerge": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchFileNames": ["kubernetes/app/reitti/**"],
|
||||||
|
"matchPackageNames": ["dedicatedcode/reitti", "dedicatedcode/reitti-tile-cache"],
|
||||||
|
"matchUpdateTypes": ["major"],
|
||||||
|
"automerge": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Ignore infrastructure images",
|
||||||
|
"matchFileNames": ["kubernetes/app/reitti/**"],
|
||||||
|
"matchPackageNames": ["postgis/postgis", "redis", "creativeprojects/resticprofile"],
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: reitti-backup-config
|
||||||
|
namespace: reitti
|
||||||
|
stringData:
|
||||||
|
profiles.yaml: ENC[AES256_GCM,data:aVuPPechcaGmXT0g6OTnISgGR2ZdBJvqrf6mpDJyIERXZiQC8aVq1RtkUeyVMs7Hed8OwuRfuo5xlG5206Bg8ynbBFEWsl+sbWRWOa9g+qSnO84Fhej+fbHITzC2BPk1q85CWJUpVcdHq1vgyKYluJpuYpS3HzrinsjTFpiziC7ft/lFjzebdlkFZgvq6cPFzYqP/8f54GOkYaR/cNr6ux6QLsbA3rfPOAfsMiaZFt3JfbTRNfqcM4eZw04N3bf4CVpyPjR69HZvlzHw0Gje+GX3vdez8bByUxo40aB9Aisvr/HeTM8L5njQDefN/zH1VGTSV2LfNk81soSowtxJ3RZ2hZYnx4dz0XUggvGqR5dhlGvT3pDK0v9lkRM1ahZw1x5q2zd3K7IcQLwYSckRdwC0j9vc8TUkHhyg+9x5TRrGy9hA4rCJtsGzTU/Sc4dcobueFXBGrIg9raTDknEo1D4Vq7H74Ce9RnemYlb1KJsjrtyqrpKkzIAChL1b6xhgOzg5YJ2UH6+laEsbC891OZp2PEdQY1lA8n36HXflsZnIQY8SOhToR6FoH3qzOB79a2I5jmJHI9O7S0L6NO2+fFDRgMbUNeIa9yJacN297Qui3paGQTcsGvSGQ7eAEH06VZXU/DX7TU0XiLfejIohm78QSmO7ZcTBxlQ1OTHc1Kiny1e0SomY7kxs1OL4SSBJirmymojuxogOGWblxt2AOz37eCFgp8L3sRPSHWGM982na6Ko7zUw1/bhukGoN445DsiuV59ilXSA0W5ci/PfrqzFOqZWKKDZfE89nCf+2P1thS3DmOpJnlG8tq5rde9QAqT0mgcvxo5Re+Bf/Ehavo0t79Gy35c6EEwPK8lEFXlSib84mfRiMnKBV60cQ4HS3xy78xLKPvjBpM4s8vbnMY4GJxCNAzOivhAfHAU3vTp/ZP8B0LJp7bNk7tre/gR+Q1DuqhwyCjo8sUZi4Cua3ILiKvcvU8ZXvjz+LfIymDocIxeFtRGHA2KceURa25v0hWrEI0Qzaz1m5XeYg76HhjcCU5WqT8CuFZNDlf+35uyKxhOZqr7kT2J/nZ/VYF2+sz9oBmeH/VW3OdgIc203e8wQIPBTd8OYpkabnwxDMlyiaG8MySZORS7kyD88Sy8bFJUN9IO7svav0WxZhJn4atAc2iqH81Y1s4WE1i87UqUDtwd5nOKXUFf8Fr6jXpB8G95hJCzgLFtrmX/6eg==,iv:Kp9nml6af8RmrVIIvAv8m647mMm5oe02T9TqkyIVY+U=,tag:WYbdlHbstN6XhcIP53VpqQ==,type:str]
|
||||||
|
restic-password-nas: ENC[AES256_GCM,data:FSRmDhSQHfHXomxPhefQ3WJNPVzSCNw/ML/mCiloViEkpVj92vcQbA==,iv:ijS0gKwp4dc/Oq346a/KLFnDBkPfhPzr4IUHbziGPxs=,tag:gE2wAuk+zWUJHgPlYQvwjw==,type:str]
|
||||||
|
restic-password-b2: ENC[AES256_GCM,data:4f0xRAKnWLsOFvu0GVu2FK7w8QS/w21AkCjSho7C1q8CV4aJSovvVA==,iv:WOru20OWYoN9jtW2iUdXpfuLd2SWiBXQ6Ncp5FUsRcE=,tag:vYa+obqI7gBHk9wY+tkIwg==,type:str]
|
||||||
|
B2_ACCOUNT_ID: ENC[AES256_GCM,data:52us2nMzoQ7p+I/+9+mJa+DK+MT8CdBDsg==,iv:E/ifDPwDyRJXOZBTPPwpLwCZzQ0n9IN+cdO/3O3u2e4=,tag:dFH0C7bZi4EcevoMJamzuQ==,type:str]
|
||||||
|
B2_ACCOUNT_KEY: ENC[AES256_GCM,data:jYDWYUj42GEtubZ5+RmYc+FT2FbJwg1PrzgtCb8I7Q==,iv:ZVvWw2aBv0iPAFzCn3L3MC3pwR/ru4zTDx0KsTiSQD8=,tag:PXLsKsT9ccSrZwUUONWnpQ==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCMDliMG1iNTVrNUZ2a0li
|
||||||
|
Tkc2WXFLbGhlbFYwdkovcjNZYXJBa0V1MFc0CnVEaEc1bzBCK0czSHh4dGE5Ky9Y
|
||||||
|
NjFWWGlScGdpODU3KzNmQzUzS3FkeVEKLS0tIDRXbHpST0RySVB1UEVRbWVYYytV
|
||||||
|
SzV4Q01MaGJGNmxqMm50OWh3S1RCbkEKaKPeVOU9Gvg+7RImg0BSLyl8DUNzCJDm
|
||||||
|
9gQd9z8IwciZE4St53kYSbQNCKMjz4yUc4mrbW04IXs5cTbnCLBspA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
|
lastmodified: "2026-10-03T20:31:00Z"
|
||||||
|
mac: ENC[AES256_GCM,data:Jg964qmIW9hSp4N+4stwmE24qi4sNQfUA0YM5rH1QHWbeZS1gAXszgQQPPrOw+hStgNWZbsgiMJVIvF3v13qgMh6ZVSAFMmf3fWJ+tN6Dhrj79Qx+klaI8qXpXQsLvHX0gJFYBAyPvtBPoDRnHK8X/twAKm03QtCLCMHv3LnQ6Y=,iv:2De8vyYSIMKTWUXB0k5VAojeTFXuCwiuduXeGcCMHmA=,tag:eZzK4MPeCJItfYbbwQXJZQ==,type:str]
|
||||||
|
version: 3.13.3
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: reitti-credentials
|
||||||
|
namespace: reitti
|
||||||
|
stringData:
|
||||||
|
DB_USERNAME: ENC[AES256_GCM,data:s5+3cPVq,iv:xgQHj/ORXzDDsOoZZruGQrGTU+y+BRwkWC7Tk3CSAuI=,tag:6p6OdIL4CR0UDiiKOVsttA==,type:str]
|
||||||
|
DB_PASSWORD: ENC[AES256_GCM,data:GoWO3wMx2R7BAgkfb/GAk6vd7wIrbL8uqaCWf2TMwpgCr8yCY0mifw==,iv:KTkH59Woh/QBkx5lHWv/iV9LqrA1Q1NcpwtDkUKJAaY=,tag:HpHvG8kW2+RTDS0L1DjJQQ==,type:str]
|
||||||
|
DB_DATABASE_NAME: ENC[AES256_GCM,data:/Xrjy1quYwI=,iv:whj1qsDAKMqCeW8Ge+M0cZEjiSpYZizlXfBy3bhIbbg=,tag:8WrJv7bgFbbxIrz3uCZumA==,type:str]
|
||||||
|
OIDC_CLIENT_SECRET: ENC[AES256_GCM,data:WHk4EOUrYj7PnJiahEAy6yL7X155bj3s4wn7nzbeS8YHR5OOCIHa1b/atf1S7bktStkllIOg+EhmzGoHYFUgNg==,iv:zCsaEmx+9kvXGw8Lda+Qi7kIRl1kU7nWk9flFJzeZyA=,tag:eGD1noK0YBjVsIn23vnixQ==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBseDh0cGhIZkU0WHNJdThj
|
||||||
|
K1dWS29TSUhPWEFxdi9EOG1aZmlKcVJTTWxVCkM3RWtTOWl5Y0psU3BDNmFQSnFT
|
||||||
|
aGlURkFzOVVNd3FWclBYbEpIRXJ1QjQKLS0tIHQrRS9hRVVIYVBIazJFNGxhNWJm
|
||||||
|
dFFocWFxVkJIOVc5aUppQ2p3R2pNU28Kj2q+bIxGc14s8qs3Uc0/Dc9tymLMsT2o
|
||||||
|
x7dDpozVupQY/Pqo4RqWp6/OIOjVSTtqKV8A99KTyp9HBd2m9xjyWA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
|
lastmodified: "2026-10-03T20:19:54Z"
|
||||||
|
mac: ENC[AES256_GCM,data:lE6AHBDRhNiTXlQMNLIMqBEDpYWfYg8TI6Mpd2as4Q+O7WckTuDkrOrULA063OgjJzohld5x3yExnR2weDMaiz2jXn0kDoXYrYxIYL4J4Ht98t8yndhtDMzSaVyJVyfRN3JRxfpJfVBTcD/mrpvo5fmQRJv0k/l0F4/lZY/UYSk=,iv:WUQv2PyrHt3tdUKsyhzggQ/kYosXebehmeNDqZQ4Lac=,tag:ooVml9rbNwtYaZGYPFv30w==,type:str]
|
||||||
|
version: 3.13.3
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: reitti-db
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
clusterIP: None
|
||||||
|
selector:
|
||||||
|
app: reitti-db
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: 5432
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: reitti
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: reitti
|
||||||
|
ports:
|
||||||
|
- port: 8080
|
||||||
|
targetPort: 8080
|
||||||
|
name: http
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: reitti-redis
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: reitti-redis
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: 6379
|
||||||
|
name: redis
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: reitti-tile-cache
|
||||||
|
namespace: reitti
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: reitti-tile-cache
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
name: http
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: reitti-db
|
||||||
|
namespace: reitti
|
||||||
|
labels:
|
||||||
|
app: reitti-db
|
||||||
|
spec:
|
||||||
|
serviceName: reitti-db
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: reitti-db
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: reitti-db
|
||||||
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 999
|
||||||
|
runAsGroup: 999
|
||||||
|
fsGroup: 999
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
# Reitti requires PostGIS; the Debian variant keeps the postgres user at UID 999
|
||||||
|
# (the alpine variant uses 70). The image creates the postgis extension in POSTGRES_DB.
|
||||||
|
image: postgis/postgis:17-3.5
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_USERNAME
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_PASSWORD
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: reitti-credentials
|
||||||
|
key: DB_DATABASE_NAME
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
startupProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 5432
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 30
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 5432
|
||||||
|
periodSeconds: 30
|
||||||
|
failureThreshold: 5
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 5432
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: data
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
storageClassName: nfs-synology-ssd
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 5Gi
|
||||||
@@ -27,7 +27,7 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
containers:
|
containers:
|
||||||
- name: vikunja
|
- name: vikunja
|
||||||
image: vikunja/vikunja:2.6.0
|
image: vikunja/vikunja:2.7.1
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 3456
|
- containerPort: 3456
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ stringData:
|
|||||||
BLOG_HOST: ENC[AES256_GCM,data:eADRFTla/PPFLVCoP9uKvPZ1YhY=,iv://xbCGLkZ6guGMDU0MnVtGR0adgMqNbe0zrCerj7w8k=,tag:HHXvN6y3YvJ4U4TkENkYVA==,type:str]
|
BLOG_HOST: ENC[AES256_GCM,data:eADRFTla/PPFLVCoP9uKvPZ1YhY=,iv://xbCGLkZ6guGMDU0MnVtGR0adgMqNbe0zrCerj7w8k=,tag:HHXvN6y3YvJ4U4TkENkYVA==,type:str]
|
||||||
VIKUNJA_HOST: ENC[AES256_GCM,data:1VVkvVrdx02jPxHsQoQI9zJKN9v/9mE=,iv:ZagDcljNclEGvmMzS6pJWTv+FMa/a/X6POaWb+kHJuo=,tag:RuaUoX8O4LrEs491Sp4UyQ==,type:str]
|
VIKUNJA_HOST: ENC[AES256_GCM,data:1VVkvVrdx02jPxHsQoQI9zJKN9v/9mE=,iv:ZagDcljNclEGvmMzS6pJWTv+FMa/a/X6POaWb+kHJuo=,tag:RuaUoX8O4LrEs491Sp4UyQ==,type:str]
|
||||||
BACKUP_LOCAL_HOST: ENC[AES256_GCM,data:ABaTI3NKkhF7K2FpPwvvrHA0l/tCxAi4Qek=,iv:34ixxSpKU1c12uoMdk4nz2Vo/+5A/npB7NWMsWFytIM=,tag:qjw2fQBebCKnqCnAPiBHaw==,type:str]
|
BACKUP_LOCAL_HOST: ENC[AES256_GCM,data:ABaTI3NKkhF7K2FpPwvvrHA0l/tCxAi4Qek=,iv:34ixxSpKU1c12uoMdk4nz2Vo/+5A/npB7NWMsWFytIM=,tag:qjw2fQBebCKnqCnAPiBHaw==,type:str]
|
||||||
|
REITTI_HOST: ENC[AES256_GCM,data:Zx0T6aUL/v6ogX1miRxzDmDQ31EImg==,iv:0LBRaaG1FHBXFWrtDX8Z6Cs75BEA7hNYm5FFrBHhyYk=,tag:Tup6HoL6E+L9GJKmv3x17Q==,type:str]
|
||||||
|
DAWARICH_HOST: ENC[AES256_GCM,data:Gpt9acoks8gnlvHnMLsFhH18fzu0sLjp,iv:QrJd20KcFtMlWarCgMVv1riUlJF3Qj/aYa2vJQizmpg=,tag:JTmmJHZ9u4ecg3/8frYSEA==,type:str]
|
||||||
|
POD_CIDR: ENC[AES256_GCM,data:TX6OQd+8IlgAk2C2kQ==,iv:F+sDxOPvWg3dgPB8NlzfpC7toY88FBeKXzjgUSk1H8M=,tag:NUdzsKszagRhG2+U4YlOcw==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- enc: |
|
- enc: |
|
||||||
@@ -50,6 +53,6 @@ sops:
|
|||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
|
||||||
encrypted_regex: ^(data|stringData|email)$
|
encrypted_regex: ^(data|stringData|email)$
|
||||||
lastmodified: "2026-09-07T11:47:37Z"
|
lastmodified: "2026-10-18T10:53:13Z"
|
||||||
mac: ENC[AES256_GCM,data:4ocnThiPrXCqKTKKgwaincewzI99O7cl9CGnJHrwLRFm8vA2G6MA8yGvywoKjmln8mEfPTTcMMZY8Nd7wFKHz9i4m+CHvzC7kPhTVIDW2HrkFoN7RgywPcgnP+mrco4wOd/huBLdv9+v/j4Iz5lXBMZgbVVkNdWV4xZ4Zx3gtyM=,iv:bfK9KN4E5nZYm6CwaFm3sxG62nDnNiuP5xsIreRHkAc=,tag:wi9r3EcJOHX0azzNVpGw0Q==,type:str]
|
mac: ENC[AES256_GCM,data:UqYOF0M6gaVjrE3/OQK/vQ0+lUcwan6fIvrJnm2BE6O28pDFL9iIDAo1ebp0oYhT8+cxNl/tTGlfH5TCblxpSCzu77/8eOgTdn19xqhTC8H8Yw56HVnYWNKZaQTyH+Qw6cG9HFf+d5OTYKeOEZufxZzpF7gT6M8BIssQ1vxEFQM=,iv:Vt1ln9ur5Dejod4X2+JUxwMwjlS198EWMASIw0Gf3Hk=,tag:NSnVkPLLTkHckVLEdTylWg==,type:str]
|
||||||
version: 3.13.3
|
version: 3.13.3
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+3
-1
@@ -12,7 +12,9 @@
|
|||||||
"local>oleksandr/homelab//kubernetes/app/paperless/renovate.json",
|
"local>oleksandr/homelab//kubernetes/app/paperless/renovate.json",
|
||||||
"local>oleksandr/homelab//kubernetes/app/lubelogger/renovate.json",
|
"local>oleksandr/homelab//kubernetes/app/lubelogger/renovate.json",
|
||||||
"local>oleksandr/homelab//kubernetes/app/firefly/renovate.json",
|
"local>oleksandr/homelab//kubernetes/app/firefly/renovate.json",
|
||||||
"local>oleksandr/homelab//kubernetes/app/podsync/renovate.json"
|
"local>oleksandr/homelab//kubernetes/app/podsync/renovate.json",
|
||||||
|
"local>oleksandr/homelab//kubernetes/app/reitti/renovate.json",
|
||||||
|
"local>oleksandr/homelab//kubernetes/app/dawarich/renovate.json"
|
||||||
],
|
],
|
||||||
"enabledManagers": ["kubernetes", "custom.regex"],
|
"enabledManagers": ["kubernetes", "custom.regex"],
|
||||||
"automergeType": "branch",
|
"automergeType": "branch",
|
||||||
|
|||||||
Reference in New Issue
Block a user