diff --git a/HOMELAB_ARCHITECTURE_MASTER_V2.md b/HOMELAB_ARCHITECTURE_MASTER_V2.md index ae3ddf5..141c3e8 100644 --- a/HOMELAB_ARCHITECTURE_MASTER_V2.md +++ b/HOMELAB_ARCHITECTURE_MASTER_V2.md @@ -532,6 +532,11 @@ Host-Pfade in `env_file` (z.B. `/mnt/...`) sind in Git-Stacks nicht verfügbar. ### Reproduzierbare Deployments (2026-04-17) Mutable Tags wie `latest`, `stable`, `release` oder reine Major-Tags wurden auf die **aktuell laufenden Digests** eingefroren. Das ist bewusst **kein Upgrade-Mechanismus**, sondern dient dazu, den heute funktionierenden Laufzeitstand exakt im Repo festzuhalten. Echte Versions-Upgrades bleiben ein eigener, geplanter Schritt. +### Stateful Digest-Pinning (2026-05-05) +- Tier-1/stateful Basisdienste werden bevorzugt mit sprechendem Minor-/Patch-Tag plus Digest gepinnt, z. B. `postgres:17.9@sha256:...` oder `mongo:7.0.32@sha256:...`. +- Redis-Caches bleiben bewusst ohne Digest-Pin. Cache-Verlust ist akzeptabel, und Sicherheits-Patches sollen dort ohne eigenen Datenbank-Upgrade-Sprint fliessen koennen. +- Bereits versionierte Apps koennen optional spaeter ebenfalls Digests erhalten; dieser Schritt ist getrennt vom Datenhalter-Pinning. + ### Nextcloud und Stirling-PDF (2026-04-19) - `nextcloud` wird bewusst **nicht** als AIO-Stack gebaut, sondern als klassischer Docker-Microservice-Stack mit eigenem PostgreSQL und eigenem Redis. Das passt besser zum bestehenden GitOps-/Compose-Modell des Repos. - `nextcloud` bleibt bei nativer App-Authentifizierung ohne zentrale ForwardAuth-Middleware vor dem Router, damit Browser-Login, Desktop-/Mobile-Clients sowie WebDAV/CardDAV sauber funktionieren. diff --git a/apps/immich/docker-compose.yml b/apps/immich/docker-compose.yml index cc0c745..a002e09 100644 --- a/apps/immich/docker-compose.yml +++ b/apps/immich/docker-compose.yml @@ -54,7 +54,7 @@ services: database: container_name: immich_postgres - image: tensorchord/pgvecto-rs:pg14-v0.2.0 + image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52 restart: unless-stopped environment: POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password diff --git a/apps/mealie/docker-compose.yml b/apps/mealie/docker-compose.yml index f3ba7b1..408caf0 100644 --- a/apps/mealie/docker-compose.yml +++ b/apps/mealie/docker-compose.yml @@ -39,7 +39,7 @@ services: - traefik.http.services.mealie.loadbalancer.server.port=9000 mealie-postgres: - image: postgres:17 + image: postgres:17.9@sha256:5b96f1a16bd9768b060dd2ffe55cb6225c4d9ef4d214a8b21eb08134869a97e4 container_name: mealie-postgres restart: unless-stopped @@ -66,4 +66,4 @@ networks: mealie_internal: driver: bridge - internal: true \ No newline at end of file + internal: true diff --git a/apps/nextcloud/docker-compose.yml b/apps/nextcloud/docker-compose.yml index 8c73c59..44960d9 100644 --- a/apps/nextcloud/docker-compose.yml +++ b/apps/nextcloud/docker-compose.yml @@ -46,7 +46,7 @@ services: - "traefik.http.services.nextcloud.loadbalancer.server.port=80" nextcloud-postgres: - image: postgres:17 + image: postgres:17.9@sha256:5b96f1a16bd9768b060dd2ffe55cb6225c4d9ef4d214a8b21eb08134869a97e4 container_name: nextcloud-postgres restart: unless-stopped environment: diff --git a/core/gitea/docker-compose.yml b/core/gitea/docker-compose.yml index 23d3916..eb08d0c 100644 --- a/core/gitea/docker-compose.yml +++ b/core/gitea/docker-compose.yml @@ -1,6 +1,6 @@ services: gitea: - image: docker.gitea.com/gitea:1.25.4 + image: docker.gitea.com/gitea:1.25.4@sha256:17d18218be2dad1f8ed402a4f906989505c90ab8b66ee9befcecfb5d470133e7 container_name: gitea restart: unless-stopped security_opt: diff --git a/docs/AI_CONTEXT.md b/docs/AI_CONTEXT.md index 6458c5f..b3c4029 100644 --- a/docs/AI_CONTEXT.md +++ b/docs/AI_CONTEXT.md @@ -160,6 +160,7 @@ KI-Agenten sollen konservativ arbeiten: keine indirekten Live-Aenderungen, keine - `Plex-Media-Server` ist im Architekturziel als Host-Sonderfall dokumentiert, aber nicht als Repo-Compose-Stack enthalten. - Echte `stack.env`- und `.env`-Dateien gehoeren nicht ins Repo; fuer Hermes liegt nur `ops/hermes-agent/stack.env.example` im Git. - Einige Images nutzen mutable Tag plus Digest. Das friert den aktuellen Digest ein, ist aber kein automatisches Upgrade-Modell. +- Stateful Images werden bevorzugt als Minor-/Patch-Tag plus Digest gepinnt; Redis-Caches bleiben bewusst ungedigestet. ## Arbeitsregel bei Unsicherheit diff --git a/docs/MIGRATION_LOG.md b/docs/MIGRATION_LOG.md index bcdf1ed..82e8206 100644 --- a/docs/MIGRATION_LOG.md +++ b/docs/MIGRATION_LOG.md @@ -16,6 +16,13 @@ Dieses Dokument ist nur noch ein historischer Verlauf. Der aktuelle operative Ab ## Historische Meilensteine +### 2026-05-05 - M3a stateful Digest-Pinning + +- PostgreSQL 17 Datenhalter auf `postgres:17.9@sha256:5b96f1a16bd9768b060dd2ffe55cb6225c4d9ef4d214a8b21eb08134869a97e4` gepinnt (`postgresql17`, `mealie-postgres`, `nextcloud-postgres`). +- Immich pgvector-Postgres auf `tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52` gepinnt. +- Komodo Mongo auf `mongo:7.0.32@sha256:32979a1189dfdc44da3f5ed40d910495f5ad8f6f7f77556646f890a30b2d3f56` sowie Komodo Core/Periphery und Gitea auf die am Host laufenden Digests gepinnt. +- Redis-Caches bleiben bewusst ohne Digest-Pin; Redeploys erfolgen stackweise mit Smoke-Test, nicht parallel. + ### 2026-05-04 - Komodo Self-Stack Drift auf persistenten Pfad zurueckgefuehrt - Drift-Befund: `komodo-core` und `komodo-periphery` liefen aus `/tmp/komodo-core-repair.yml` bzw. `/tmp/komodo-periphery-repair.yml`; `komodo-mongo` verwies auf `/mnt/user/services/stacks/komodo/compose.yaml`, obwohl dieser Pfad fehlte. diff --git a/docs/REPO_MAP.md b/docs/REPO_MAP.md index bb9024b..def89a0 100644 --- a/docs/REPO_MAP.md +++ b/docs/REPO_MAP.md @@ -73,11 +73,11 @@ Secret-Werte werden hier nicht dokumentiert. Aufgefuehrt werden nur Variablennam | Stack | Compose | Services / Images | Traefik Hosts | Networks | Ports | Abhaengigkeiten | |---|---|---|---|---|---|---| -| Gitea | `core/gitea/docker-compose.yml` | `gitea` -> `docker.gitea.com/gitea:1.25.4` | `git.kaleschke.info` | `frontend_net` | `222:22/tcp` | SQLite in `/data`; SSH-Port ist dokumentierte Ausnahme | +| Gitea | `core/gitea/docker-compose.yml` | `gitea` -> `docker.gitea.com/gitea:1.25.4@sha256:...` | `git.kaleschke.info` | `frontend_net` | `222:22/tcp` | SQLite in `/data`; SSH-Port ist dokumentierte Ausnahme | | Authelia | `security/authelia/docker-compose.yml` | `authelia` -> `authelia/authelia:latest@sha256:...` | `auth.kaleschke.info` | `frontend_net`, `backend_net` | keine | PostgreSQL 17 Storage, Traefik ForwardAuth; bewusst ohne Redis-Session-Backend | | Vaultwarden | `security/vaultwarden/docker-compose.yml` | `vaultwarden` -> `vaultwarden/server:latest@sha256:...` | `vault.kaleschke.info` | `frontend_net` | keine | Datei-Persistenz, `ADMIN_TOKEN_FILE` | | ddns-updater | `infra/ddns-updater/docker-compose.yml` | `ddns-updater` -> `ghcr.io/qdm12/ddns-updater:latest@sha256:...` | keine | `frontend_net` | keine | Cloudflare/API-Internetbedarf | -| PostgreSQL 17 | `infra/postgresql17/docker-compose.yml` | `postgresql17` -> `postgres:17` | keine | `backend_net` | keine | shared DB-Cluster | +| PostgreSQL 17 | `infra/postgresql17/docker-compose.yml` | `postgresql17` -> `postgres:17.9@sha256:...` | keine | `backend_net` | keine | shared DB-Cluster | | Redis | `infra/redis/docker-compose.yml` | `Redis` -> `redis:7-alpine` | keine | `backend_net` | keine | shared Cache, Passwort-Datei | ### Host Services @@ -220,6 +220,7 @@ Das Skript liest Secret-Dateien auf dem Host und schreibt Dump-Artefakte. Bei An - `apps/mealie` nutzt in Compose `mealie_internal`; Architektur-Doku nennt teils `mealie_mealie_internal`. Laufzeitnamen koennen durch Compose-Projektpraefixe abweichen. - `backend_net` ist in der Architektur als `internal: true` beschrieben; einzelne Compose-Dateien referenzieren es external. Live-Netz-Attribute bei Drift-Fragen pruefen. - Einige Images bleiben trotz Digest-Pin semantisch auf mutable Tags (`latest@sha256`, `release@sha256`). Das ist bewusst dokumentiert, aber bei Updates gesondert pruefen. +- Stateful Datenhalter sind seit 2026-05-05 bevorzugt mit Minor-/Patch-Tag plus Digest gepinnt; Redis-Caches bleiben bewusst ohne Digest-Pin. - `scrutiny` bleibt `privileged: true`; dokumentierte Ausnahme, aber weiterhin pruefenswert. - `Plex-Media-Server` ist als historischer Host-Sonderfall dokumentiert, aber nicht als Repo-Compose-Stack enthalten. - BentoPDF und Hermes Agent koennen je nach Live-Stand vorbereitet statt produktiv sein; vor Deploy-/Rollback-Fragen in Komodo/Runtime pruefen. diff --git a/infra/postgresql17/docker-compose.yml b/infra/postgresql17/docker-compose.yml index 00a4afb..053572b 100644 --- a/infra/postgresql17/docker-compose.yml +++ b/infra/postgresql17/docker-compose.yml @@ -1,6 +1,6 @@ services: postgresql17: - image: postgres:17 + image: postgres:17.9@sha256:5b96f1a16bd9768b060dd2ffe55cb6225c4d9ef4d214a8b21eb08134869a97e4 container_name: postgresql17 restart: unless-stopped @@ -23,4 +23,4 @@ services: networks: backend_net: - external: true \ No newline at end of file + external: true diff --git a/ops/komodo/docker-compose.yml b/ops/komodo/docker-compose.yml index 906d6f4..ff33328 100644 --- a/ops/komodo/docker-compose.yml +++ b/ops/komodo/docker-compose.yml @@ -4,7 +4,7 @@ services: # Netz: komodo_net (internal: true) – niemals frontend_net # ────────────────────────────────────────────────────────────────── komodo-mongo: - image: mongo:7 + image: mongo:7.0.32@sha256:32979a1189dfdc44da3f5ed40d910495f5ad8f6f7f77556646f890a30b2d3f56 container_name: komodo-mongo labels: komodo.skip: @@ -33,7 +33,7 @@ services: # Admin-Dienst: bewusst ohne pauschale ForwardAuth-Middleware; dokumentierte Ausnahme # ────────────────────────────────────────────────────────────────── komodo-core: - image: ghcr.io/moghtech/komodo-core:2 + image: ghcr.io/moghtech/komodo-core:2@sha256:8a7dbba232e4e49797bb412be5f78207c89fcf22cc2727b38631ae30f7518a4c container_name: komodo-core init: true restart: unless-stopped @@ -79,7 +79,7 @@ services: # Ausnahme: Docker-Socket ohne :ro (Periphery startet/stoppt Container) # ────────────────────────────────────────────────────────────────── komodo-periphery: - image: ghcr.io/moghtech/komodo-periphery:2 + image: ghcr.io/moghtech/komodo-periphery:2@sha256:8ac9f2ef9c1461b95c862d445da00253005e7094d1e30f5b7b04b8d60ca7a3d6 container_name: komodo-periphery init: true restart: unless-stopped