From 39e7b2ae6e3b756afddaad9eea029e3f4ad81fc0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 23:41:41 +0000 Subject: [PATCH] Fix Mattermost crash-looping with permission denied on config.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The official mattermost/mattermost-team-edition image runs as a fixed UID/GID 2000 baked into the image — it does not read PUID/PGID env vars, that's a LinuxServer.io s6-overlay convention this image doesn't use. This file set them anyway (computed from ACTUAL_USER's uid/gid), which did nothing, while the actual host directories (./data, ./logs, ./config, ./plugins) got chowned to ACTUAL_USER instead of 2000:2000. Confirmed live: the container fails on its very first start with "could not create config file: open /mattermost/config/config.json: permission denied" and crash-loops — which then presents as a 502 from Caddy, an easy trail to follow to the wrong place since Caddy itself was fine. Removed the dead PUID/PGID mechanism and chown the app's own volumes to 2000:2000 after the existing ACTUAL_USER chown. db (postgres:15-alpine) isn't affected — its entrypoint fixes its own volume ownership on startup. Runs on both fresh installs and "update" reruns, so re-running the installer on an already-broken instance self-heals it. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn --- services/mattermost.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/services/mattermost.sh b/services/mattermost.sh index 83bdfaf..a2347a2 100644 --- a/services/mattermost.sh +++ b/services/mattermost.sh @@ -335,9 +335,6 @@ install_mattermost() { [ -n "$DB_PASS" ] || DB_PASS=$(generate_password 32) local TZ_VAL="${SITE_TZ:-$(cat /etc/timezone 2>/dev/null || echo UTC)}" - local UID_VAL GID_VAL - UID_VAL=$(id -u "$ACTUAL_USER") - GID_VAL=$(id -g "$ACTUAL_USER") # Compute SITE_URL — extra instances default to a distinct subdomain so # they don't collide with the first instance's. @@ -489,15 +486,22 @@ TURN_HOST=$TURN_HOST_VAL TURN_PORT=$TURN_PORT_VAL TURN_USERNAME=$TURN_USERNAME_VAL TURN_PASSWORD=$TURN_PASSWORD_VAL - -# PUID/PGID for file ownership -PUID=$UID_VAL -PGID=$GID_VAL EOF chmod 600 .env mkdir -p data logs config plugins db chown -R "$ACTUAL_USER:$ACTUAL_USER" "$DIR" + # mattermost/mattermost-team-edition's image runs as a fixed UID/GID + # 2000 baked in at build time — unlike some other images in this repo, + # it does NOT read PUID/PGID env vars (that's a LinuxServer.io s6-overlay + # convention this image doesn't use; a previous version of this file set + # them anyway, which did nothing). Confirmed live: leaving ./data, + # ./logs, ./config, ./plugins owned by ACTUAL_USER instead of 2000:2000 + # makes the container fail on its very first start with "could not + # create config file: open /mattermost/config/config.json: permission + # denied" and crash-loop — db (postgres:15-alpine) isn't affected, its + # entrypoint fixes ownership itself on startup when it needs to. + chown -R 2000:2000 data logs config plugins # ── Firewall ───────────────────────────────────────────────────────────── if command -v ufw &>/dev/null; then