Author SHA1 Message Date
oleksandr 809eea6d51 chore(k8s/vikunja): pause Vikunja by scaling to zero 2026-11-05 19:34:36 +02:00
oleksandr acd823d196 feat(k8s): remove Grocy, Firefly III and CryptPad 2026-11-05 19:34:35 +02:00
oleksandr c3b911e4ab feat(k8s/infrastructure/authelia): skip OIDC consent screen with implicit consent mode 2026-11-05 19:26:30 +02:00
renovate 820340455d chore(k8s/immich): update dependency immich-app/immich to v3.3.6 2026-11-04 18:02:13 +00:00
renovate bb8da2f3ba chore(k8s/dawarich): update freikin/dawarich docker tag to v1.21.0 2026-11-04 12:02:24 +00:00
renovate d26f4821de chore(k8s/reitti): update dedicatedcode/reitti-tile-cache docker tag to v5.9.1 2026-11-03 12:01:39 +00:00
renovate 5910d406bf chore(k8s/reitti): update dedicatedcode/reitti docker tag to v5.9.1 2026-11-03 12:00:46 +00:00
renovate a7d27804e2 chore(k8s/reitti): update dedicatedcode/reitti-tile-cache docker tag to v5.9.0 2026-11-02 12:01:34 +00:00
renovate 5e79bad09e chore(k8s/reitti): update dedicatedcode/reitti docker tag to v5.9.0 2026-11-02 12:00:42 +00:00
renovate 7c95f2191c chore(k8s/dawarich): update freikin/dawarich docker tag to v1.20.1 2026-11-02 00:01:45 +00:00
renovate 3951ecae96 chore(k8s/dawarich): update freikin/dawarich docker tag to v1.20.0 2026-10-31 12:00:41 +00:00
renovate 82ad813a1c chore(k8s/paperless): update ghcr.io/paperless-ngx/paperless-ngx docker tag to v3.4 2026-10-30 00:00:53 +00:00
renovate 5db7c87292 chore(k8s/media): update lscr.io/linuxserver/prowlarr docker tag to v2.7.0 2026-10-28 00:02:20 +00:00
renovate 10ee6528fd chore(k8s/dawarich): update freikin/dawarich docker tag to v1.19.0 2026-10-28 00:01:58 +00:00
renovate 57f9f3883b chore(k8s/jellyfin): update jellyfin/jellyfin docker tag to v12.4 2026-10-27 00:01:21 +00:00
renovate 352059fbbc chore(k8s/dawarich): update freikin/dawarich docker tag to v1.18.1 2026-10-27 00:00:44 +00:00
renovate a913e10a42 chore(k8s/dawarich): update freikin/dawarich docker tag to v1.18.0 2026-10-26 00:01:27 +00:00
renovate 2cab677ef9 chore(k8s/reitti): update dedicatedcode/reitti-tile-cache docker tag to v5.8.1 2026-10-24 18:00:58 +00:00
renovate 3f4269511c chore(k8s/reitti): update dedicatedcode/reitti docker tag to v5.8.1 2026-10-24 18:00:38 +00:00
renovate 2ecc949323 chore(k8s/dawarich): update freikin/dawarich docker tag to v1.17.0 2026-10-24 00:00:42 +00:00
renovate cc0d255b99 chore(k8s/homepage): update ghcr.io/gethomepage/homepage docker tag to v2.7.0 2026-10-23 18:00:50 +00:00
renovate 98a8a469c4 chore(k8s/jellyfin): update jellyfin/jellyfin docker tag to v12.3 2026-10-23 06:01:35 +00:00
renovate 03a062c649 chore(k8s/reitti): update dedicatedcode/reitti-tile-cache docker tag to v5.8.0 2026-10-22 06:01:35 +00:00
renovate c38cf40898 chore(k8s/reitti): update dedicatedcode/reitti docker tag to v5.8.0 2026-10-22 06:00:42 +00:00
renovate fe3bd8e56a chore(k8s/paperless): update apache/tika docker tag to v3.3.3.0 2026-10-22 00:01:53 +00:00
renovate 04a3aa1d54 chore(k8s/immich): update dependency immich-app/immich to v3.3.5 2026-10-22 00:01:38 +00:00
renovate 212b0bdbf3 chore(k8s/media): update lscr.io/linuxserver/qbittorrent docker tag to v5.3.0 2026-10-21 18:01:39 +00:00
renovate 93fb70770b chore(k8s/media): update dependency seerr-team/seerr to v3.5.1 2026-10-21 18:01:15 +00:00
renovate a46aab984c chore(k8s/vikunja): update vikunja/vikunja docker tag to v2.7.1 2026-10-21 00:01:02 +00:00
renovate 6bbe3afbdd chore(k8s/immich): update dependency immich-app/immich to v3.3.4 2026-10-20 12:02:14 +00:00
oleksandr 144fb51126 fix(k8s/media): trust Traefik forwarded headers in *arr apps via POD_CIDR 2026-10-18 15:07:40 +03:00
renovate 5b6bb444ad chore(k8s/dawarich): update freikin/dawarich docker tag to v1.16.0 2026-10-17 18:00:58 +00:00
renovate f8fb3c59ad chore(k8s/homepage): update ghcr.io/gethomepage/homepage docker tag to v2.6.0 2026-10-17 06:00:33 +00:00
renovate 107d352036 chore(k8s/reitti): update dedicatedcode/reitti-tile-cache docker tag to v5.7.0 2026-10-15 00:01:27 +00:00
renovate bcb4ebbbb8 chore(k8s/reitti): update dedicatedcode/reitti docker tag to v5.7.0 2026-10-15 00:00:36 +00:00
renovate 95b25cacc5 chore(k8s/lubelogger): update ghcr.io/hargata/lubelogger docker tag to v1.7.4 2026-10-14 18:01:31 +00:00
renovate f01ac8f468 chore(k8s/immich): update dependency immich-app/immich to v3.3.3 2026-10-14 18:01:18 +00:00
oleksandr 2756b38ec3 fix(k8s/archmirror): keep nginx responsive when NFS is slow 2026-10-12 21:17:42 +03:00
renovate 728221523f chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.9 2026-10-12 00:01:17 +00:00
renovate 820ce00535 chore(k8s/homepage): update ghcr.io/gethomepage/homepage docker tag to v2.5.0 2026-10-11 00:01:46 +00:00
oleksandr 96bfd53907 feat(k8s/paperless): enable native AI with Claude Haiku 5.5 and local embeddings 2026-10-10 21:40:53 +03:00
renovate ec757b8b48 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.8 2026-10-10 06:00:52 +00:00
renovate ca4cf45e7a chore(k8s/immich): update dependency immich-app/immich to v3.3.1 2026-10-09 00:01:15 +00:00
oleksandr 07960e0c92 feat(k8s/dawarich): deploy Dawarich with PostGIS and Authelia OIDC 2026-10-08 13:38:58 +03:00
renovate 7afeb02b4d chore(k8s/immich): update dependency immich-app/immich to v3.3.0 2026-10-08 00:01:14 +00:00
renovate ecc38d207c chore(k8s/paperless): update ghcr.io/paperless-ngx/paperless-ngx docker tag to v3.3 2026-10-06 06:01:10 +00:00
renovate d082a82e73 chore(k8s/jellyfin): update jellyfin/jellyfin docker tag to v12.2 2026-10-06 00:01:28 +00:00
oleksandr 8f914714cb feat(k8s/infrastructure/authelia): add avatar pictures for users 2026-10-04 00:54:00 +03:00
oleksandr ea2a2d53ef fix(k8s/homepage): use Jellyfin widget API v2 for Jellyfin 12 2026-10-04 00:28:10 +03:00
oleksandr 6cc59537c0 chore(k8s/reitti): disable data management after reprocessing 2026-10-04 00:13:10 +03:00
oleksandr a181d45ee8 chore(k8s/reitti): temporarily enable data management for reprocessing 2026-10-04 00:06:58 +03:00
oleksandr e662c59cd5 fix(k8s/reitti): raise memory limit and relax probe timeouts for large imports 2026-10-03 23:55:43 +03:00
oleksandr 1577313de5 feat(k8s/reitti): enable OIDC sign-up and disable local login 2026-10-03 23:43:07 +03:00
oleksandr 498330b752 feat(k8s/reitti): deploy Reitti with PostGIS, Authelia OIDC, and restic backups 2026-10-03 23:34:47 +03:00
oleksandr 6002b003a0 feat(mon/alerting): route alerts to Telegram, add gateway and syslog rules 2026-10-03 23:08:38 +03:00
renovate 4468b3e590 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.7 2026-10-03 12:01:21 +00:00
renovate ab73f9c35c chore(k8s/vikunja): update vikunja/vikunja docker tag to v2.7.0 2026-10-02 18:00:37 +00:00
renovate b990b898c7 chore(k8s/media): update lscr.io/linuxserver/qbittorrent docker tag to v5.2.4 2026-09-29 12:01:27 +00:00
renovate 2b3845e18c chore(k8s/immich): update dependency immich-app/immich to v3.2.4 2026-09-28 18:00:49 +00:00
renovate d9e8e946ac chore(k8s/media): update dependency seerr-team/seerr to v3.5.0 2026-09-28 12:01:35 +00:00
renovate 03b393bbae chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.6 2026-09-28 12:01:16 +00:00
renovate 451f19f082 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.5 2026-09-27 12:00:43 +00:00
renovate 3c1c4bfffc chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.4 2026-09-25 18:00:38 +00:00
renovate c0141082bc chore(k8s/paperless): update ghcr.io/paperless-ngx/paperless-ngx docker tag to v3.2 2026-09-19 06:01:06 +00:00
renovate 6eb8e0aba2 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.3 2026-09-18 18:00:32 +00:00
oleksandr 7ea92e8cec chore(k8s/pihole): update pihole to 2026.07.2 and dnscrypt-proxy to v2.1.18 2026-09-17 18:41:00 +03:00
renovate e34da438a6 chore(k8s/homepage): update ghcr.io/gethomepage/homepage docker tag to v2.4.0 2026-09-17 12:01:21 +00:00
renovate 595d4841d5 chore(k8s/media): update lscr.io/linuxserver/radarr docker tag to v6.4.4 2026-09-17 06:01:30 +00:00
renovate 85a0dfabeb chore(k8s/media): update lscr.io/linuxserver/sonarr docker tag to v4.0.20 2026-09-17 00:01:48 +00:00
renovate 1d5ef1dd60 chore(k8s/media): update lscr.io/linuxserver/prowlarr docker tag to v2.6.5 2026-09-17 00:01:32 +00:00
oleksandr 4e82d683d6 feat(k8s/podsync): update config 2026-09-16 23:25:20 +03:00
renovate c7745ceb37 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.2 2026-09-16 12:00:36 +00:00
oleksandr 555246f00e fix(k8s/grocy): open SQLite database read-only in backup job 2026-09-16 11:42:36 +03:00
oleksandr f2f3711faa fix(k8s/jellyfin): open SQLite databases read-only in backup jobs 2026-09-16 11:42:36 +03:00
renovate 9fc2c8d90b chore(k8s/immich): update dependency immich-app/immich to v3.2.2 2026-09-16 00:01:08 +00:00
renovate 0564cb1242 chore(k8s/jellyfin): update jellyfin/jellyfin docker tag to v12.1 2026-09-15 06:01:34 +00:00
renovate 1221d4e318 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.1 2026-09-15 06:01:14 +00:00
renovate 7d233c126b chore(k8s/immich): update dependency immich-app/immich to v3.2.1 2026-09-15 00:01:26 +00:00
oleksandr bac0fc2cdd feat(k8s/podsync): update config 2026-09-14 22:22:09 +03:00
renovate fabbbf6073 chore(k8s/firefly): update fireflyiii/core docker tag to version-6.7.0 2026-09-14 18:01:23 +00:00
78 changed files with 1264 additions and 1329 deletions
+2 -4
View File
@@ -28,9 +28,7 @@ homelab-v2/
│ ├── archmirror/
│ ├── blog/
│ ├── external/ # External service vars (e.g. Home Assistant)
│ ├── firefly/
│ ├── gitea/
│ ├── grocy/
│ ├── homepage/
│ ├── immich/
│ ├── jellyfin/
@@ -49,19 +47,19 @@ homelab-v2/
| Service | Description |
|---------|-------------|
| **Gitea** | Self-hosted Git service |
| **Firefly III** | Personal finance manager |
| **Immich** | Photo and video management with face recognition |
| **Jellyfin** | Media streaming with Intel GPU hardware transcoding |
| **Media Stack** | Sonarr, Radarr, Prowlarr, qBittorrent — automated media acquisition |
| **Paperless-ngx** | Document management with OCR |
| **Pi-hole** | DNS sinkhole with ad blocking and encrypted DNS via dnscrypt-proxy |
| **Grocy** | Pantry and grocery management |
| **LubeLogger** | Vehicle maintenance tracker |
| **Homepage** | Dashboard aggregator |
| **Podsync** | Podcast downloader |
| **Archmirror** | Local Arch Linux package repository mirror |
| **Blog** | Personal static blog served via git-sync + nginx (gh-pages branch) |
| **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
@@ -41,6 +41,9 @@ spec:
value: ":514"
useRemoteIP: true
useLocalTimestamp: true
# Scraped by the stack's vmagent so ingestion stalls can alert.
vmServiceScrape:
enabled: true
resources:
requests:
cpu: 50m
@@ -59,10 +59,49 @@ spec:
vmalert:
enabled: true
# Telegram + email wired later (see monitoring-rpi5-setup.md step 11).
# Default config uses a blackhole receiver until then.
# k3s runs scheduler/controller-manager in one binary with no separate
# 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:
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:
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
data:
nginx.conf: |
worker_processes auto;
events {
worker_connections 1024;
}
@@ -15,6 +17,8 @@ data:
default_type application/octet-stream;
sendfile on;
# NFS reads block the worker; offload them so /health keeps answering
aio threads;
gzip on;
server {
-78
View File
@@ -1,78 +0,0 @@
# CryptPad Deployment TODO
## 1. Generate OIDC secret and update both configs
```bash
# Generate a random secret
openssl rand -base64 32
# Hash it for Authelia
docker run --rm authelia/authelia:latest authelia crypto hash generate pbkdf2 --variant sha512 --password 'YOUR_SECRET'
```
- [+] Decrypt Authelia configmap: `cd kubernetes && sops -d -i infrastructure/controllers/authelia/configmap.sops.yaml`
- [+] Replace `REPLACE_WITH_PBKDF2_HASH` with the generated hash
- [+] Re-encrypt: `sops -e -i infrastructure/controllers/authelia/configmap.sops.yaml`
- [+] Decrypt CryptPad secret: `sops -d -i app/cryptpad/secret.sops.yaml`
- [+] Replace `REPLACE_WITH_CRYPTPAD_OIDC_SECRET` with the plaintext secret
- [+] Re-encrypt: `sops -e -i app/cryptpad/secret.sops.yaml`
## 2. Fill in and encrypt backup secret
```bash
cd kubernetes && sops -d -i app/cryptpad/secret-backup.sops.yaml
```
- [+] Replace `REPLACE_REST_PASSWORD` with the password for the `cryptpad` htpasswd user on rest-server
- [+] Replace `REPLACE_WITH_STRONG_PASSWORD` x2 with restic repo passwords for NAS and B2
- [+] Replace `REPLACE_WITH_B2_KEY_ID` with Backblaze B2 application key ID
- [+] Replace `REPLACE_WITH_B2_APPLICATION_KEY` with Backblaze B2 application key
- [+] Re-encrypt: `sops -e -i app/cryptpad/secret-backup.sops.yaml`
## 3. Create NFS directories on Synology
SSH into Synology and run:
```bash
mkdir -p /volume3/k8s-storage/cryptpad-data
mkdir -p /volume3/k8s-storage/cryptpad-config
```
- [+] Directories created
## 4. Set up restic repos and htpasswd user
```bash
# Generate htpasswd entry and append to /volume1/docker/rest-server/config/htpasswd on Synology
docker run --rm httpd:2-alpine htpasswd -nbB cryptpad 'YOUR_REST_PASSWORD'
# Init Synology repos
restic -r "rest:http://cryptpad:PASSWORD@synology.storage.lviv:8888/cryptpad-data/" init
restic -r "rest:http://cryptpad:PASSWORD@synology.storage.lviv:8888/cryptpad-config/" init
# Init B2 repos
B2_ACCOUNT_ID=... B2_ACCOUNT_KEY=... restic -r "b2:berezovskyi-backup-homelab-cryptpad:/data/" init
B2_ACCOUNT_ID=... B2_ACCOUNT_KEY=... restic -r "b2:berezovskyi-backup-homelab-cryptpad:/config/" init
```
- [+] cryptpad htpasswd user added to rest-server
- [+] Synology repos initialised
- [+] B2 repos initialised
## 5. Commit, push and verify deployment
- [ ] Commit and push all changes
- [ ] Pod comes up healthy (first start is slow: OnlyOffice download + SSO plugin clone):
```bash
kubectl get pods -n cryptpad -w
kubectl logs -n cryptpad -l app=cryptpad --tail=50 -f
```
- [ ] Both domains resolve with valid TLS:
- https://cryptpad.berezovskyi.dev
- https://sandbox.cryptpad.berezovskyi.dev
- [ ] OIDC login works: "Register with Authelia" button appears and completes successfully
- [ ] Run a backup job manually to verify repos:
```bash
kubectl create job -n cryptpad --from=cronjob/cryptpad-data-backup test-backup-data
kubectl logs -n cryptpad -l job-name=test-backup-data -f
```
-63
View File
@@ -1,63 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: cryptpad-config
namespace: cryptpad
data:
application_config.js: |
(() => {
const factory = (AppConfig) => {
AppConfig.registeredOnlyTypes = AppConfig.availablePadTypes;
AppConfig.disableAnonymousPadCreation = true;
AppConfig.disableAnonymousStore = true;
return AppConfig;
};
if (typeof(module) !== 'undefined' && module.exports) {
module.exports = factory(
require('../www/common/application_config_internal.js')
);
} else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) {
define(['/common/application_config_internal.js'], factory);
}
})();
config.js: |
module.exports = {
httpUnsafeOrigin: 'https://${CRYPTPAD_HOST}',
httpSafeOrigin: 'https://${CRYPTPAD_SANDBOX_HOST}',
httpAddress: '0.0.0.0',
//httpPort: 3000,
//httpSafePort: 3001,
// websocketPort: 3003,
// maxWorkers: 4,
//otpSessionExpiration: 7*24, // hours
//enforceMFA: false,
//logIP: false,
adminKeys: [
"[oleksandr@cryptpad.berezovskyi.dev/wiMN+oF1CaWHMaWxv11M+xqvnjXfNgshqoKIvEcG9Ss=]"
],
//inactiveTime: 90, // days
//archiveRetentionTime: 15,
//accountRetentionTime: 365,
//disableIntegratedEviction: true,
//maxUploadSize: 20 * 1024 * 1024,
//premiumUploadSize: 100 * 1024 * 1024,
filePath: './datastore/',
archivePath: './data/archive',
pinPath: './data/pins',
taskPath: './data/tasks',
blockPath: './block',
blobPath: './blob',
blobStagingPath: './data/blobstage',
decreePath: './data/decrees',
logPath: './data/logs',
logToStdout: true,
logLevel: 'verbose',
logFeedback: false,
verbose: true,
installMethod: 'docker',
};
-123
View File
@@ -1,123 +0,0 @@
# Backs up user data (blob, datastore, data, block directories)
apiVersion: batch/v1
kind: CronJob
metadata:
name: cryptpad-data-backup
namespace: cryptpad
labels:
app: cryptpad-backup
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
metadata:
labels:
app: cryptpad-backup
spec:
restartPolicy: OnFailure
containers:
- name: resticprofile
image: creativeprojects/resticprofile:0.32.0
command:
- sh
- -c
- |
resticprofile -c /secrets/profiles.yaml -n cryptpad-data backup
resticprofile -c /secrets/profiles.yaml -n cryptpad-data copy
env:
- name: B2_ACCOUNT_ID
valueFrom:
secretKeyRef:
name: cryptpad-backup-config
key: B2_ACCOUNT_ID
- name: B2_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: cryptpad-backup-config
key: B2_ACCOUNT_KEY
volumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
- name: data
mountPath: /backup-data
readOnly: true
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 1Gi
volumes:
- name: secrets
secret:
secretName: cryptpad-backup-config
- name: data
persistentVolumeClaim:
claimName: cryptpad-data
---
# Backs up config and customization directories
apiVersion: batch/v1
kind: CronJob
metadata:
name: cryptpad-config-backup
namespace: cryptpad
labels:
app: cryptpad-backup
spec:
schedule: "0 3 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
metadata:
labels:
app: cryptpad-backup
spec:
restartPolicy: OnFailure
containers:
- name: resticprofile
image: creativeprojects/resticprofile:0.32.0
command:
- sh
- -c
- |
resticprofile -c /secrets/profiles.yaml -n cryptpad-config backup
resticprofile -c /secrets/profiles.yaml -n cryptpad-config copy
env:
- name: B2_ACCOUNT_ID
valueFrom:
secretKeyRef:
name: cryptpad-backup-config
key: B2_ACCOUNT_ID
- name: B2_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: cryptpad-backup-config
key: B2_ACCOUNT_KEY
volumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
- name: config
mountPath: /backup-config
readOnly: true
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
volumes:
- name: secrets
secret:
secretName: cryptpad-backup-config
- name: config
persistentVolumeClaim:
claimName: cryptpad-config
-175
View File
@@ -1,175 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: cryptpad
namespace: cryptpad
labels:
app: cryptpad
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: cryptpad
template:
metadata:
labels:
app: cryptpad
spec:
securityContext:
runAsUser: 4001
runAsGroup: 4001
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
initContainers:
# # Create required subdirectories on NFS volumes before subPath mounts are used
# - name: init-dirs
# image: busybox:1.36
# securityContext:
# runAsUser: 0
# runAsNonRoot: false
# command:
# - sh
# - -c
# - |
# mkdir -p /data/blob /data/datastore /data/data /data/block /data/onlyoffice
# mkdir -p /config/customize
# chown -R 4001:4001 /data /config
# volumeMounts:
# - name: data
# mountPath: /data
# - name: config
# mountPath: /config
# Clone the official CryptPad SSO plugin into an emptyDir shared with the main container
- name: install-sso-plugin
image: alpine/git:v2.47.2
securityContext:
runAsUser: 0
runAsNonRoot: false
command:
- sh
- -c
- |
git clone --depth=1 https://github.com/cryptpad/sso /plugin
chown -R 4001:4001 /plugin
volumeMounts:
- name: sso-plugin
mountPath: /plugin
containers:
- name: cryptpad
image: cryptpad/cryptpad:version-2026.2.0
ports:
- containerPort: 3000
name: http
protocol: TCP
- containerPort: 3003
name: api
protocol: TCP
env:
- name: CPAD_CONF
value: "/cryptpad/config/config.js"
- name: CPAD_MAIN_DOMAIN
value: "https://${CRYPTPAD_HOST}"
- name: CPAD_SANDBOX_DOMAIN
value: "https://${CRYPTPAD_SANDBOX_HOST}"
# Trust the Traefik pod CIDR so CryptPad sees real client IPs.
# Adjust if your pod CIDR is different.
- name: CPAD_TRUSTED_PROXY
value: "10.0.0.0/8"
- name: CPAD_REALIP_HEADER
value: "X-Forwarded-For"
- name: CPAD_REALIP_RECURSIVE
value: "on"
# Downloads and installs OnlyOffice frontend on first start (persisted via data PVC).
# First startup will be slower while OnlyOffice assets are fetched.
- name: CPAD_INSTALL_ONLYOFFICE
value: "yes"
volumeMounts:
# User data — split into subdirs on a single NFS PVC
- name: data
mountPath: /cryptpad/blob
subPath: blob
- name: data
mountPath: /cryptpad/datastore
subPath: datastore
- name: data
mountPath: /cryptpad/data
subPath: data
- name: data
mountPath: /cryptpad/block
subPath: block
# Customization (branding, themes) — persisted on NFS
- name: config
mountPath: /cryptpad/customize
subPath: customize
# OnlyOffice dist — local-path (not NFS): rdfind uses hard links which
# require a real filesystem, and scanning NFS for dedup is very slow
- name: onlyoffice
mountPath: /cryptpad/www/common/onlyoffice/dist
# SSO plugin — freshly cloned by init container on each pod start
- name: sso-plugin
mountPath: /cryptpad/lib/plugins/sso
# sso.js mounted directly from the secret — overlays the NFS config dir
# at this specific file path, no init container needed
- name: sso-secret
mountPath: /cryptpad/config/sso.js
subPath: sso.js
readOnly: true
- name: application-config
mountPath: /cryptpad/customize/application_config.js
subPath: application_config.js
readOnly: true
- name: application-config
mountPath: /cryptpad/config/config.js
subPath: config.js
readOnly: true
# npm run build runs on every start and can take several minutes.
# startupProbe absorbs that time; liveness/readiness take over once up.
startupProbe:
httpGet:
port: 3000
path: /
failureThreshold: 120
periodSeconds: 60
livenessProbe:
httpGet:
port: 3000
path: /
periodSeconds: 30
readinessProbe:
httpGet:
port: 3000
path: /
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 512Mi
limits:
memory: 2Gi
volumes:
- name: data
persistentVolumeClaim:
claimName: cryptpad-data
- name: config
persistentVolumeClaim:
claimName: cryptpad-config
- name: sso-plugin
emptyDir: {}
- name: onlyoffice
persistentVolumeClaim:
claimName: cryptpad-onlyoffice
- name: sso-secret
secret:
secretName: cryptpad-credentials
items:
- key: sso.js
path: sso.js
- name: application-config
configMap:
name: cryptpad-config
-24
View File
@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cryptpad
namespace: cryptpad
annotations:
cert-manager.io/cluster-issuer: letsencrypt
# No Traefik auth middleware — authentication is handled natively via the OIDC SSO plugin
spec:
tls:
- hosts:
- ${CRYPTPAD_HOST}
secretName: cryptpad-tls
rules:
- host: ${CRYPTPAD_HOST}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: cryptpad
port:
number: 3000
@@ -1,26 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cryptpad-sandbox
namespace: cryptpad
annotations:
cert-manager.io/cluster-issuer: letsencrypt
# The sandbox domain is required by CryptPad for CSP isolation of embedded content.
# It must be a different origin from the main domain but points to the same backend.
# No auth middleware — this domain serves sandboxed iframes with restrictive CSP headers.
spec:
tls:
- hosts:
- ${CRYPTPAD_SANDBOX_HOST}
secretName: cryptpad-sandbox-tls
rules:
- host: ${CRYPTPAD_SANDBOX_HOST}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: cryptpad
port:
number: 3000
@@ -1,56 +0,0 @@
# Default deny all ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: cryptpad
spec:
podSelector: {}
policyTypes:
- Ingress
---
# Allow Traefik to reach the CryptPad pod (both HTTP and API/WebSocket ports)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller
namespace: cryptpad
spec:
podSelector:
matchLabels:
app: cryptpad
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
ports:
- port: 3000
- port: 3003
---
# Allow backup pods egress to Synology (restic rest-server), B2, and DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backup-egress
namespace: cryptpad
spec:
podSelector:
matchLabels:
app: cryptpad-backup
policyTypes:
- Egress
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
- ports:
- port: 8000
protocol: TCP
- ports:
- port: 443
protocol: TCP
-33
View File
@@ -1,33 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: cryptpad-config-nfs
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: ""
persistentVolumeReclaimPolicy: Retain
mountOptions:
- hard
- noatime
- timeo=30
- retrans=3
nfs:
server: synology.storage.lviv
path: ${CRYPTPAD_CONFIG_NFS_PATH}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cryptpad-config
namespace: cryptpad
spec:
accessModes:
- ReadWriteOnce
storageClassName: ""
volumeName: cryptpad-config-nfs
resources:
requests:
storage: 10Gi
-33
View File
@@ -1,33 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: cryptpad-data-nfs
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
storageClassName: ""
persistentVolumeReclaimPolicy: Retain
mountOptions:
- hard
- noatime
- timeo=30
- retrans=3
nfs:
server: synology.storage.lviv
path: ${CRYPTPAD_DATA_NFS_PATH}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cryptpad-data
namespace: cryptpad
spec:
accessModes:
- ReadWriteOnce
storageClassName: ""
volumeName: cryptpad-data-nfs
resources:
requests:
storage: 100Gi
@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cryptpad-onlyoffice
namespace: cryptpad
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 5Gi
@@ -1,26 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: cryptpad-backup-config
namespace: cryptpad
stringData:
profiles.yaml: ENC[AES256_GCM,data:8t3Vx7GUX059eX6nxypFx/VacLL+hMy+muF3cybpSMNt5cQXONoUrFQnjW1VkWRgk/n/fqVa80HmT3g1JCeUBwNVDsM9DfH0VCiJxoMYrpDmYObkt82RUMnojhG6afPVPEduvaccOAjyslGnZAMAuQT+DIO/C8wayYDQJcIXJZeHorRJR/4P358EWw7h/p6ylNXGWPiI7IsIn0zsaePD3mshoA4ix+pUbBztTSk3Ij7iiGqltYIZkq8QYkOy4oiAmFTLxIlZfEfrMXrkOaHuvkGd1uftX3VfzJAaLmbGP5sEdkAPawYmGWLnU+ObFSL31zkbTCKhNtEwzQbDmw5RC4srVMj6UttDDs7LBzGZh/HUuXoKb+DIBlYV9siGwZH3bLrg7XoXVi2BimKPAQELlAtOfvOe7NZ8cBE34cCvd3MiZqN37uZYdx2sRHFPJp6PyWbglG2TIqj/J1lPKdZOMG7NpEvc2WXi8ltWjtNmDNjoLsaUh5+e3TqLIYkdd4BxwN0sEJFU/apyyGcS5/2TED0ZgBPINvdCVApTagNwIWjmi11VH2r5hxkb2OnZkwRjsyujmSexaFdS7jjBDXZNg6x1Q4vgBb70iCfTPqAGQyFkTpf3+AKopuPgto9LLztmmC7e4Q08D1ncDGatGRrgIXDhhhhFnbTKdle53gQKLWi8THxIF1/nlvu07zn+HYP5sWG38No2kpMJwCXeUoqXwHhcgVRlAyPka6ip+zWOyg/qdcJU4k4sCW4+DkrdwUHOCiT/0wYRMdeoDRJDLVS/5OESl3HboIQSTxDhgUid0iGH3zr35zwa3DR4mMXYPkh+Nodsp0oh5aG0lIDGrz+6lOVznYUTate1CVm3HN2zQPRyuTPMxILsEVC44qQ3KyR55VgZhwER2418wg68VFQA1uT8HTPEVZFPRgxdK4amIHr7cnC2B67/X0oeHJNbDEc0EAkEx8v08HklJQELNMNInRySW1UnBQOIWo3rl0PsZgyecWnK9vdwPjfEyzr8DVlfm7rGMNTWc7iIPwYom9jLHh4IgOU5TEVatwkd+zMS8ZeHPeFEdL/bf0YbdBqir8+X9ERSkG41OQGYL5Rhx3XM6oExfA4hGGqAEXfGTCAqIljkyKzo7280sIdkDvEBq+FMnCJ+APCSoPqNQUqZpEmWG/XP+Q+bgo5Pb32vlxL8dwcVmuiuu0cndW7gzA6YgfCRfTmGTNjW43J/h5ODBa8Vhu2WNiRMwCzH72ExOvwgKEBeP1LPHVcMLT0f/CMItcpzkuGwzlitZMAm2nmCdSB71hdtsKD6x5hIzhsDCAzZz6VCUF+NAgjOyks3urlDiBhyMnzetXnDgtLB1kL8qwIHOvWQoF5S50KrCbHTNJUhBWBJzRom7oZJOdyHwo7MmSMvRWTY5xA09umSia6/qyDlGeCHDYx/C8i3/WGUGsVKB2EzsfY=,iv:z79twnVkLyonYaOgz2f4ZW7noMlDxZgDRqYySBj+Mlk=,tag:2W0mtSBGiqgWPKDyZrKYRg==,type:str]
restic-password-nas: ENC[AES256_GCM,data:0g81dj/gNwnBPkbVXR1o5mZ4axAhnL7YwSNcnE2fI1DWly4cO3kNyxta5OdgTAGZwNeiT+qaOFi6HXHn9fSHlQ==,iv:OZEza2gkiygZ1KzvD3MJZ/JXIrfbcZenKcOJfMlEjvM=,tag:rnJ8sFQgzD6g3pEHRQLg3A==,type:str]
restic-password-b2: ENC[AES256_GCM,data:sazn2f09uZsFU1/MY30iPj0gx9pSFvcy/JgHsXTLMFbq5OimAfHsiYR1nMf2mQ8GwqMtQTF4t0lkfDnmy/8Qyg==,iv:HOI8oohNCCtP/heNBCQ5HEKfRVdMalv3MU/puRkOQ4A=,tag:aLKeUbwED2TjeAfkydj+MQ==,type:str]
B2_ACCOUNT_ID: ENC[AES256_GCM,data:Jh4gWGGt5wVaVAMG5oWFXW7W0Taq9Qiyhw==,iv:XZtsiYUtFtSDhgLpG3uNIGLHWqGmCM3zHq2RUu6tdXM=,tag:KQfrBmkAYadVvhtgAzDNzw==,type:str]
B2_ACCOUNT_KEY: ENC[AES256_GCM,data:XI+P//Ti512rQfDgmV00Bq3Wxly6//ESBKsDItXdug==,iv:/xAPGSJIathFIwyWUQoBW2DwYBpHnJCElnRMe16Pf9s=,tag:xSh2kFbQnw+bpAbbQ3rHWQ==,type:str]
sops:
age:
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlVGM3NlRSenp4d05sTEdY
c0JkdW5Xd2RQU3I4SlVTczVRWnVaRUY5RHdnClM1QVlGR3lRWGZCVXR0RjR1Kzlh
ck4vLzNpeThIdmV4citIaFlVWnpFWXMKLS0tIHV2aWtSVTRxMzUrbldwQVRLRHE5
ajAzS2pINWIvQTc0T0FhMit6ZHNVRlkKW6hYD2mjAtZRyC8/fbSWiij1/clTB4br
sAmsCMBIDQf+r12TuzzpLiMnNOIU349GcYxuA24GWaEanordqCLz3A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-13T12:31:48Z"
mac: ENC[AES256_GCM,data:O+jD7jCBoQYNrRr+j/yn4YkGLaggHee8YVmvE5I5QXOB5pfPg09yQbuYj2IhKPBbVXl24ejlNDEAG3/qDaWgg1IlB+dKeTyrqxWq+mQ7vM9bgNRhf4ozS1lL3NR23V6JhilrosxTlFYCajerxdUbCh0vBXqsdJ0cIV8yggtQ7eY=,iv:gJkOvEFY4L/7qE3zMYnnon8XcGUegmcWKvKQ+/rxBVo=,tag:xQ1Qo7SgOs3N8451xX7Yxg==,type:str]
encrypted_regex: ^(data|stringData|email)$
version: 3.12.1
-25
View File
@@ -1,25 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: cryptpad-credentials
namespace: cryptpad
stringData:
#ENC[AES256_GCM,data:s4VxDsDqwHw6ZhFNzA/mS+gdPwZlV5AcBDRUqfHTKSzjQPVg7unz7HkyfXtSBt36aH3P7fR9lUF1XtNvH9fF+6EfCa1dzIToSEw=,iv:TuYHrkjDFkA7fHhWzaHGrptyP5ClwiMArjoTf5LHXrQ=,tag:gvZxTmeeCEDTISgIpKxhhA==,type:comment]
#ENC[AES256_GCM,data:CXpQCo8r5GCE6lIpXpXlab0CEdMCuNC54Ynh4ahfE1fv2c49wNoiQNRQAjONbmhUoUIiUcCehNmuw/ZK5Fd3rvVUhXdUAKYo,iv:U6vrAHUz22QWSLxBYRFea+LXajuHIh8NlggB6DAoCjc=,tag:nnV8RMrNv+trUQgXpCvkJA==,type:comment]
#ENC[AES256_GCM,data:7TBFv3i2TzlyAcVhAdFE6T2F0E8pdAbYZorT6/brY8Ed+g6LvnwdVaYPcpJ7P6ETWXraqbhoktWICYklr35PAg==,iv:xsPinB1/gkzMHyzsrJ2gj8Fm0PWaIQbtBIB7fT1BTzI=,tag:O9dv+myneU7neE7JiRGuBQ==,type:comment]
sso.js: ENC[AES256_GCM,data:u1XHMXQKf6QtqqjzNx8LZIEZxKSWhVFZbgvKBqsGoKo7kve0nZynH/bYohVO3XDBtahBqDCgeAD/rj5OE2MlEhwF0OTfylpPmlDjD3tuwogMv2NSDwERzzGv2BvMY97kIRwbGP3OtHGEEGO32JmNKWInZH7BrazeX5gvNLKjHk8XtCN8jKxoJwGEYw7EM8s219iFyQISKjo9/yElv4JVlecIa1bcbzswRsgWqzjG3kBJ2HLRcnH4Nr8D8VCDEdO32GHS0Y9Z7b3eaaj0YQyWleyAfqlufktMcr+SFDSQy4sPnzFuydi7kPXRb6OVDZLaKMVA4422VEEsuAOcz5CUZIJAg5KhPz9lZsruRw3hZBTjhRE2G05TwsvJNwY005rVe2pHL/Q3OZRKNZIfXK34lOwnBQMnBPJvtogIT+hZUBBAyz82nuR8KuujsGLo4sJPC/Vuayg9CrwxbQRx7fit5sdu5djwvVleBKyayhbBaP23BZToB9znSNm5HCOpohpAg4OYXazRpLBGH6lHla1tZy7MpfnoltEOHjeBQoqpez3zBQ9zNichIuPVnIK0h1dqAjLlZc5n7d9L6AHDrzSRq40iOnuc4ZuATMXtmd1JynSrjCH4FYKtROV9V3JXUCK9GwnZ04D26rbwxCKKykHkABF4AFDvv4ZeJPvN+Ag6R8TuSG74qzRUjvBP1+2uR/y9IsN5dGviYKzGnVFvkD87RrF3nZQc40+C4CfAuP9xTLJPzZ0b1t6Qr3Q52LipSyOt/I04ULToOU4U7heEkpbZxJAWiAlgLskjy9TfL/OY1uyZT9ZanWAhRVBa0dk2h8I5p9a01XtR8X3sIqg41i1K3VqEcKGk7IQMf+WmiUdLef7qx6Gq3+Di067NJ7fKKNAN3IFGE/LBlBVaj1fQNOaCfjSJ/A==,iv:FSSJUe6ymLHIM5CQLVgemHX71Z7Bz609WsNkOs9QM1E=,tag:Wxdnfa6WXyXVxI3VjU6dMA==,type:str]
sops:
age:
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5Vm8xRmZ0WDJRMmNPVUxq
T3VQSUVUYnVER0FFVW5FYWFHaUV3S2daWFJvCmxLdWpLVHpnMWNQaTlDZ0VOZ0JL
K044cmpRZm50SmZNNWZlWjBDS1hGS2cKLS0tIGRxMnZTTWRRMlg5eVBOb3pVYUlK
clRoWlp2SjQrOGFjQW92VnQ4amxUMXMKMjcBWo44X+Y2kmwpKZcBsBZZkWQJZEOf
VscZUj8VAZKF9IxOmbBaFc2EBi5xI7sYJSJ+gaLHHKLhcSNu59P+kQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-13T19:48:58Z"
mac: ENC[AES256_GCM,data:0mpN6sWiCHp3zVIKIdIEAnBEcczPb1YVfj4fae50JnJ4jF9ZZ6Wz4sQny00LKN59NFFHHM5bOa+ibqEXZ3pgtF0WQmmc5Sfn5w6n66L4mSJ0Pjx4akMJYjt5xMkRuLG996yZXg7pvSd3YrMgJEqf0hiexN+KJMLDqUwDIYpUHpc=,iv:BMIyWxc0k8SZTxS9/F3Vxfa4HY/WordDRQTfJmZZSI0=,tag:FpPT98LvKY2HgeBfZOw5TQ==,type:str]
encrypted_regex: ^(data|stringData|email)$
version: 3.12.1
-17
View File
@@ -1,17 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: cryptpad
namespace: cryptpad
spec:
selector:
app: cryptpad
# Session affinity ensures WebSocket connections always reach the same pod
sessionAffinity: ClientIP
ports:
- port: 3000
targetPort: 3000
name: http
- port: 3003
targetPort: 3003
name: api
@@ -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: {}
@@ -1,4 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: cryptpad
name: dawarich
@@ -2,7 +2,7 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: firefly
namespace: dawarich
spec:
podSelector: {}
policyTypes:
@@ -12,11 +12,11 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller
namespace: firefly
namespace: dawarich
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: firefly-iii
app: dawarich
policyTypes:
- Ingress
ingress:
@@ -29,18 +29,18 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app-to-db
namespace: firefly
namespace: dawarich
spec:
podSelector:
matchLabels:
app: firefly-db
app: dawarich-db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: firefly-iii
app: dawarich
ports:
- port: 5432
---
@@ -48,18 +48,18 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backup-to-db
namespace: firefly
namespace: dawarich
spec:
podSelector:
matchLabels:
app: firefly-db
app: dawarich-db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: firefly-backup
app: dawarich-backup
ports:
- port: 5432
---
@@ -67,11 +67,11 @@ apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backup-egress
namespace: firefly
namespace: dawarich
spec:
podSelector:
matchLabels:
app: firefly-backup
app: dawarich-backup
policyTypes:
- Egress
egress:
@@ -92,4 +92,23 @@ spec:
to:
- podSelector:
matchLabels:
app: firefly-db
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
+190
View File
@@ -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}
+38
View File
@@ -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
}
]
}
@@ -1,8 +1,8 @@
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: firefly-iii
name: cogitri
namespace: flux-system
spec:
interval: 1m0s
url: https://firefly-iii.github.io/kubernetes
url: https://charts.cogitri.dev
+27
View File
@@ -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
+12
View File
@@ -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
-4
View File
@@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: firefly
-83
View File
@@ -1,83 +0,0 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: firefly-iii
namespace: flux-system
spec:
chart:
spec:
chart: firefly-iii
version: 1.9.13
reconcileStrategy: ChartVersion
sourceRef:
kind: HelmRepository
name: firefly-iii
namespace: flux-system
targetNamespace: firefly
interval: 1m0s
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
values:
deploymentStrategyType: Recreate
image:
# renovate: datasource=docker depName=fireflyiii/core
tag: version-6.6.6
podSecurityContext:
seccompProfile:
type: RuntimeDefault
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 512Mi
persistence:
enabled: true
storageClassName: nfs-synology-ssd
storage: 5Gi
config:
existingSecret: firefly-credentials
env:
DB_HOST: firefly-db
DB_CONNECTION: pgsql
DB_PORT: "5432"
DB_DATABASE: firefly
DB_USERNAME: firefly
TZ: Europe/Kyiv
TRUSTED_PROXIES: "10.244.0.0/24"
APP_URL: https://${FIREFLY_HOST}
AUTHENTICATION_GUARD: remote_user_guard
AUTHENTICATION_GUARD_HEADER: Remote-Email
AUTHENTICATION_GUARD_EMAIL: Remote-Email
MAIL_MAILER: smtp
MAIL_HOST: smtp.protonmail.ch
MAIL_PORT: "587"
MAIL_ENCRYPTION: tls
cronjob:
enabled: true
auth:
existingSecret: firefly-credentials
secretKey: STATIC_CRON_TOKEN
schedule: "0 3 * * *"
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.middlewares: authelia-chain-authelia-authelia-auth@kubernetescrd
hosts:
- ${FIREFLY_HOST}
tls:
- secretName: firefly-tls
hosts:
- ${FIREFLY_HOST}
-44
View File
@@ -1,44 +0,0 @@
{
"kubernetes": {
"fileMatch": ["kubernetes/app/firefly/.+\\.yaml$"]
},
"customManagers": [
{
"customType": "regex",
"fileMatch": ["kubernetes/app/firefly/release\\.yaml$"],
"matchStrings": [
"#\\s*renovate:\\s*datasource=(?<datasource>\\S+)\\s+depName=(?<depName>\\S+)\\s*\\n\\s*tag:\\s*[\"']?(?<currentValue>[^\\s\"']+)"
]
}
],
"packageRules": [
{
"matchFileNames": ["kubernetes/app/firefly/**"],
"semanticCommitScope": "k8s/firefly"
},
{
"description": "Tags are version-X.Y.Z; skip floating version-X.Y, version-X, latest, develop",
"matchFileNames": ["kubernetes/app/firefly/**"],
"matchPackageNames": ["fireflyiii/core"],
"versioning": "regex:^version-(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)$"
},
{
"matchFileNames": ["kubernetes/app/firefly/**"],
"matchPackageNames": ["fireflyiii/core"],
"matchUpdateTypes": ["patch", "minor"],
"automerge": true
},
{
"matchFileNames": ["kubernetes/app/firefly/**"],
"matchPackageNames": ["fireflyiii/core"],
"matchUpdateTypes": ["major"],
"automerge": false
},
{
"description": "Ignore infrastructure images",
"matchFileNames": ["kubernetes/app/firefly/**"],
"matchPackageNames": ["postgres", "creativeprojects/resticprofile"],
"enabled": false
}
]
}
@@ -1,26 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: firefly-backup-config
namespace: firefly
stringData:
profiles.yaml: ENC[AES256_GCM,data:2IDoUurD5tw5uTUX/rWuhGZbaCcYcR/J2ClSdr61rq5w1jjZunnyqeY8Vrp2LSaiDhYd6nIHB0oeM8HVsvkzbLksXVzbS/4/098KEJtey3I7yxfvvlgu9ZKbw0wuLqeXjfEkl7cArTdjMKwA3/B5/Jmqw9Q0g5QUPP97MF12Hagg/kpKipXD/n5YoOtv7ZqfHnxrIIh6XXIpa98pJ58x+7ct7K7DeUUj1s/3WAI7idJ4kTexwOb/NVup9qpheuxqAZmF0z8YUC73W0qzQzgUAOJ4+O09xc15PFRq19a95W9SnSHn8Ao56S67s26d2Hbp4JCa8U6MxHDJ09IdHzpu/bmGAVL6LxDheegYOLZWJtNoAryyE6sQN2PJQxIwFngKaMvs6CHSrZWIbCfKzIhNrJPr/u/l5pDvCSMcvg2oX7Bkc2uJ4WY/yFXSHhaWIdJv0VSvcUH04li1inrZe9AYfnsajRVuzgXrnhonqy/2NXrH32leSVjEeU97+Ma1eOX/t3+SNBglL5kJxJIRJ/tSkPDe/9GpVr+2QNQUmRMuIpSsRNQgGODU/XCFrMyJ1Ikl+pKhHitOELfckJ3FuZPRJB6HEqfkE2fZLK5e2G0JRJ4FinYFo6HkXzk4IAzLDlN2E7kgyPyCqHJQt4C/X+OTwE6MErPEPgE5o9pwC8TGv+Q8AN6rRdYs7FPBR9jxqWxoSTCdz49sVf/kcgcWnicn8XmFEGdWTWk3MqKDe8YdN6fyqPha2lxpsz7FkZMcTV2ZrLvIR65lkmL9Vb1I7SwroYuTr+sj3jTAJLZXgRTXpKodc2zTQR9rQEKvA1C7YgchTJa4axDkMY37MDHZnHPW6MEmPlpPw8NMge6QfNYDTAWvrwThGWQ051RSm8KbYfm+qlMWqx+zCFRcypKwBUKVWuf7TYa0jnL9u4QrUvpLBAr6jErNRdRLgm79h80n/ucPEBLCHlzhPzHGW/evdWMDTCd0B5dYbP0zpPkGEmzfBfnH23ru48DotzPV/y0j+SNacgUXQPFkC5x50jOS2Fay+5qInOyA75aSiFD5EMZmf8gx1a3+rDtUt+6Qict8Umtb3ZzpTrWxvxbV5oxCXNwWShSLAFyfwoNE1sEq++xu+Jp0SzTuSg+Kxz+CmuCJ4bnbYkrhJxyKfw==,iv:WdIFJmhmZ8S+ma5l5SS7de2PrxZJgKK2njrPbLVQSuo=,tag:/mPn6QHatxQYwsZInrK30w==,type:str]
restic-password-nas: ENC[AES256_GCM,data:RIn57MOwyqVGR/GuVpIXi+p5jZ2UQm4VgioCgE1GXIk=,iv:DcF6cD+AVa0LoXY6+wACfQvoAtdndl0chmPcm463fEE=,tag:RK9FF1RMFsfHGmg+ZcBEVA==,type:str]
restic-password-b2: ENC[AES256_GCM,data:nIcy6uJY4fCjQH3aVggt3meckNAytAsw/ZNnGBBm7DM=,iv:zPf9YTDgT9dlq1nlyW6weMjZ0b3eVAuB15Lyx897xGU=,tag:+x0Sn3UQZEyhdMYrTK+Nqg==,type:str]
B2_ACCOUNT_ID: ENC[AES256_GCM,data:t4YqtZRIpLpP7QHGBTeZ8vCL2L+1BjbLug==,iv:TvsBorT7r5A1d1AjPbYZ2vnm0x7gCPe4qY2bXFoK66Y=,tag:zaRhrGV/4siiWiykPlF6Gw==,type:str]
B2_ACCOUNT_KEY: ENC[AES256_GCM,data:xZjFBj7oT2FcKHdwGBzyD1xR/bKtHGLEBsnAqblE+g==,iv:gtJfZvTZucbx6983OOk7WdD8KhJtrW6Wv0hnECYXQ8s=,tag:DCvHrL1Wv3NodzbH5aXylQ==,type:str]
sops:
age:
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRSVBheDRtOEd0T0RJeG5x
dnRtN2RTeEs1andrVk9XUTZtMklDdmx5aEhrCmlNR1puUHVGaFYrUHNHYU1hbnpz
Q2J2ditrY1FuTXg3MUsvWm05WFcrUVUKLS0tIHdqeGFvNnkvVkdPWUphSkhETUpi
R1RWWEpDVkdHamx3M1p5a2YwUkR2REEKp/sZFcCNeZnHCvpwcOu827HLg0wxLWJG
EXHzgm5lZgiA/pQgxOJCiaz9HoNn3ttVE8z3aCnShUqAoXzpnh1Rpw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-04-21T20:22:40Z"
mac: ENC[AES256_GCM,data:wlXAnMwySlqHadgeAtgC+QCceqSw+mODWzKrqOTb4JSqvK1aEbPDUJWn8ow+0ff5OcU/3XVBr6b9GVzD6DsPXhg/aLsM/d5h6BRFb/qmrusD5YRyScu/gokwiD52I3qDf7rHeLNsYmoO4I6KuwEQRXasJ6H+QIOTNUxbcd+TTnM=,iv:8dNbZg7oJODgdR7mT3XgKL7sXooNYAvr8GM2l0DK6ao=,tag:M2JPh6qkisTG+A+2DCgABA==,type:str]
encrypted_regex: ^(data|stringData|email)$
version: 3.12.2
-30
View File
@@ -1,30 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: firefly-credentials
namespace: firefly
stringData:
APP_KEY: ENC[AES256_GCM,data:OugBKeVQqUDf8rFrGxMYgNROPesgVLsoKuQmWVvW9Kg=,iv:hnASzIOuoLczCUf0Luq2d6YXz5sKoHHawSys29cCMaE=,tag:u3SeTEc0VIb/NOwnXTn9Vg==,type:str]
STATIC_CRON_TOKEN: ENC[AES256_GCM,data:YL+ghixRjb1t6K1Q09clyxlYeYSj3rsy82n78efFVAw=,iv:V2q7uKOpl3e/FROZFvH7YCXBSUnQm7QcwqFyZaBbx2I=,tag:dZ1XPxEOGgAvfyL426rDTw==,type:str]
DB_USERNAME: ENC[AES256_GCM,data:Vk4jFf4Znw==,iv:LpP9DqkC1IlAwFNak8MTLPLf75iEpDwEm9ReLZPxRJo=,tag:qMexrfvQONJjfG11xh07wA==,type:str]
DB_PASSWORD: ENC[AES256_GCM,data:SsGb3qXMiq7EqGyfU2E6xqku1HbmWM8C,iv:+3V3Fh76gim9wcrhYd6CX7smyz0Kc8Qywx5j0wrmVaw=,tag:UawliAt7zOD0rpxNe3KcPw==,type:str]
DB_DATABASE: ENC[AES256_GCM,data:tLd4MWLoqQ==,iv:sG65BMBOAaKqYgCZ/xpv7LYaDNAPX+9KAeOBvYfUbgw=,tag:tRKptDmGV3iwV6luVFv/wQ==,type:str]
MAIL_USERNAME: ENC[AES256_GCM,data:npTpeFJuH7rOmPN7+0tuAgSdK+OxIjHIOHFVhFGcwA==,iv:ugGlT9MfWedvLFb/iQTxSIB5pPQsKGS5utalEP0pyUs=,tag:iv1i73xuCs0svFIgysb9dA==,type:str]
SITE_OWNER: ENC[AES256_GCM,data:WhpJSSWjniUumYjtRLHbOc51tcZ84JBtWw==,iv:nfy/1lXXlQYQW49LQevRevbVee1DODvqFKLPm3nRmU0=,tag:3nMwbS06dxD8oTvURw3OWA==,type:str]
MAIL_FROM: ENC[AES256_GCM,data:JcZt/4D8pa6St+3Z5oX61Ez7I0PscCIDSJhVnDUyfQ==,iv:r8rSDEXjdWzpivA3QQQRiQScdv6rNK5VzAnlwl+13jQ=,tag:N55MPwZ6KGO9L18DTOJ/CA==,type:str]
MAIL_PASSWORD: ENC[AES256_GCM,data:YrqECSPI6I7aYdx+oUmgGA==,iv:rvggM+Chw0JIOqfifzH5Q5yw4JhAv5BZgJfKevfWm2c=,tag:c9Wmxy8iivL4DKwEQj8VPg==,type:str]
sops:
age:
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWdDRxUU1walNTNWY1VlVj
MVB3OFo2Nm03b3haTjFtV09TaWtuYnJXNEN3CmFFOUM4czgxWGFubUJrNDRpOTBq
eHB0ckJNZnltMC84S2NyQVRmUWNNMjQKLS0tIERUL0hwSzVmYlRHSVJwVnE0bkVt
Zm1kOVhMU0JOa1U1MzN2M2FhdlVYUG8KhOhnu/8FxuEJdW5O0HeYVCu5eLgeyqaN
Q88TjwbcwcIruXo/e0ATxWRp+yzwGB0nspQHZzAMP16uN6r3gZo3Zw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-04-22T21:18:05Z"
mac: ENC[AES256_GCM,data:JszWTjBGpBSuldSp+k/ZhO9P6+v+6WhTddv56WSHkkh1JT0JnomgKYReMj5bDxYeA6hJPLgFmD0N4gjporu3n8oCvADJgpXnVTEmYPnIJJqhEn3z8pGCKjeuxEvJk1MV7XvLEhZZJuvvb04uquyxvl1M8h9BJSCuPk7wxcM5pLA=,iv:MlF48Pqoi4239h3NAFj0VMO6YXJSt88GqCT+cA0qqXY=,tag:/mgkPgXMX3iyTomvKikO8A==,type:str]
encrypted_regex: ^(data|stringData|email)$
version: 3.12.2
-76
View File
@@ -1,76 +0,0 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: grocy-config-backup
namespace: grocy
labels:
app: grocy-backup
spec:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
metadata:
labels:
app: grocy-backup
spec:
restartPolicy: OnFailure
initContainers:
- name: sqlite-backup
image: alpine:3.21
command:
- sh
- -c
- |
apk add --no-cache sqlite
sqlite3 /db-local/grocy.db ".backup /backup/grocy.db"
volumeMounts:
- name: db
mountPath: /db-local
readOnly: true
- name: backup-tmp
mountPath: /backup
containers:
- name: resticprofile
image: creativeprojects/resticprofile:0.32.0
command:
- sh
- -c
- |
resticprofile -c /secrets/profiles.yaml -n grocy-config backup
resticprofile -c /secrets/profiles.yaml -n grocy-config copy
env:
- name: B2_ACCOUNT_ID
valueFrom:
secretKeyRef:
name: grocy-backup-config
key: B2_ACCOUNT_ID
- name: B2_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: grocy-backup-config
key: B2_ACCOUNT_KEY
volumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
- name: config
mountPath: /config
readOnly: true
- name: backup-tmp
mountPath: /backup
volumes:
- name: secrets
secret:
secretName: grocy-backup-config
- name: config
persistentVolumeClaim:
claimName: grocy-config
- name: db
persistentVolumeClaim:
claimName: grocy-db
- name: backup-tmp
emptyDir: {}
-96
View File
@@ -1,96 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: grocy
namespace: grocy
labels:
app: grocy
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: grocy
template:
metadata:
labels:
app: grocy
spec:
securityContext:
# runAsNonRoot omitted — LinuxServer image requires root for s6-overlay init
seccompProfile:
type: RuntimeDefault
initContainers:
- name: migrate-db-to-local
image: busybox:1.36
command:
- sh
- -c
- |
if [ ! -d /config/data ]; then
echo "No /config/data yet — skipping"
exit 0
fi
cd /config/data
for db in *.db; do
[ -f "$db" ] && [ ! -L "$db" ] || continue
echo "Migrating $db to local storage..."
cp "$db" "/db-local/$db"
rm -f "$db"
ln -sf "/db-local/$db" "$db"
done
echo "Done"
volumeMounts:
- name: config
mountPath: /config
- name: db
mountPath: /db-local
containers:
- name: grocy
image: linuxserver/grocy:4.6.0
ports:
- containerPort: 80
name: http
protocol: TCP
env:
- name: PUID
value: "1027"
- name: PGID
value: "100"
- name: TZ
value: Etc/UTC
- name: UMASK
value: "002"
- name: GROCY_AUTH_CLASS
value: "Grocy\\Middleware\\ReverseProxyAuthMiddleware"
- name: GROCY_REVERSE_PROXY_AUTH_HEADER
value: Remote-User
volumeMounts:
- name: config
mountPath: /config
- name: db
mountPath: /db-local
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 90
periodSeconds: 30
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 30
periodSeconds: 10
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 512Mi
volumes:
- name: config
persistentVolumeClaim:
claimName: grocy-config
- name: db
persistentVolumeClaim:
claimName: grocy-db
-24
View File
@@ -1,24 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grocy
namespace: grocy
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.middlewares: authelia-chain-authelia-authelia-auth@kubernetescrd
spec:
tls:
- hosts:
- ${GROCY_HOST}
secretName: grocy-tls
rules:
- host: ${GROCY_HOST}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: grocy
port:
number: 80
-50
View File
@@ -1,50 +0,0 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: grocy
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller
namespace: grocy
spec:
podSelector:
matchLabels:
app: grocy
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backup-egress
namespace: grocy
spec:
podSelector:
matchLabels:
app: grocy-backup
policyTypes:
- Egress
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
- ports:
- port: 8888
protocol: TCP
- ports:
- port: 443
protocol: TCP
-33
View File
@@ -1,33 +0,0 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: grocy-config-nfs
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
storageClassName: ""
persistentVolumeReclaimPolicy: Retain
mountOptions:
- hard
- noatime
- timeo=30
- retrans=3
nfs:
server: synology.storage.lviv
path: ${GROCY_NFS_PATH}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grocy-config
namespace: grocy
spec:
accessModes:
- ReadWriteOnce
storageClassName: ""
volumeName: grocy-config-nfs
resources:
requests:
storage: 5Gi
-12
View File
@@ -1,12 +0,0 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grocy-db
namespace: grocy
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 1Gi
@@ -1,26 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: grocy-backup-config
namespace: grocy
stringData:
profiles.yaml: ENC[AES256_GCM,data:oCTBX2/3P6xmhgi4ObZ81gl8goRVbqn1kL0ZNbiyurzX+omqsk7RrpVpKXsBwAXbqDIvwAk6gWyFQwT3g8LQEzpLJTXLSJE4pNSlpK3V02xtWzQu+28rPptnpRKqYqLM7DGeTmm1AJwzTNaCG7X46RBCc1gWP8S6vXvjjwpdqpsJH3G2zQpZsx8fmlRC3Vc38DWq1EQatnOi+RFMd2e7WufL6Yari9r14E8tpp3s1CZ1qwQ9W9K5uHAjXI+kuPL/NVRqYzkqwuSvmD4QTtHhH1eyu3WFIkIkah1tDYAivy+wCZjMLSe+q6heHiXIMV5IaVj0tTg/L5wbjwwQZXB53nnbuadViPuC3kFBej7QHkx6hwIMmEgKsp2skG7mFFLkYm9AXDOUxUZlrVU3eN47PxR2nFNYiWoQi5YSYkltBA4eEFZ9d4EKFcxWqj1tr7Y4VDtTjz2ZEfff/eyu8oJ75XdFb74Or8PXBKfFUpLjtOnax7Dc7Ff/fv1oTCvmHSxyv4pgdCfrkwERnMd5DspkxEppCqPpxtxMVIp31cAWDkvJ21wmCR9esCVHfe1eTj4+76Ok7c3vEXy49M/K9GstwPIWcEwiDrvftiXMEgHn95YRcNBGdjh3nLJ76DTO+pTsuVoOW5Bogcn4W7hGrgYKFFFESMzXUWRlF15YPN0RHg/2TI0I9Ke1lIOhUZj1ljefH9UwnERhKmXZ7AlsXvDPqUpYPwPmW55bbkDDa/VDp58BLA==,iv:tfWTMYk99Jkje9GAHLEUu77LIIP3XQjWaR25HQYHOLg=,tag:chdgdkDNp57f3OCIEOcYTw==,type:str]
restic-password-nas: ENC[AES256_GCM,data:bG0LFnoo84t/r+cOGwjBPALc4dzrUj3Y9sMIuF7W1bjEkC9XsvSTQkczK1vmevhKuWdaaPYBr72gFzHcga7hUQ==,iv:tD1zf/mWknbMWtn/k0o8zJPcNvBK2Xa12eNSPyarybI=,tag:b03st6HrnpgXgkjDn0Gp+Q==,type:str]
restic-password-b2: ENC[AES256_GCM,data:nyDMggQFE5Z2aCz/+kTdIIYe2BXisTb/MlVRfiRMCKjPPZDQ49jyf3z986jEXp9CyxKK665ySjnZEXn3txi/PQ==,iv:xvdCBKhlFPMH4cTXSm2VtFlpJlgbiggvdvfyjB7b76I=,tag:HEoizYHWcnkVTAe3APWsMA==,type:str]
B2_ACCOUNT_ID: ENC[AES256_GCM,data:iXPdIOHzrggnh2pjimgFpQPNmA2FZgj8Mg==,iv:uS91Eg9xOHdZH113zfzlldgmCnFTopuOx/mmlsQsUC8=,tag:QDtAIhKwUkpt3v/tRZBYFA==,type:str]
B2_ACCOUNT_KEY: ENC[AES256_GCM,data:RLT5JBRs7JfcJzFv6MilqXUTf5MocOeB1Pp1kQaUcg==,iv:FqyfAgE0wM7KFdPTBM2s3eKrXvzeUCO7qLyUwZUCPqM=,tag:rM15UoD2CyZ4yRYAQJ6xoA==,type:str]
sops:
age:
- recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArR1BFRmFZU3dJblVEVnRr
bksyUzVHU0NjUkY2bGlXMzh3N0VEall4TFNVCmlBOUM4UnBPeVRPOHp3SnI5djUr
elpodVdqSWt2L0ovMFZCNUZTVkxIcVEKLS0tIDRvNzdSQ3hxN0o3R3ViSzJoQi9E
eDZTN3Fzak81RDJPR2dVOHlKOHJURzAK8DUPG6iCb6s7CQ6/+TZrIcLDKbN8bmh6
lUwBN0Ciu8OAX+tRW6P3R/iZebc9s5jH/VkzGsR9qGjKw5BsNB811Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-03-11T19:28:51Z"
mac: ENC[AES256_GCM,data:2SpDKL7Mwu/h7KLQoBXnk9iB84XNaex8hVbaUqmq4myIHAzvntb/zLXOexhsKPbQ0Ea7QDOKZIpkAG2dBPtRMtZWTr9uPpMoHzQG2lDGnYKGvBJXW/7WmaCdXlDf1FukqnYJZ3YoY+5xpTpYpXbWv1fyygp1YWmjKzY5qfcjtvw=,iv:TNbbiRmRRvPuQKiBjan7CVylNrt+eTjXxwKTJbeOhLw=,tag:9bqc9L4LlSq/d+oT257rsQ==,type:str]
encrypted_regex: ^(data|stringData|email)$
version: 3.12.1
-12
View File
@@ -1,12 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: grocy
namespace: grocy
spec:
selector:
app: grocy
ports:
- port: 80
targetPort: 80
name: http
+5 -4
View File
@@ -24,6 +24,7 @@ data:
type: jellyfin
url: https://${JELLYFIN_HOST}
key: "{{HOMEPAGE_VAR_JELLYFIN_API_KEY}}"
version: 2 # Jellyfin 12 dropped /emby paths and ?api_key auth
enableBlocks: true
enableUser: true
enableMediaControl: false
@@ -86,14 +87,14 @@ data:
icon: paperless-ngx.png
href: https://${PAPERLESS_HOST}/
description: Documents storage
- Grocy:
icon: grocy.png
href: https://${GROCY_HOST}/
description: Chores and inventory tracker
- Vikunja:
icon: vikunja.png
href: https://${VIKUNJA_HOST}/
description: Task management
- Reitti:
icon: mdi-map-marker-path
href: https://${REITTI_HOST}/
description: Location history
widgets.yaml: |
---
+1 -1
View File
@@ -24,7 +24,7 @@ spec:
type: RuntimeDefault
containers:
- name: homepage
image: ghcr.io/gethomepage/homepage:v2.3.0
image: ghcr.io/gethomepage/homepage:v2.7.0
ports:
- containerPort: 3000
name: http
+1 -1
View File
@@ -28,7 +28,7 @@ spec:
main:
image:
repository: ghcr.io/immich-app/immich-server
tag: v3.2.0
tag: v3.3.6
resources:
requests:
cpu: 100m
+13 -5
View File
@@ -5,6 +5,11 @@
# 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
# 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
kind: CronJob
metadata:
@@ -27,14 +32,15 @@ spec:
restartPolicy: OnFailure
initContainers:
- name: sqlite-backup
image: alpine:3.24
image: alpine:3.21
command:
- sh
- -c
- |
set -e
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:
- name: db
mountPath: /db-local
@@ -84,7 +90,8 @@ spec:
# media files and the metadata providers.
# 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
# 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
kind: CronJob
metadata:
@@ -107,7 +114,7 @@ spec:
restartPolicy: OnFailure
initContainers:
- name: sqlite-backup
image: alpine:3.24
image: alpine:3.21
command:
- sh
- -c
@@ -116,7 +123,8 @@ spec:
apk add --no-cache sqlite
mkdir -p /backup/introskipper
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
volumeMounts:
- name: config
+1 -1
View File
@@ -43,7 +43,7 @@ spec:
mountPath: /db-local
containers:
- name: jellyfin
image: jellyfin/jellyfin:12.0
image: jellyfin/jellyfin:12.4
env:
- name: JELLYFIN_PublishedServerUrl
value: https://${JELLYFIN_HOST}
+1 -1
View File
@@ -18,7 +18,7 @@ spec:
values:
image:
# renovate: datasource=docker depName=ghcr.io/hargata/lubelogger
tag: "v1.7.3"
tag: "v1.7.4"
updateStrategy:
type: RollingUpdate
@@ -45,10 +45,13 @@ spec:
- psql -d postgres -c 'CREATE DATABASE "prowlarr-log"' || true
containers:
- name: prowlarr
image: lscr.io/linuxserver/prowlarr:2.5.2
image: lscr.io/linuxserver/prowlarr:2.7.0
envFrom:
- configMapRef:
name: media-common-env
env:
- name: PROWLARR__SERVER__TRUSTEDNETWORKS
value: ${POD_CIDR}
ports:
- containerPort: 9696
name: http
@@ -29,7 +29,7 @@ spec:
mountPath: /media
containers:
- name: qbittorrent
image: lscr.io/linuxserver/qbittorrent:5.2.3
image: lscr.io/linuxserver/qbittorrent:5.3.0
envFrom:
- configMapRef:
name: media-common-env
+4 -1
View File
@@ -54,10 +54,13 @@ spec:
- psql -d postgres -c 'CREATE DATABASE "radarr-log"' || true
containers:
- name: radarr
image: lscr.io/linuxserver/radarr:6.3.0
image: lscr.io/linuxserver/radarr:6.4.4
envFrom:
- configMapRef:
name: media-common-env
env:
- name: RADARR__SERVER__TRUSTEDNETWORKS
value: ${POD_CIDR}
ports:
- containerPort: 7878
name: http
+4 -1
View File
@@ -54,10 +54,13 @@ spec:
- psql -d postgres -c 'CREATE DATABASE "sonarr-log"' || true
containers:
- name: sonarr
image: lscr.io/linuxserver/sonarr:4.0.19
image: lscr.io/linuxserver/sonarr:4.0.20
envFrom:
- configMapRef:
name: media-common-env
env:
- name: SONARR__SERVER__TRUSTEDNETWORKS
value: ${POD_CIDR}
ports:
- containerPort: 8989
name: http
+1 -1
View File
@@ -18,7 +18,7 @@ spec:
targetNamespace: media
values:
image:
tag: v3.4.1
tag: v3.5.1
podLabels:
app: seerr
extraEnv:
@@ -21,7 +21,7 @@ spec:
type: RuntimeDefault
containers:
- name: tika
image: apache/tika:3.3.1.0
image: apache/tika:3.3.3.0
env:
- name: TZ
value: Europe/Kyiv
+28 -3
View File
@@ -24,7 +24,7 @@ spec:
type: RuntimeDefault
containers:
- name: paperless
image: ghcr.io/paperless-ngx/paperless-ngx:3.1
image: ghcr.io/paperless-ngx/paperless-ngx:3.4
ports:
- containerPort: 8000
name: http
@@ -86,6 +86,31 @@ spec:
value: allauth.socialaccount.providers.openid_connect
- name: PAPERLESS_SOCIALACCOUNT_ALLOW_SIGNUPS
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:
- name: data
mountPath: /usr/src/paperless/data
@@ -110,9 +135,9 @@ spec:
resources:
requests:
cpu: 100m
memory: 512Mi
memory: 1536Mi
limits:
memory: 5Gi
memory: 6Gi
volumes:
- name: data
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
+2 -2
View File
@@ -27,7 +27,7 @@ spec:
mountPath: /data
containers:
- name: pihole
image: pihole/pihole:2026.02.0
image: pihole/pihole:2026.07.2
envFrom:
- configMapRef:
name: pihole-config
@@ -95,7 +95,7 @@ spec:
mountPath: /data
- name: dnscrypt-proxy
image: klutchell/dnscrypt-proxy:v2.1.15
image: klutchell/dnscrypt-proxy:v2.1.18
imagePullPolicy: IfNotPresent
env:
- name: TZ
+9 -9
View File
@@ -4,19 +4,19 @@ metadata:
name: podsync-config
namespace: podsync
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:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2QTBUbnNBcGFhYjNiNGRG
T3JqdFY0dTIzWDA3OGNVUkoreVhONXVDeFVVCkR0amlYMThyejlPaWlPSkdGL0xy
YUN3VEhGajJoQjNiRVV5ckw0cE1JaTAKLS0tIDFSWnpWWVFxQ0VVY2U4bUFtTWVk
bkg3K01kWFl4ZWZuK21KRTIxUEhDUEEKPGWzrJlyZGNOsvrVhWKw56y8iAwrqDQK
OWJYIq0gt9NWfNBao8UpiuKJXU4SX01hW4fa1OEfGSDJAjNNxGpFVA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaVFQxWG40NEVzcVBVTmp0
bXJrWlRmdW0vK0JaaytiamNrVGM0dG9lQkYwCldjSVQ3akhlbTNITUxvTEE1Z2pY
WGFjQTBoT2w0aXFreFdwcVlVWlBhRGcKLS0tIDBYRnZaK2FkL0YwRkZZb2loRmQx
VkZOR2g4bWJQTlRudVoyU01KT3FVREkKgqZ3NJtwtWgYThwdOxrerzl0KlaS5Wve
QxiwAtIrK+zXp/JL0q4UEVs5duO8VnrlS8kc1LvxR+uDt9iVpAWyeg==
-----END AGE ENCRYPTED FILE-----
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
encrypted_regex: ^(data|stringData|email)$
lastmodified: "2026-06-22T19:19:33Z"
mac: ENC[AES256_GCM,data:Rd0q5r8DA3I7rNNbv9t/5c1LD0Dm1897rGvqhi4l91g9KpSCxQFu0+z6cUH7yhLCopFSWCezQHnBYEGFEkESl04DYkAAj/+ntLSnAhfHijbZshCdHhzr+bxMInajVbDMJTs0DXm2moFMUpcpVn3EHC3UTr/kj/PDfsK9oXugIW0=,iv:ZmlXvPONTD2w+Agh5QqYr8DMMbAeM/QQuWRsFcrw728=,tag:IRoRIxkcQQQuLbG+ccTxuA==,type:str]
version: 3.13.1
lastmodified: "2026-09-16T20:20:54Z"
mac: ENC[AES256_GCM,data:DY3u/NKp/be29EqpFoWE8B+b6t2rjJ4yy+3iONYgG0o04o8FfAr4IsToncdN9p1SZNqtEyxTmogzazRxqp2eTe4TBBg+Uqnpl2yEWhj9+ESIUJs+2YoWHpnB97+VOHy9hN6jDtUWSoIH7B1E4O54u5dISiw35v5O1bEl4Oxk8fk=,iv:9tUIfbmnjJ1D7nDIYoTxtmtA9Wah5wNwnzeZQkNh2U4=,tag:FNYW90bX5zxTBEb5aRBskg==,type:str]
version: 3.13.3
@@ -1,12 +1,12 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: firefly-db-backup
namespace: firefly
name: reitti-db-backup
namespace: reitti
labels:
app: firefly-backup
app: reitti-backup
spec:
schedule: "0 2 * * *"
schedule: "30 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
@@ -15,31 +15,31 @@ spec:
template:
metadata:
labels:
app: firefly-backup
app: reitti-backup
spec:
restartPolicy: OnFailure
initContainers:
- name: pg-dump
image: postgres:17
image: postgis/postgis:17-3.5
imagePullPolicy: IfNotPresent
env:
- name: PGHOST
value: firefly-db
value: reitti-db
- name: PGUSER
valueFrom:
secretKeyRef:
name: firefly-credentials
name: reitti-credentials
key: DB_USERNAME
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: firefly-credentials
name: reitti-credentials
key: DB_PASSWORD
- name: PGDATABASE
valueFrom:
secretKeyRef:
name: firefly-credentials
key: DB_DATABASE
name: reitti-credentials
key: DB_DATABASE_NAME
command:
- sh
- -c
@@ -55,18 +55,18 @@ spec:
- sh
- -c
- |
resticprofile -c /secrets/profiles.yaml -n firefly-db backup
resticprofile -c /secrets/profiles.yaml -n firefly-db copy
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: firefly-backup-config
name: reitti-backup-config
key: B2_ACCOUNT_ID
- name: B2_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: firefly-backup-config
name: reitti-backup-config
key: B2_ACCOUNT_KEY
volumeMounts:
- name: secrets
@@ -77,19 +77,19 @@ spec:
volumes:
- name: secrets
secret:
secretName: firefly-backup-config
secretName: reitti-backup-config
- name: backup-tmp
emptyDir: {}
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: firefly-uploads-backup
namespace: firefly
name: reitti-files-backup
namespace: reitti
labels:
app: firefly-backup
app: reitti-backup
spec:
schedule: "0 3 * * *"
schedule: "30 3 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
@@ -98,7 +98,7 @@ spec:
template:
metadata:
labels:
app: firefly-backup
app: reitti-backup
spec:
restartPolicy: OnFailure
containers:
@@ -109,25 +109,25 @@ spec:
- sh
- -c
- |
resticprofile -c /secrets/profiles.yaml -n firefly-uploads backup
resticprofile -c /secrets/profiles.yaml -n firefly-uploads copy
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: firefly-backup-config
name: reitti-backup-config
key: B2_ACCOUNT_ID
- name: B2_ACCOUNT_KEY
valueFrom:
secretKeyRef:
name: firefly-backup-config
name: reitti-backup-config
key: B2_ACCOUNT_KEY
volumeMounts:
- name: secrets
mountPath: /secrets
readOnly: true
- name: uploads
mountPath: /uploads
- name: files
mountPath: /files
readOnly: true
resources:
requests:
@@ -138,7 +138,7 @@ spec:
volumes:
- name: secrets
secret:
secretName: firefly-backup-config
- name: uploads
secretName: reitti-backup-config
- name: files
persistentVolumeClaim:
claimName: firefly-firefly-iii
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
+120
View File
@@ -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
+27
View File
@@ -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
@@ -1,4 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: grocy
name: reitti
+133
View File
@@ -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
+26
View File
@@ -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
+29
View File
@@ -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
+25
View File
@@ -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
@@ -1,12 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: firefly-db
namespace: firefly
name: reitti-db
namespace: reitti
spec:
clusterIP: None
selector:
app: firefly-db
app: reitti-db
ports:
- port: 5432
targetPort: 5432
+38
View File
@@ -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
@@ -1,20 +1,20 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: firefly-db
namespace: firefly
name: reitti-db
namespace: reitti
labels:
app: firefly-db
app: reitti-db
spec:
serviceName: firefly-db
serviceName: reitti-db
replicas: 1
selector:
matchLabels:
app: firefly-db
app: reitti-db
template:
metadata:
labels:
app: firefly-db
app: reitti-db
spec:
securityContext:
runAsUser: 999
@@ -22,24 +22,26 @@ spec:
fsGroup: 999
containers:
- name: postgres
image: postgres:17
# 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: firefly-credentials
name: reitti-credentials
key: DB_USERNAME
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: firefly-credentials
name: reitti-credentials
key: DB_PASSWORD
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: firefly-credentials
key: DB_DATABASE
name: reitti-credentials
key: DB_DATABASE_NAME
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
ports:
@@ -7,6 +7,7 @@ metadata:
app: vikunja-backup
spec:
schedule: "0 2 * * *"
suspend: true
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
@@ -90,6 +91,7 @@ metadata:
app: vikunja-backup
spec:
schedule: "0 3 * * *"
suspend: true
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
+2 -2
View File
@@ -6,7 +6,7 @@ metadata:
labels:
app: vikunja
spec:
replicas: 1
replicas: 0
strategy:
type: Recreate
selector:
@@ -27,7 +27,7 @@ spec:
type: RuntimeDefault
containers:
- name: vikunja
image: vikunja/vikunja:2.6.0
image: vikunja/vikunja:2.7.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3456
+1 -1
View File
@@ -7,7 +7,7 @@ metadata:
app: vikunja-db
spec:
serviceName: vikunja-db
replicas: 1
replicas: 0
selector:
matchLabels:
app: vikunja-db
+5 -9
View File
@@ -26,18 +26,14 @@ stringData:
PAPERLESS_CONSUME_NFS_PATH: ENC[AES256_GCM,data:pUres8hqvlE8InL/hM+RCMlGVulsIGc=,iv:WWtAlN9W9z19+btNMrFJq6DuU+gJ5ff4KIMKjp1Yg5Q=,tag:6tOtmyELDEXAkFcO8P+QcA==,type:str]
PAPERLESS_DATA_NFS_PATH: ENC[AES256_GCM,data:bjTpsnmlDwLLAHi4QeEFd2jabphhBperp8Aqwccmo/jX7gI=,iv:le84tRqtPvjyt/YCPZ4DIqNTOIQ1UI7NzKg/F405suY=,tag:qKBMVRQ6/jLWJvg5QmrmfA==,type:str]
HOMEPAGE_HOST: ENC[AES256_GCM,data:lctHEKeFiwq47QYApI2/6YetrDQ=,iv:uPmTrf0ftl0T9jyOCHBGzb4cgn3qtKyPunFBZGMTkpY=,tag:O5PWGpULOjXv+xJHbIeepA==,type:str]
GROCY_HOST: ENC[AES256_GCM,data:BE5AFwuZwG0TmzD3AeOcc1cT5CXf,iv:RIvwnpiLq0ICfbtlcMNAcbvSaQlm15ic8GYjCbm2Dg0=,tag:XUfN8hz6yrLZnkmo8ZLF0Q==,type:str]
GROCY_NFS_PATH: ENC[AES256_GCM,data:qXHalcb1biQLv0mIgC/Tl14vwYFQddq6vpxJF+q0RgTk,iv:dHO7icOCGKOyVJYpMCSOwaL1UNBaaSahXCqucBYc3jI=,tag:95jW9bSUbIAFLTBo5y6jnQ==,type:str]
CRYPTPAD_HOST: ENC[AES256_GCM,data:eIBnKk95IniY86Nu0VcwOInYLIb31wTG,iv:t4Mok6eHmVJXCR3mezjKOtLNUd0pHYAPFC+Hs+1wYLs=,tag:AbriiF/vCZgo1djxYBw+lQ==,type:str]
CRYPTPAD_SANDBOX_HOST: ENC[AES256_GCM,data:60pg2HsZmMlC+uVgxyJzWqPKHWv1mebSJArH9J4G0kg=,iv:eprm7ESoYlt2oVt/Em3MGHA+hAMSdW+zfoCIZMyL4tg=,tag:5pJ4I953A++7dIFW5B7dMg==,type:str]
CRYPTPAD_DATA_NFS_PATH: ENC[AES256_GCM,data:dNOxsmge//CgcBO0GIQUdcIBfaiGI1IVxXJ8IjmQl+Wh3A==,iv:hfuLuSWuSnbiItweWBSKxpxZJFgAWgUJCZNLcLZQVgw=,tag:7o353kHezQVRqb5BtC7rYw==,type:str]
CRYPTPAD_CONFIG_NFS_PATH: ENC[AES256_GCM,data:VJ4h7ADenNgFIiNIFK7pJKMrUBYc4e9c4MdVzqGoR4TDWGYL,iv:8ZhMHiZLh2C4J/vh/8L96R6VIkKoWc7ib/bUAQ5rZE0=,tag:HgvJjjYybCgxatUbcRFY7Q==,type:str]
SEERR_HOST: ENC[AES256_GCM,data:l64ttp+rLNU8GfwIE4fhJROSMDEb,iv:1vHOw0LyGN9OMhYemhtRq9GE2fc4J2EprZU3bp/h4kk=,tag:WNV0Jh7816ra7IIOBMspBg==,type:str]
FIREFLY_HOST: ENC[AES256_GCM,data:EQdrW33PVlD/brZCqh/sTkqLdPWW/bo=,iv:zbNnjsT1J6lpCEWtvNyL4A3bjWsusCjI5goWcZ8hajk=,tag:VwA6YA056bsyYIKB+X59bw==,type:str]
GITEA_HOST: ENC[AES256_GCM,data:Ky3tXS9E9iadabpVzoK5zEbigmtn,iv:t6OdQeQ7Kxzb7qbi+KeoOkJd0XE2Dse5P1fFyiHM6tg=,tag:GpmHtVDr0IQVbpbALVx40g==,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]
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:
age:
- enc: |
@@ -50,6 +46,6 @@ sops:
-----END AGE ENCRYPTED FILE-----
recipient: age1zffnskvuezntkk703a0pyxsd5m8vx2hm33dr47wdfy8mn4fdw4sqgw0jgc
encrypted_regex: ^(data|stringData|email)$
lastmodified: "2026-09-07T11:47:37Z"
mac: ENC[AES256_GCM,data:4ocnThiPrXCqKTKKgwaincewzI99O7cl9CGnJHrwLRFm8vA2G6MA8yGvywoKjmln8mEfPTTcMMZY8Nd7wFKHz9i4m+CHvzC7kPhTVIDW2HrkFoN7RgywPcgnP+mrco4wOd/huBLdv9+v/j4Iz5lXBMZgbVVkNdWV4xZ4Zx3gtyM=,iv:bfK9KN4E5nZYm6CwaFm3sxG62nDnNiuP5xsIreRHkAc=,tag:wi9r3EcJOHX0azzNVpGw0Q==,type:str]
lastmodified: "2026-11-05T17:33:51Z"
mac: ENC[AES256_GCM,data:5t7xU5d1P5EdHvMc7lG2VGTrCKjJ7oPRDhPXAnY0pIb+OonO0aHZeJArl6GWefFMg22LMIvB7LIu9FkXpw35Ipq6KUWvgvXnGtH2DgbRSM/VQ3hMysH9xEZk6ZsviSV0fQMT0eU5UKwqNZnFk40JRz+Eao9YiMXfM12YiMUeUzQ=,iv:Xy6T62+PX14Qy3VFK6U9stKTWnBO/5VkmHgS+EFx7Fs=,tag:Rz/NMOXAs0EGIat+9fGZ2A==,type:str]
version: 3.13.3
File diff suppressed because one or more lines are too long
+3 -2
View File
@@ -11,8 +11,9 @@
"local>oleksandr/homelab//kubernetes/app/vikunja/renovate.json",
"local>oleksandr/homelab//kubernetes/app/paperless/renovate.json",
"local>oleksandr/homelab//kubernetes/app/lubelogger/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"],
"automergeType": "branch",