From 78692c5999bad9599d61b48b517c345539f5d0b2 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 20:56:41 +0000 Subject: [PATCH 1/3] traccar: exclude Asterisk's AMI port (5038/tcp) from the published range MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed live: on a box also running Asterisk from this repo, `docker network connect caddy_net traccar` failed with "failed to bind host port 0.0.0.0:5038/tcp: address already in use". Asterisk runs with network_mode: host (services/asterisk.sh), so its AMI (port 5038, hardcoded in services/sms-inbound.sh) binds directly on the host's network stack — no Docker NAT involved. Traccar's docker-compose.yml published the entire 5000-5150 range for device protocols, which needs Docker to also bind host port 5038 for its own port-forwarding, directly colliding with Asterisk's AMI on any box running both services from this repo. Split the TCP range into 5000-5037 and 5039-5150 to skip that one port; left UDP as a single 5000-5150 range since AMI is TCP-only. --- services/traccar.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/services/traccar.sh b/services/traccar.sh index 4e3ddb7..6878a78 100644 --- a/services/traccar.sh +++ b/services/traccar.sh @@ -196,7 +196,7 @@ install_traccar() { echo " - Deploy a PostgreSQL database container (Traccar no longer ships H2)" echo " - Point Traccar at it via env vars (CONFIG_USE_ENVIRONMENT_VARIABLES) — no secrets in a config file" echo " - Deploy an autoheal container that restarts Traccar if its healthcheck fails" - echo " - Expose port 8082 (web) and 5000-5150 (device protocols)" + echo " - Expose port 8082 (web) and 5000-5150 (device protocols; 5038/tcp skipped — Asterisk AMI)" echo " - No default login — register the first account at the web UI, it becomes admin" echo " - Offer a Caddy reverse proxy and to start the container" return 0 @@ -287,7 +287,16 @@ ${_CADDY_NET_BLOCK} healthcheck: - ./data:/opt/traccar/data:rw ports: - "8082:8082" - - "5000-5150:5000-5150" + # 5038/tcp is skipped: it's Asterisk's AMI port (services/asterisk.sh + # runs Asterisk with network_mode: host, so AMI binds it directly on + # the host, not through Docker networking). Publishing the full + # 5000-5150 range here would fight Asterisk for that exact host port + # on any box running both services from this repo. Confirmed live: + # this is what made "docker network connect caddy_net traccar" fail + # with "failed to bind host port 0.0.0.0:5038/tcp: address already in + # use" on a box with Asterisk's PSTN trunk already installed. + - "5000-5037:5000-5037" + - "5039-5150:5039-5150" - "5000-5150:5000-5150/udp" ${_CADDY_NET_BLOCK} autoheal: @@ -336,7 +345,8 @@ Android/iOS app, OwnTracks, or any of 200+ supported device protocols. stays open to anyone who reaches this server until you turn it off, so do this right away, then go to Settings → Server → Permissions and uncheck Registration. -- Device protocols: ports 5000-5150 (TCP + UDP) +- Device protocols: ports 5000-5150 (TCP + UDP; 5038/tcp is skipped — reserved + for Asterisk's AMI if this box also runs Asterisk from this repo) - App data: \`data/\` and \`logs/\` - Database: PostgreSQL (\`traccar-db\` container, data in \`db/\`) - All database settings (name, user, password) live in \`.env\` — Traccar From 2ced57db55c61aca169ffedd647ec9072c689bcf Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 21:01:22 +0000 Subject: [PATCH 2/3] traccar: also exclude Asterisk's SIP ports (5060 tcp+udp, 5061 tcp) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix only excluded 5038 (AMI). Confirmed live: after attaching caddy_net, `docker compose up -d` still failed — "failed to bind host port 0.0.0.0:5060/tcp: address already in use" — because Asterisk (network_mode: host) also owns 5060 (SIP, tcp+udp) and 5061 (SIP TLS, tcp), both inside Traccar's 5000-5150 range. Asterisk gets priority on all three ports; Traccar's range just skips them. Audited every other network_mode: host service in the repo (caddy, homeassistant, kyber-server, lyrion, mattermost, watchyourlan, wolf-pair, wolf) — none of them land in 5000-5150, so Asterisk is the only conflict to account for. --- services/traccar.sh | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/services/traccar.sh b/services/traccar.sh index 6878a78..e0e5c51 100644 --- a/services/traccar.sh +++ b/services/traccar.sh @@ -196,7 +196,7 @@ install_traccar() { echo " - Deploy a PostgreSQL database container (Traccar no longer ships H2)" echo " - Point Traccar at it via env vars (CONFIG_USE_ENVIRONMENT_VARIABLES) — no secrets in a config file" echo " - Deploy an autoheal container that restarts Traccar if its healthcheck fails" - echo " - Expose port 8082 (web) and 5000-5150 (device protocols; 5038/tcp skipped — Asterisk AMI)" + echo " - Expose port 8082 (web) and 5000-5150 (device protocols; 5038/5060/5061 skipped — Asterisk keeps priority on those)" echo " - No default login — register the first account at the web UI, it becomes admin" echo " - Offer a Caddy reverse proxy and to start the container" return 0 @@ -287,17 +287,24 @@ ${_CADDY_NET_BLOCK} healthcheck: - ./data:/opt/traccar/data:rw ports: - "8082:8082" - # 5038/tcp is skipped: it's Asterisk's AMI port (services/asterisk.sh - # runs Asterisk with network_mode: host, so AMI binds it directly on - # the host, not through Docker networking). Publishing the full - # 5000-5150 range here would fight Asterisk for that exact host port - # on any box running both services from this repo. Confirmed live: - # this is what made "docker network connect caddy_net traccar" fail - # with "failed to bind host port 0.0.0.0:5038/tcp: address already in - # use" on a box with Asterisk's PSTN trunk already installed. + # 5038 (AMI), 5060 (SIP, tcp+udp), and 5061 (SIP TLS, tcp) are skipped: + # they're Asterisk's ports (services/asterisk.sh runs Asterisk with + # network_mode: host, so it binds them directly on the host, not + # through Docker networking). Publishing the full 5000-5150 range here + # would fight Asterisk for those exact host ports on any box running + # both services from this repo. Confirmed live: this is what made + # "docker network connect caddy_net traccar" and then a plain + # `docker compose up -d` both fail with "failed to bind host port + # 0.0.0.0:5038/tcp" and then "...5060/tcp: address already in use" on + # a box with Asterisk's PSTN trunk already installed. Checked every + # other network_mode: host service in this repo (caddy, homeassistant, + # kyber-server, lyrion, mattermost, watchyourlan, wolf-pair, wolf) — + # none of them land in 5000-5150, so Asterisk is the only conflict. - "5000-5037:5000-5037" - - "5039-5150:5039-5150" - - "5000-5150:5000-5150/udp" + - "5039-5059:5039-5059" + - "5062-5150:5062-5150" + - "5000-5059:5000-5059/udp" + - "5061-5150:5061-5150/udp" ${_CADDY_NET_BLOCK} autoheal: image: willfarrell/autoheal:latest @@ -345,8 +352,9 @@ Android/iOS app, OwnTracks, or any of 200+ supported device protocols. stays open to anyone who reaches this server until you turn it off, so do this right away, then go to Settings → Server → Permissions and uncheck Registration. -- Device protocols: ports 5000-5150 (TCP + UDP; 5038/tcp is skipped — reserved - for Asterisk's AMI if this box also runs Asterisk from this repo) +- Device protocols: ports 5000-5150 (TCP + UDP; 5038/tcp, 5060/tcp+udp, and + 5061/tcp are skipped — reserved for Asterisk's AMI and SIP if this box also + runs Asterisk from this repo, which gets priority on those ports) - App data: \`data/\` and \`logs/\` - Database: PostgreSQL (\`traccar-db\` container, data in \`db/\`) - All database settings (name, user, password) live in \`.env\` — Traccar From e1129b7f276ea95d735f9ae0525b82b0412f828e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 21:34:15 +0000 Subject: [PATCH 3/3] 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"