traccar: never recursively chown the Postgres data directory

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).
This commit is contained in:
Claude
2026-08-03 21:34:15 +00:00
parent 2ced57db55
commit e1129b7f27
+12 -2
View File
@@ -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"