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

自架位置追蹤 App 怎麼選?Traccar、OwnTracks、Dawarich 比較

比較 Traccar、OwnTracks、Dawarich 與 Home Assistant,依位置歷史、即時地圖或自動化需求選擇,並將 ingest endpoint 留在公開網際網路之外。

適合你情境的自架位置追蹤應用程式

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

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

  • 去年 3 月去過的所有地方,以及地點與行程地圖:Dawarich。
  • 多部裝置的即時地圖,以及地理圍籬與事件規則:Traccar。
  • 讓單支手機將位置傳送到你已經執行的服務:使用 HTTP 模式的 OwnTracks。
  • 居家與外出自動化,不需要位置歷史:單獨使用 Home Assistant。

若要透過 HTTP 回報位置,手機必須能連線到你控制的 HTTPS endpoint,因此伺服器端會在下方另設一個章節。若你還在規劃伺服器上要執行哪些服務,今年值得自架的服務完整清單可讓你了解位置追蹤服務在整體架構中的位置。

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

Traccar 是追蹤伺服器。它支援專用 GPS 追蹤器使用的通訊協定,每個協定各自使用一個連接埠。根據目前的協定清單,連接埠編號從 5001 到 5267;Traccar 自己的 Docker 使用說明則會發布 TCP 與 UDP 的完整 5000 到 5300 範圍。相同說明也警告,每個發布的連接埠都會啟動自己的 docker-proxy 程序,會消耗大量記憶體。因此,只發布裝置實際使用的連接埠,或停用 Docker 的 userland proxy,改用 iptables NAT,會是較輕量的選擇。除此之外,Traccar 還提供即時地圖、地理圍籬、事件規則與報表。Web 介面預設監聽連接埠 8082。

手機可使用 Android 與 iOS 的 Traccar Client 應用程式。它透過 OsmAnd 通訊協定回報位置,預設監聽連接埠 5055。應用程式中的設定會決定電池續航力與位置資料筆數。Distance 會在移動時每隔 N 公尺要求更新一次。當距離設定為 0 時,Interval 會啟用依時間回報;此功能僅適用於 Android。當精確度設為最高時,Interval 也會啟用依時間回報。當精確度設為最高時,Angle 會在航向變更達指定角度時觸發更新。Stationary Heartbeat 控制裝置未移動時的行為。Traccar 官方文件指出,這些設定都無法保證確切結果,因為最終決定權在手機。

Traccar 隨附內嵌的 H2 資料庫,因此安裝程式無須額外設定即可運作;但專案不建議在正式環境使用 H2。文件說明可改用 MySQL、MariaDB 與 PostgreSQL,並建議大型部署使用 TimescaleDB。TimescaleDB 是建構於 PostgreSQL 上的時間序列資料庫。請在累積歷史資料前搬移資料庫,因為日後若要保留這些歷史資料,就必須將現有資料遷移到替代資料庫。

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

OwnTracks:手機應用程式、Recorder 與 Frontend

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 是一般的自動模式。在 iOS 上,Move 會在裝置移動 locatorDisplacement 公尺或經過 locatorInterval 秒時發布,先達到的條件優先;預設值分別為 100 公尺和 300 秒。在 Android 上,Move 預設每 10 秒要求一次定位。OwnTracks 文件指出,Move 模式的耗電量與導航應用程式相當,建議在旅途中或充電時使用,而不要作為日常設定。

OwnTracks Recorder 會儲存收到的資料並提供簡易地圖;獨立的 OwnTracks Frontend 則在其上提供較完整的網頁介面,包括熱點圖、日期範圍篩選,以及以點或線繪製的歷史紀錄。許多人完全不安裝 Recorder,因為無論應用程式指向 Recorder、Dawarich 或 Home Assistant,payload 都相同。這就是從這裡開始的原因:應用程式是穩定且單純的資料來源,之後仍可更換資料接收端。

Dawarich:自架 Google Maps Timeline

Dawarich 採用 AGPL-3.0 授權,並透過 Docker Compose 檔案執行。現行預設安裝包含 3 個容器:內含 Rails 應用程式與 Sidekiq 背景工作的容器、PostgreSQL,以及 Redis。應用程式提供 3000 埠。可匯入的來源包括 Google Maps Timeline、OwnTracks、Strava、Immich、GPX 與 GeoJSON 檔案,以及相片中的 EXIF 資料。這份匯入清單讓它不只是即時地圖,也能匯入早於伺服器啟用時間的歷史資料。

資料匯入使用 HTTP endpoint,並帶有帳戶頁面中的 API key。OwnTracks 會將資料傳送至 /api/v1/owntracks/points?api_key=...,Overland 則傳送至 /api/v1/overland/batches?api_key=...。GPSLogger 會重用 OwnTracks endpoint。

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

