Fix FMD crash-loop: bind-mounted db dir needs UID 1000, not $ACTUAL_USER

fmd-server's image runs as a fixed, non-configurable UID:GID 1000:1000
baked into its own Dockerfile (useradd --uid 1000 fmd-server) - nothing
like PUID/PGID to override it. The install script chowned the bind-mounted
./data dir to $ACTUAL_USER instead, which only happens to work when that
user's host UID is coincidentally 1000. Confirmed live: the container
crash-loops forever on "permission denied" creating its sqlite db
otherwise - same root-cause shape as the Mattermost UID/GID bug fixed
earlier this session, different fixed UID.

Fixed at both points a container start can happen: the fresh-install path
(chown -R 1000:1000 "$FMD_DIR/data" right after the existing $ACTUAL_USER
chown, ordered after it since that one is recursive over the whole
directory and would otherwise overwrite this) and the update path
(previously unguarded - re-asserted before every docker compose up so a
box already stuck in this state self-heals on next update instead of
staying broken forever, same self-heal precedent as the Vaultwarden SMTP
fix earlier this session).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn
This commit is contained in:
Claude
2026-08-11 15:08:39 +00:00
parent 2a2aba0c9d
commit 88aac103c9
+21
View File
@@ -277,6 +277,17 @@ install_fmd() {
case "$MODE" in
update)
log_info "Refreshing the FindMyDevice image only — token, port, and Caddy config are left as-is."
# fmd-server's image runs as a fixed, non-configurable
# UID:GID 1000:1000 (confirmed against its own
# Dockerfile — not something PUID/PGID or similar can
# override). The bind-mounted ./data dir needs that
# exact numeric ownership regardless of what host user
# actually owns it; re-assert it on every update too,
# not just at install time, so a box whose data/ was
# ever chowned to something else (e.g. $ACTUAL_USER
# not being UID 1000) self-heals instead of staying
# stuck crash-looping on "permission denied" forever.
[ -d "$FMD_DIR/data" ] && chown -R 1000:1000 "$FMD_DIR/data"
( cd "$FMD_DIR" && docker compose pull && docker compose up -d ) \
&& log_success "FindMyDevice image refreshed" \
|| log_warning "Refresh failed — check: docker compose -f $FMD_DIR/docker-compose.yml logs"
@@ -353,6 +364,16 @@ FMD_ENV
mkdir -p data
chown -R "$ACTUAL_USER:$ACTUAL_USER" "$FMD_DIR"
# fmd-server's image runs as a fixed, non-configurable UID:GID 1000:1000
# (confirmed against its own Dockerfile: `useradd --uid 1000 fmd-server`,
# baked in, not something an env var can override) — the bind mount at
# ./data:/var/lib/fmd-server/db needs that exact numeric ownership on the
# host side regardless of $ACTUAL_USER's actual UID, or the container
# crash-loops on "permission denied" trying to create its sqlite db.
# Confirmed live. Must run AFTER the chown above, not before, since that
# one is recursive over the whole directory and would otherwise
# overwrite this.
chown -R 1000:1000 "$FMD_DIR/data"
log_success "FindMyDevice${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)} configured at $FMD_DIR (port $WEB_PORT)"
configure_caddy_for_service "FindMyDevice${INSTANCE_SUFFIX:+ ($INSTANCE_SUFFIX)}" "${CONTAINER}:8080" "fmd${INSTANCE_SUFFIX:+-$INSTANCE_SUFFIX}"