From e1129b7f276ea95d735f9ae0525b82b0412f828e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 21:34:15 +0000 Subject: [PATCH] traccar: never recursively chown the Postgres data directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed live: after re-running the installer to pick up the caddy_net/port fixes, Traccar crash-looped with "FATAL: could not open file \"global/pg_filenode.map\": Permission denied" — a Postgres-side error, not a Traccar or Caddy problem. install_traccar() had two `chown -R $ACTUAL_USER "$TRACCAR_DIR"` calls (one via ensure_docker_dir_ownership at the top, one explicit near the end) inherited from the original H2-only script, where that was safe — everything under the directory (logs/, data/, config/) was meant to be host-user-owned. Once db/ started holding Postgres's own data files (owned internally by whatever uid the postgres container runs as, not $ACTUAL_USER), both of those recursive chowns reassign db/'s contents to $ACTUAL_USER on every rerun, and Postgres can no longer read its own files afterward. Replaced both with non-recursive/scoped chowns that never touch db/: the top-level directory itself, docker-compose.yml, and .env directly, plus a separate `chown -R` limited to logs/ and data/ (which are Traccar's own app-writable directories and always safe to reassign). --- services/traccar.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/services/traccar.sh b/services/traccar.sh index e0e5c51..9dfb341 100644 --- a/services/traccar.sh +++ b/services/traccar.sh @@ -203,7 +203,15 @@ install_traccar() { fi mkdir -p "$TRACCAR_DIR" - ensure_docker_dir_ownership "$TRACCAR_DIR" + # Non-recursive on purpose — a rerun already has a `db/` full of Postgres's + # own data files, owned by whatever uid the postgres container runs as + # internally, not $ACTUAL_USER. ensure_docker_dir_ownership's chown -R + # would reassign all of those to $ACTUAL_USER, and Postgres can't read + # its own files anymore afterward ("could not open file + # global/pg_filenode.map: Permission denied") — confirmed live on a + # rerun. logs/ and data/ get their own chown -R further down instead; + # db/ is never touched by this script again once created. + chown "$ACTUAL_USER:$ACTUAL_USER" "$TRACCAR_DIR" 2>/dev/null || true cd "$TRACCAR_DIR" || return 1 # Reuse an existing DB password across reruns instead of generating a new @@ -335,7 +343,9 @@ TRACCAR_ENV mkdir -p logs data db - chown -R "$ACTUAL_USER:$ACTUAL_USER" "$TRACCAR_DIR" + # db/ is deliberately excluded — see the comment on the earlier chown. + chown "$ACTUAL_USER:$ACTUAL_USER" "$TRACCAR_DIR" docker-compose.yml .env + chown -R "$ACTUAL_USER:$ACTUAL_USER" logs data log_success "Traccar configured at $TRACCAR_DIR" configure_caddy_for_service "Traccar" "traccar:8082" "traccar"