From 767479d1131ddbfd20b68f4a6471faf33c9315e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 15 Aug 2026 02:34:40 +0000 Subject: [PATCH] Self-heal Mattermost data/logs/config/plugins ownership on every start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root-caused a live "stream closed" image-upload failure to data/20260814/.../mkdir: permission denied — the volumes weren't owned by the fixed UID 2000 mattermost/mattermost-team-edition runs as, most likely left that way by the PikaPods data import. The install script already chown -R 2000:2000's these on every run (fresh or update), so re-running the installer would have fixed it — but that still means remembering to re-run it every time ownership drifts for any reason, including causes this repo doesn't control (a future migration, a manual restore, anything that copies files in as a different UID). Added a small mattermost-fix-perms init container (busybox, chown, exit) that the mattermost service now depends on via condition: service_completed_successfully. Runs on every `docker compose up` — including a plain host reboot, since restart: unless-stopped brings the stack back on its own — so this self-heals permanently instead of needing a human to notice and fix it by hand again. Verified the generated compose file (with representative variable values) against real `docker compose config`: valid YAML, and the dependency graph correctly shows mattermost waiting on both db (service_healthy) and mattermost-fix-perms (service_completed_successfully). --- services/mattermost.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/services/mattermost.sh b/services/mattermost.sh index e98614f..309d3e6 100644 --- a/services/mattermost.sh +++ b/services/mattermost.sh @@ -545,6 +545,28 @@ ${_CADDY_NET_BLOCK} healthcheck: timeout: 5s retries: 5 + # Fixes ownership on the bind-mounted volumes below to the fixed UID/GID + # (2000) mattermost/mattermost-team-edition runs as, before the mattermost + # service starts — every time, not just at install time. Confirmed live: + # importing data from another host (e.g. a PikaPods migration) can leave + # these owned by whatever UID did the copy instead of 2000, and the + # container doesn't fix this itself on start the way postgres's official + # image does — it just fails every file write with "permission denied" + # until someone notices and runs chown by hand. This removes the "by + # hand" part permanently: runs on every `docker compose up`, including a + # plain host reboot, so ownership drift from any future cause self-heals + # without needing this installer re-run again. + mattermost-fix-perms: + image: busybox:latest + container_name: ${MM_CONTAINER}-fix-perms + command: sh -c "chown -R 2000:2000 /data /logs /config /plugins" + volumes: + - ./data:/data + - ./logs:/logs + - ./config:/config + - ./plugins:/plugins + restart: "no" + mattermost: image: mattermost/mattermost-team-edition:latest container_name: ${MM_CONTAINER} @@ -554,6 +576,8 @@ ${_CADDY_NET_BLOCK} healthcheck: depends_on: db: condition: service_healthy + mattermost-fix-perms: + condition: service_completed_successfully volumes: - ./data:/mattermost/data - ./logs:/mattermost/logs