SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-09-11

自架位置追蹤工具比較:Traccar、OwnTracks、Dawarich

比較 Traccar、OwnTracks、Dawarich 與 Home Assistant:依歷史軌跡、即時位置或自動化需求選擇,並避免將 ingest endpoint 暴露在公開網際網路。

符合您情境的自架位置追蹤應用程式

自架位置追蹤取決於一個問題:您是要為自己保留歷史記錄,還是要與其他人一起查看即時位置?Dawarich 適合前者。它是 Google Maps Timeline 的自架替代方案,也能匯入您現有的位置歷史記錄。Traccar 適合後者。它是為 GPS 硬體與車隊打造的,也能將手機視為另一個追蹤器。OwnTracks 則可作為兩者底層使用的手機應用程式與訊息格式。如果您已經執行 Home Assistant,它也能知道手機的位置,但預設會在 10 天後刪除位置軌跡。

請依照您下個月想查看的內容選擇:

  • 去年 3 月到過的所有地點與行程地圖:Dawarich。
  • 多台裝置的即時地圖、地理圍籬與事件規則:Traccar。
  • 讓一支手機將位置傳送到您已在使用的系統:使用 HTTP mode 的 OwnTracks。
  • 居家與離家自動化,且不需要歷史記錄:單獨使用 Home Assistant。

在手機能連線到您控制的 HTTPS endpoint 之前,這些方案都無法運作,因此下方會另設一節介紹伺服器端。如果您仍在規劃這台主機還適合執行哪些服務,今年值得自架的其他服務完整清單可協助您了解追蹤器在整體架構中的位置。

Traccar:GPS 硬體、車隊與即時位置

Traccar 是追蹤伺服器。它支援專用 GPS 追蹤器使用的通訊協定,每個協定都在 5000 至 5150 範圍內使用自己的 TCP 與 UDP 埠,並在此基礎上提供即時地圖、地理圍籬、事件規則與報表。Web 介面預設監聽 8082 埠。

手機可使用 Android 與 iOS 版 Traccar Client 應用程式。它透過 OsmAnd 通訊協定回報位置,預設監聽 5055 埠。相關設定會影響電池續航力與資料列數。Distance 會在移動時每隔 N 公尺要求更新一次。Interval 會在距離為 0 時,改以時間間隔回報。Angle 會在行進方向變更時觸發更新,單位為度。Stationary Heartbeat 定義裝置停止移動時的處理方式。Traccar 官方文件表示,這些設定都無法保證確切結果,因為實際行為由手機決定。

Traccar 隨附內嵌的 H2 資料庫,因此安裝程式不需要額外設定;但專案不建議在 production 環境使用 H2。對於較小型的伺服器,官方建議使用 MySQL 或 MariaDB;對於大型伺服器,則建議使用 PostgreSQL,並可選擇搭配 TimescaleDB。請在累積歷史資料前先遷移資料庫,因為日後轉換 H2 檔案必須手動處理,且沒有受支援的工具可用。

Traccar 不適合的用途:它是用來即時監看物件的主控台。報表內容是車隊報表、行程、停靠與摘要,因此若要查看自己一整年的週末活動,得到的會比較像查詢結果,而不是時間軸。

OwnTracks:手機應用程式與端點,僅此而已

OwnTracks 是最精簡的經典配置。應用程式會在判定裝置已移動時發布一小段 JSON payload,也能透過 MQTT(message queuing telemetry transport)或純 HTTP 發布。在 HTTP 模式中,端點是格式為 http[s]://[user[:password]@]host[:port]/path 的 URL,並使用 HTTP Basic 進行驗證;專案強烈建議採用 https:// 機制。使用 OwnTracks Recorder 時,路徑為 /pub

監測模式比任何伺服器設定都重要。Quiet 只有在你要求時才發布。Manual 會加入區域監測與低耗電的位置請求。Significant 是一般的自動模式。Move 會在裝置移動 locatorDisplacement 公尺,或經過 locatorInterval 秒時立即發布,以先發生者為準;預設值分別為 100 公尺與 300 秒。OwnTracks 文件指出,Move 模式的耗電量與導航應用程式相當,並建議在旅途中或充電時使用,而不要作為日常設定。