至於 compose 檔案本身、volumes 與 restart policy,請參閱 在 VPS 上執行 compose 的容器運作方式。本頁內容到此,實際採用與否請自行決定。

Home Assistant:適合判斷是否在家,不適合保存歷史記錄

如果您已經在執行 Home Assistant,便已具備裝置追蹤功能。伴 app 會回報位置,而 OwnTracks integration 會提供 webhook URL 與 encryption key,供您貼到 app 中。設定 MQTT 後,該 integration 會改為監聽 MQTT 訊息,而不是 HTTP。

限制在於保留期限。Home Assistant 的 recorder 預設為 purge_keep_days: 10,並會在當地時間每天 04:12 執行自動清理,避免資料庫無限制成長。這項預設值適合家庭自動化資料庫,但不適合位置歷史封存。Home Assistant 能回答「現在有人在家嗎?」若要回答「我在 3 月 14 日時位於何處?」,就必須在歷史記錄刪除前保留資料:提高 purge_keep_days、停用 auto_purge,或將相同串流傳送至能保留資料的其他系統。保留較長的歷史記錄會使 recorder 資料庫增大;如果停用 auto_purge,文件建議自行排程定期執行 recorder.purge 呼叫。

持續追蹤或偶爾分享?

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

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

如果你要的是單次旅程使用 2 小時的分享連結,決定採用哪台伺服器前,請先查看其 release notes。Traccar 提供暫時性的裝置分享連結;Dawarich 則提供即時位置分享連結,可選擇設定 passphrase、到期日期,並立即撤銷連結。

你是否真的需要 MQTT broker?

先不要使用 broker。HTTP 模式只需要 URL、密碼與 TLS(傳輸層安全性),上述每台伺服器都支援這種模式。當多個元件需要在同一時間取得相同串流時,broker 才有存在的必要。例如,Home Assistant 需要對某個區域做出反應,同時錄影程式寫入歷史紀錄,或家庭成員需要互相查看時,便適合使用 broker。

MQTT 是發布與訂閱協定,Mosquitto 是常用的 broker。其預設 listener 使用 1883 埠傳送未加密內容;請在 8883 設定 TLS listener,並只公開該 listener。存取控制以 topic 為單位,因此可以允許某個帳號發布到 owntracks/alice/phone,但不允許讀取其他內容。這就是家庭環境採用 MQTT 的主要理由:broker 會在應用程式下層強制執行誰能查看誰的規則,因此即使應用程式發生錯誤,也無法擴大可見範圍。

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

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

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