OwnTracks Recorder 會儲存收到的資料並提供簡易地圖。許多人不會安裝它,因為無論應用程式指向 Recorder、Dawarich 或 Home Assistant,payload 都完全相同。這正是從這裡開始的原因:應用程式是穩定且單純的資料產生端,之後仍可改用其他資料消費端。

Dawarich:自架的 Google Maps Timeline

Dawarich 採用 AGPL-3.0 授權,並透過 Docker Compose 檔案執行。可正常運作的安裝包含 4 個容器:Rails 應用程式、處理背景工作的 Sidekiq worker、PostgreSQL,以及 Redis。應用程式提供 3000 埠。可匯入的來源包括 Google Maps Timeline、OwnTracks、Strava、Immich、GPX 與 GeoJSON 檔案,以及相片中的 EXIF 資料。這份匯入清單使它成為時間軸,而不是即時地圖,因為它可以納入伺服器建立前的歷史資料。

資料匯入使用攜帶 API key 的 HTTP endpoint;API key 可在帳戶頁面取得。OwnTracks 會將資料 POST 至 /api/v1/owntracks/points?api_key=...,Overland 則會 POST 至 /api/v1/overland/batches?api_key=...。GPSLogger 會重複使用 OwnTracks endpoint。

請注意該 key 的傳遞位置。它位於 query string 中,而 nginx 的預設 log 格式會寫入完整的請求列,因此每一個位置資料都會讓該 key 以明文寫入 /var/log/nginx/access.log。請將該 log 視為 secret。若要將 log 傳送到任何集中式系統,請先輪換該 key。絕對不要將仍可使用的 URL 貼到支援討論串中。

至於 compose 檔案本身、volumes 與 restart policy,請參閱在 VPS 上執行 compose 的容器機制。本頁只說明判斷方向。

Home Assistant:適合掌握是否有人在家,但不適合保存歷史記錄

如果你已經在執行 Home Assistant,就已經具備裝置追蹤功能。行動應用程式會回報位置,而 OwnTracks 整合會提供 webhook URL 和加密金鑰,供你貼到應用程式中。完成 MQTT 設定後,該整合會改為接收 MQTT 訊息,而不是 HTTP。

限制在於資料保留期限。Home Assistant 的 recorder 預設為 purge_keep_days: 10,而自動清理每天當地時間 04:12 執行,以避免資料庫無限制成長。這項預設值適合家庭自動化資料庫,但不適合位置封存。Home Assistant 可以回答「現在是否有人在家」。除非你將相同的資料流傳送到能夠長期保存的位置,否則它無法回答「我在 3 月 14 日的位置在哪裡」。

持續追蹤或偶爾分享?

持續追蹤表示應用程式全天發布位置資訊,不論你是否正在移動,而它建立的歷史記錄就是主要用途。偶爾分享則表示人們在旅途中互相查看位置,歷史記錄只是無人要求的副作用。同一套軟體可以支援這兩種用途,只需採用不同設定。

若要持續追蹤,優先使用以位移為基準的回報方式,而不是短時間計時器。將資料庫放在確實會備份的儲存空間上。並在第一天決定資料保留期限,不要等到磁碟空間用盡才處理。若只是偶爾分享,僅在需要期間提高回報頻率,之後將手機恢復為低耗電模式。OwnTracks 可在應用程式中直接調整這項設定,Traccar Client 則透過距離與間隔欄位提供相同功能。

如果你要的是單次旅程使用 2 小時的分享連結,確定方案前先查看所選伺服器的 release notes。這項功能在不同版本之間的變化最大,也是這裡所有選項中最薄弱的部分。

是否需要 MQTT broker?

先不要使用。HTTP 模式只需要 URL、密碼和 TLS(傳輸層安全性),上述每個伺服器都接受這種模式。當多個元件需要在同一時間使用相同串流時,broker 才有存在的必要。例如 Home Assistant 在某個區域有反應時,錄影器同時寫入歷史紀錄,或讓家人彼此查看。

MQTT 是發布與訂閱通訊協定,Mosquitto 是常用的 broker。它在 1883 以明文監聽,並在 8883 提供 TLS;實際上只應使用 8883。存取控制以主題為單位,因此可以允許某個帳戶發布到 owntracks/alice/phone,但不允許讀取其他內容。這就是家庭環境採用 MQTT 的主要理由:broker 在應用程式下層強制執行誰能查看誰,因此應用程式發生錯誤時,也不會擴大可見範圍。

代價是多一個服務,並且需要管理自己的憑證、使用者清單及故障模式。broker 停止接受連線時,情況就像手機沒有訊號一樣,而且兩者都不會告訴你原因。

一支手機會產生多少筆位置資料?

以下數字是算術結果,不是實測值。計算假設回報間隔固定、每次回報寫入一列,且沒有其他資料。

ChartPosition rows per phone at a fixed reporting interval (arithmetic)
The data behind this chart
[
  {
    "label": "Every 30 seconds",
    "points_30d": "86,400",
    "points_365d": "1,051,200"
  },
  {
    "label": "Every 60 seconds",
    "points_30d": "43,200",
    "points_365d": "525,600"
  },
  {
    "label": "Every 5 minutes",
    "points_30d": "8,640",
    "points_365d": "105,120"
  },
  {
    "label": "Every 15 minutes",
    "points_30d": "2,880",
    "points_365d": "35,040"
  }
]

手機每分鐘回報一次時,每月會寫入 43,200 列,每年會寫入 525,600 列。將間隔調整為 15 分鐘後,每年的資料量會變成 35,040 列。實際應用程式通常比這更複雜,因為它們除了依時間回報,也會在位置移動時回報;手機靜止時則會停止回報。因此,請將上方的數字視為上限,而不是預測值。

每年 500,000 列對 PostgreSQL 而言不算多。最先造成問題的成本通常是繪製資料:要求地圖以完整解析度呈現一整年的位置資料時,瀏覽器早在資料庫察覺負載前就可能停滯。這也是此類應用程式會將歷史資料彙整為行程與地點的原因。請在自己的伺服器上測量實際數量,不要直接相信部落格文章中的數字:

SELECT pg_size_pretty(pg_total_relation_size('tc_positions'));

這是 Traccar 在 PostgreSQL 上的 positions 資料表。使用一個月後,對你選擇的伺服器執行對應查詢,再將結果乘以 12。這些伺服器都不會自行刪除舊位置資料。它們會保留你送入的資料,直到你主動移除為止。因此,請在資料表仍小時決定保留政策,並確認備份涵蓋資料庫,而不只是設定檔,因為位置歷史無法從其他資料重建。

電池耗電由手機決定,不是伺服器決定

自架服務不會改變這一點。作業系統會決定 GPS 何時喚醒、背景應用程式可執行多久,以及是否能持續運作到隔天早上。Android 會積極暫停背景工作,iOS 則會提供重大位置變更,而不是持續的位置資料。伺服器無法介入這些決策,因此,應用程式中設定較短的回報間隔只代表提出要求,手機會依自身規則處理。

你能控制的是手機上的設定:授予應用程式「永遠允許」的背景位置權限,將追蹤應用程式排除在電池最佳化之外,並依每天的使用情境調整回報模式。整週使用移動模式,手機通常下午 4 點前就會耗盡電力。

伺服器端的現象是一次寫入大量帶有舊時間戳的資料列。Traccar Client 和 OwnTracks 都會在離線期間暫存位置點,網路恢復後再一次送出,因此寫入時間與定位時間會是不同的值。地圖若在城市中畫出一條直線,表示定位資料有缺口,而不是手機沿著道路行駛。

伺服器端:TLS 與經過驗證的資料接收路徑