圖表Position rows per phone at a fixed reporting interval (arithmetic)
此圖表背後的資料
[
  {
    "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 筆資料。實際應用程式通常更複雜,因為除了依時間回報,也會在位置移動時回報;手機靜止時則可能停止回報。因此,請將這些數字視為固定間隔的範例,而不是預測值。

每年 50 萬筆資料對 PostgreSQL 而言並不多。較早遇到的瓶頸通常是繪製資料:若地圖要求以完整解析度繪製一整年的位置資料,瀏覽器會在資料庫察覺負載前就停止回應。因此,這類應用程式通常會將歷史資料彙整為行程與地點。請在自己的主機上測量實際數量,不要直接採用部落格文章中的數字:

SELECT pg_size_pretty(pg_total_relation_size('tc_positions'));

這是 Traccar 在 PostgreSQL 中的 positions 資料表。選定伺服器後,正常使用一個月,再執行等效查詢,最後乘以十二。Home Assistant 預設會自動刪除舊的歷史資料。請在資料表仍然較小時訂定保留規則,並確認備份涵蓋資料庫,而不只是設定檔,因為位置歷史無法從其他資料重建。

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

自架服務不會改變這一點。作業系統會決定 GPS 何時喚醒、背景應用程式可執行多久,以及是否能持續運作一整晚。Android 會積極暫停背景工作,iOS 則會提供顯著位置變化,而不是持續的位置資料。伺服器無法介入這些行為,因此在應用程式中縮短回報間隔只是一項要求,手機會依自身規則處理。

你能控制的是手機端設定:授予應用程式「一律允許」的背景位置權限、將追蹤應用程式排除在電池最佳化之外,並依每天的使用情境調整回報模式。整週都使用移動模式,手機很可能下午 4 點前就沒電。

伺服器端的症狀是突然收到一批帶有舊時間戳記的資料列。OwnTracks 以及啟用離線緩衝設定的 Traccar Client,會在離線期間暫存位置點,網路恢復後再一次送出,因此寫入時間與定位時間會是不同值。當地圖在城市中畫出一條直線時,表示定位資料中間有缺口,不代表那是一條道路。

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

手機需要一個可解析的主機名稱,以及手機信任的憑證。自簽憑證是全新安裝完全收不到資料最常見的原因:應用程式會因 TLS 交握失敗而放棄,伺服器日誌則保持空白,因為請求根本沒有完成。空白日誌看起來像是手機問題,但實際上不是。

有兩種清楚的做法。第一種是在 nginx 中使用正式憑證終止 TLS,也就是在 nginx 前方使用 Let's Encrypt 憑證,並開放 80 與 443 埠。80 埠必須持續可連線,因為 certbot 的 nginx 外掛會使用 HTTP-01 challenge 驗證網域,而 Let's Encrypt 只會在 80 埠執行這項驗證。因此,請將 80 埠重新導向至 HTTPS,不要關閉它。只有改用 DNS-01 或 TLS-ALPN-01 challenge,才能只使用 443 埠。第二種是不開放任何入站埠,改用 Cloudflare Tunnel,讓公用 IP 上沒有任何服務監聽。這適合 Dawarich 與 OwnTracks,因為它們的資料接收使用一般 HTTP。

Tunnel 方案有一項限制。Traccar 的 OsmAnd protocol 使用 HTTP,因此手機用戶端通過反向代理或 tunnel 時不會有問題。專用 GPS 硬體使用的二進位 protocol 則會在各自的埠上使用原始 TCP 或 UDP。這些埠必須確實開放,除了 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 失敗是不同問題。請先修正錯誤訊息所指出的問題,再處理應用程式。

開放的 ingest endpoint 會洩漏你的位置

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

  • 任何持有該 URL 的人都能將資料點寫入你的歷程。錯誤資料點很難察覺,移除起來也很麻煩。
  • URL 不是秘密。它會出現在手機的應用程式設定、反向代理的存取日誌,以及你曾在瀏覽器分頁中測試過該 URL 時的瀏覽記錄,也可能出現在你求助時附上的螢幕截圖中。
  • 未受保護的讀取 API,例如 OwnTracks Recorder 的 /api/0/last,會將你最新的位置交給任何查詢它的人。
  • 無論採取何種措施,主機名稱都是公開的。新核發的憑證會在幾分鐘內出現在憑證透明度日誌,因此即使你從未公開某個位址,該位址仍可被發現。

OwnTracks 使用 TLS 上的 HTTP Basic,Dawarich 使用 API key,Traccar 則使用其帳戶模型,並設定唯一的裝置識別碼。讓管理介面與 ingest 路徑使用相同的驗證機制,因為整段軌跡都能在該介面中讀取。第一週後,查看有哪些來源持續嘗試連線:

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

清單中應以手機的行動 IP 位址為主。其他計數很高的來源都值得檢查,而且在 nginx 的 ingest 位置設定速率限制不會增加成本。

追蹤器也可能無聲無息地失效。容器停止執行,手機持續緩衝資料,而你直到幾週後發現某趟行程遺失,才知道發生問題。將容器 health check 或 systemd OnFailure= 指向你自己的 ntfy 伺服器,讓這份沉默透過同一支負責回報的手機通知你。

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

Traccar 透過使用者與裝置權限控管存取:帳戶只能查看管理員授予它的裝置,API 則使用工作階段或 token。OwnTracks 透過 MQTT 時,會在 broker 以主題 ACL 強制執行存取控制。這是其中最嚴格的方式,因為無法訂閱某個主題的帳戶,不論任何應用程式如何處理,都無法讀取該主題。OwnTracks 透過 HTTP 時沒有對等的控制層,因此 endpoint 後方的元件就是完整的存取控制機制。Dawarich 也支援家人即時位置分享,且每位成員都能自行控制是否分享位置。

家庭追蹤不只是技術問題,也涉及同意。所有手機會發布位置的人,都應知道手機正在發布位置,以及如何停止發布。無法由當事人關閉的追蹤器,不算是家庭功能。

自架服務無法解決的問題

  • 手機的作業系統會決定何時啟用 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,以及何時停止背景應用程式,因此大多數缺口都始於此處。授予應用程式「永遠」的背景定位權限,將其排除在電池最佳化之外,並確認回報模式。在 iOS 的 OwnTracks 中,Move 模式每 locatorDisplacement 公尺或 locatorInterval 秒發布一次,預設值為 100 公尺和 300 秒;在 Android 上,則預設每 10 秒要求一次定位。無論是哪種情況,其耗電量都相當於導航應用程式。如果資料列延遲成批抵達,且帶有較早的時間戳記,表示離線緩衝區正在清空;定位資料已經取得,只是上傳延遲。

只使用秘密 URL 足以保護位置端點嗎?

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

這篇文章對您有幫助嗎?

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