手機需要能解析的主機名稱,以及手機信任的憑證。自我簽署憑證是全新安裝完全收不到資料最常見的原因:應用程式會在 TLS 交握時失敗並放棄,而伺服器日誌會保持空白,因為請求從未完成。空白日誌看似是手機問題,但實際上不是。

有兩種直接的做法。使用正式憑證在 nginx 中終止 TLS,也就是在 nginx 前方使用 Let’s Encrypt 憑證,並只開放 443。或者使用 Cloudflare Tunnel,讓公開 IP 上完全沒有接聽中的服務,完全不開放入站埠。這適合 Dawarich 與 OwnTracks,因為它們的資料接收使用一般 HTTP。

使用 Tunnel 時有一項限制。Traccar 的 OsmAnd 通訊協定使用 HTTP,因此手機用戶端通過反向代理或 Tunnel 不會有問題。專用 GPS 硬體使用的二進位通訊協定,則是在各自連接埠上的原始 TCP。這些通訊協定確實需要開放連接埠,且必須同時在 VPS 防火牆及供應商的獨立網路防火牆上開放。大多數主機的供應商網路防火牆位於另一個控制面板。

服務開始回應後,使用一個請求驗證整條路徑,不要只根據應用程式的狀態猜測:

curl -si -u alice:secret -H 'Content-Type: application/json' \
  -d '{"_type":"location","lat":51.5,"lon":-0.12,"tst":1788480000}' \
  https://track.example.com/pub | head -1

正常運作的端點會回覆 2xx 狀態碼。401 表示認證資料錯誤,但傳輸正常。若 curl 在收到任何狀態列前就發生錯誤,表示問題出在 DNS 或 TLS;請先修正憑證,再處理應用程式。

開放的資料接收端點會洩漏你的位置

未經驗證的資料接收 URL 會將你的位置交給任何找到它的人,而確實有人會找到。

  • 持有 URL 的任何人都能將位置點寫入你的歷史紀錄。虛假的位置點很難察覺,移除時也很耗時。
  • URL 不是秘密。它會出現在手機的應用程式設定、反向代理的存取日誌、你曾在瀏覽器分頁中測試過時留下的瀏覽紀錄,以及你尋求協助時附上的任何螢幕截圖中。
  • 會回應未經驗證 GET 請求的端點,會將你最新的位置交給猜中路徑的爬蟲。
  • 無論採取何種措施,主機名稱都是公開的。新核發的憑證會在數分鐘內出現在憑證透明度日誌中,因此從未公開的位址仍然可以被發現。

對 OwnTracks 使用 TLS 上的 HTTP Basic,對 Dawarich 使用 API key,並使用 Traccar 的帳戶模型搭配唯一的裝置識別碼。讓管理介面與資料接收路徑使用相同的驗證機制,因為完整軌跡可在該介面中讀取。接著在第一週後查看有哪些來源持續嘗試連線:

sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

清單中應以手機的行動網路 IP 位址為主。任何其他出現次數很高的來源都值得檢查,而在 nginx 中對資料接收位置設定速率限制不會增加成本。

追蹤系統也可能無聲無息地失效。容器停止執行,手機繼續將資料暫存,直到數週後發現少了一段旅程,才知道發生問題。將容器健康檢查或 systemd OnFailure= 指向你自己的 ntfy 伺服器,讓這段沉默透過同一支負責回報的手機傳達給你。

誰還能查看這些軌跡,以及如何強制執行存取控制

Traccar 透過使用者與裝置權限控管存取:帳戶只能查看管理員授予它的裝置,API 則使用工作階段或 token。OwnTracks over MQTT 透過 broker 的 topic ACL 強制執行存取控制。這是上述方案中最嚴格的方式,因為無法訂閱 topic 的帳戶,無論任何應用程式如何處理,都無法讀取其中的內容。OwnTracks over HTTP 沒有等效的控管層,因此 endpoint 後方的元件就是完整的存取控制機制。Dawarich 的設計前提是由一個人查看自己的歷史記錄;如果有多人需要互相即時查看位置,Traccar 或 broker 會是更合適的選擇。

家庭追蹤除了技術問題,也是同意問題。所有透過手機發布位置的人,都應知道手機正在發布位置,以及如何停止發布。個人無法關閉的追蹤器,不是家庭功能。

自架服務無法解決的問題

  • 手機的作業系統決定何時啟用 GPS,因此耗電與軌跡中的缺口主要是手機造成的,不是伺服器造成的。
  • Google 已變更 Timeline 資料的匯出方式。規劃遷移前,請先閱讀 Dawarich 目前的匯入文件,因為 Google 今天提供的檔案,與人們兩年前匯入的檔案不同。
  • 每次請求都會讓你的端點看到行動網路 IP 位址,請求經過的每個網路也一樣。自架服務會改變誰持有這筆記錄,但不會移除這筆記錄。
  • 位置歷程無法取代。請備份資料庫,並至少還原一次以確認備份可用;同時將備份加密保存,因為這是伺服器上最敏感的檔案。

FAQ

哪個自架應用程式可以取代 Google Maps Timeline?

Dawarich。它是可自架的 Google Timeline 替代方案,可匯入 Google Maps Timeline 匯出資料,以及 OwnTracks、Strava、Immich、GPX、GeoJSON 資料與相片 EXIF,並將歷史記錄呈現為地點與行程,而不是即時地圖。Traccar 也能儲存相同的位置點,但其介面是車隊主控台,報表也是車隊報表。規劃遷移前,請先查看 Dawarich 的匯入文件,確認它要求的匯出格式,因為 Google 的匯出格式曾經變更。

沒有 MQTT broker 也能使用 OwnTracks 嗎?

可以。將應用程式設為 HTTP 模式,並提供格式為 http[s]://[user[:password]@]host[:port]/path 的 URL;對 OwnTracks Recorder 而言,該 URL 為 /pub。它會傳送相同的 JSON payload,並使用 HTTP Basic 進行驗證;OwnTracks 強烈建議使用 https:// scheme。等到有兩個服務需要同時使用相同串流,或需要依 topic 實施存取控制,再加入 broker,讓 broker 決定哪些使用者可以查看哪些資料。

一年的位置歷史記錄需要多少儲存空間?

請以資料列數量而非 GB 規劃。每部手機每分鐘回報一次,一年會產生 525,600 列;每十五分鐘回報一次,則會產生 35,040 列。這兩種規模對 PostgreSQL 都很小。實際限制在於瀏覽器需要在一張地圖上繪製一年的位置點,因此這些應用程式會先進行彙整。使用 pg_total_relation_size 在一個月後測量自己的資料表,再乘以十二。

為什麼我的位置歷史記錄會有缺口?

手機的作業系統決定何時喚醒 GPS,以及何時停止背景應用程式,因此大多數缺口都是從這裡開始的。授予應用程式永久的背景位置權限,將它排除在電池最佳化之外,並檢查回報模式。在 OwnTracks 中,Move mode 每移動 locatorDisplacement 公尺或經過 locatorInterval 秒就會發布一次;預設值為 100 公尺與 300 秒,耗電量相當於導航應用程式。如果資料列在稍後集中抵達,且帶有較早的時間戳記,表示離線緩衝區正在排清資料。位置修正資料已經取得,只有上傳延遲。

只有 secret URL 足以保護位置端點嗎?

不夠。未經驗證的 ingest endpoint 會讓任何取得 URL 的人都能將虛假的位置點寫入歷史記錄;URL 也不是 secret,因為它會出現在應用程式設定、反向代理存取日誌、瀏覽器歷史記錄,以及你分享的任何螢幕截圖中。主機名稱本身即可被發現,因為新憑證簽發後不久就會出現在憑證透明度日誌中。請在 TLS 上使用 HTTP Basic 或 API key,對 ingest path 實施速率限制,並讓管理介面使用相同的驗證機制。

#self-hosting#privacy#traccar#owntracks#dawarich#gps