自建 OwnTrack 追蹤個人 GPS 軌跡服務

graph TB %% External Components Mobile[📱 OwnTracks Mobile App
MQTT + WebSocket] Browser[🌐 Web Browser] External[🌍 External MQTT Clients] WebApp[📱 Mobile Web App
WebSocket Only] %% Docker Services subgraph "Docker Environment" subgraph "Mosquitto MQTT Broker" MQTT[Eclipse Mosquitto
Port: 1883, 9001] end subgraph "OwnTracks Recorder" Recorder[OwnTracks Recorder
Port: 8083
HTTP API] end subgraph "Frontend Web Interface" Frontend[OwnTracks Frontend
Port: 80
Nginx Web Server] end end %% Storage subgraph "Data Storage" MosquittocConf[(Mosquitto Config
./mosquitto/config)] MosquittoData[(Mosquitto Data
./mosquitto/data)] MosquittoLog[(Mosquitto Logs
./mosquitto/log)] RecorderStore[(Location Data
./store)] AuthFile[(Authentication
./auth/users.auth)] end %% Data Flow - Location Publishing Mobile -.->|MQTT Publish
Location Data
Port 1883| MQTT Mobile -.->|WebSocket Publish
Location Data
Port 9001| MQTT External -.->|MQTT Publish
Location Data
Port 1883| MQTT WebApp -.->|WebSocket Publish
Location Data
Port 9001| MQTT %% Internal MQTT Subscription MQTT -->|MQTT Subscribe
Location Topics| Recorder %% Data Storage Flow Recorder --> RecorderStore MQTT --> MosquittoData MQTT --> MosquittoLog %% Web Interface Flow Browser -->|HTTP Request
Port 80| Frontend Frontend -->|HTTP API Calls
Port 8083| Recorder Recorder -->|JSON Response
Location Data| Frontend Frontend -->|HTML/JS/CSS| Browser %% Configuration and Authentication MQTT -.-> MosquittocConf Recorder -.-> AuthFile %% WebSocket for Real-time (optional) MQTT -.->|WebSocket
Port 9001| Browser %% Styling classDef service fill:#e1f5fe,stroke:#01579b,stroke-width:2px classDef storage fill:#f3e5f5,stroke:#4a148c,stroke-width:2px classDef external fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px class MQTT,Recorder,Frontend service class MosquittoData,MosquittoLog,RecorderStore,AuthFile,ConfigFile storage class Mobile,Browser,External external

  • 安裝與設定目錄檔案配置
    .
    ├── auth
    │   └── users.auth
    ├── docker-compose.yml
    ├── .env
    └── mosquitto
        └── config
            ├── mosquitto.conf
            └── passwd
  • docker-compose.yml
    services:
      mosquitto:
        image: eclipse-mosquitto:2
        ports:
          - 1883:1883
          - 9001:9001
        volumes:
          - ./mosquitto/config:/mosquitto/config
          - ./mosquitto/data:/mosquitto/data
          - ./mosquitto/log:/mosquitto/log
        restart: unless-stopped
     
      otrecorder:
        image: owntracks/recorder
        ports:
          - 8083:8083
        volumes:
          - ./store:/store
          - ./config:/config
          - ./auth:/auth
        restart: unless-stopped
        environment:
          - OTR_HOST=mosquitto
          - OTR_PORT=1883
          - OTR_USER=${OTR_USER}
          - OTR_PASS=${OTR_PASS}
          - OTR_HTTPPORT=8083
          - OTR_AUTHFILE=/auth/users.auth
        depends_on:
          - mosquitto
     
      owntracks-frontend:
        image: owntracks/frontend
        ports:
          - 80:80
        environment:
          - SERVER_HOST=otrecorder
          - SERVER_PORT=8083
        restart: unless-stopped
     

    https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/owntracks/docker-compose.yml

  1. 到 .env 內設定 recoder 存取 MQTT 的帳號密碼

    vi .env

  2. 產生 MQTT 的設定檔 mosquitto/config/mosquitto.conf

    mkdir -p mosquitto/config/
    vi mosquitto/config/mosquitto.conf

    • mosquitto/config/mosquitto.conf
      listener 1883
      protocol mqtt
       
      listener 9001
      protocol websockets
       
      allow_anonymous true
      #allow_anonymous false
      #password_file /mosquitto/config/passwd
       
      log_dest file /mosquitto/log/mosquitto.log
      log_type error
      log_type warning
      log_type notice
      log_type information
      #log_type debug
      #log_type subscribe
      #log_type unsubscribe
       
      persistence true
      persistence_location /mosquitto/data/
       
      max_inflight_messages 20
      max_queued_messages 1000
       
      allow_zero_length_clientid true
       
      connection_messages true
      log_timestamp true
       

      https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/owntracks/mosquitto/config/mosquitto.conf

  3. 產生可存取 MQTT 的帳號密碼檔

    touch mosquitto/config/passwd
    chmod 0770 mosquitto/config/passwd

  4. 設定直接存取 OTRecorder 的帳號密碼檔 auth/users.auth (不透過 MQTT 直接存取)

    mkdir -p auth
    vi auth/users.auth

  5. 第一次啟動服務

    docker compose pull
    docker compose up -d

  6. 查看相關紀錄
    • docker compose 紀錄

      docker compose logs -f

    • MQTT 紀錄

      tail -f mosquitto/log/mosquitto.log

  7. 建立 Recoder 存取 MQTT 的帳號密碼(定義在 .env 內) Exp. recorder / recorderpass

    docker compose exec mosquitto chown root:root /mosquitto/config/passwd
    docker compose exec mosquitto mosquitto_passwd /mosquitto/config/passwd recorder

    輸入兩次密碼 recorderpass 即可

  8. 建立 jonathan 存取 MQTT 的帳號密碼 Exp. jonathan / mypassword

    docker compose exec mosquitto mosquitto_passwd /mosquitto/config/passwd jonathan

    輸入兩次密碼 mypassword 即可

直接連 OTRecoder

連 MQTT (才可看到 Friends)

  • Connection 要選 MQTT
  • 設定 Endpoint
    • Host/Port Exp. 192.168.11.200 / 9001 (WebSocket)
    • Client ID Exp. jonathan (建議和 Credentials 的 Username 相同
    • Use WebSockets : 啟用
  • 設定 Identification
    • Device ID Exp. pixel9
    • Tracker ID Exp. jt (會顯示在 Android 的地圖上)
  • 設定 Credentials (設定在 mosquitto/config/passwd)
    • Username Exp. jonathan
    • Password Exp. mypassword
  • TLS 關閉
  • Parameters
    • Keepalive : 3600
    • Clean Session : 啟動
  • 這樣的設定好處是, 手機連上哪個網路都可以立即回報, 不用等回到可連上內網的網路才統一回報
目前 MQTT + WebSocket 服務還無法成功透過 Cloudflare Tunnel 設定方式提供對外服務
  • 因為在相同裝置 Exp. Android, 修改設定中的 Device ID, Username 就會在主機端自動建立不同的目錄 Exp. Device ID : pixel9 , Username : jonathan 就會在 store/rec 與 store/last 都會建立出 jonathan/pixel9 的目錄
  • 如果想要將 store/rec 內的紀錄檔 Exp. 2025-05.rec 進行合併 Exp. jonathan/jonathan/2025-05.rec → jonathan/pixel9/2025-05.rec
    1. 備份與合併 2025-05.rec

      cd store/rec/jonathan/pixel9
      cp 2025-05.rec 2025-05.rec.bak
      cat ../jonathan/2025-05.rec >> 2025-05.rec

    2. 將合併後的檔案依照資料時間進行排序

      sort -s -k 1 2025-05.rec -o 2025-05.rec

    3. 刪除 data.mdb 資料檔

      cd
      rm -f store/ghash/data.mdb

    4. 重起 otrecorder 服務

      docker compose restart otrecorder
      docker compose logs -f otrecorder

  • 因為在相同裝置 Exp. Android, 修改設定中的 Device ID, Username 就會在主機端自動建立不同的目錄 Exp. Device ID : jonathan , Username : jonathan 就會在 store/rec 與 store/last 都會建立出 jonathan/jonathan 的目錄
  1. 針對這檔案型的作法就是直接刪除檔案 Exp. 刪除 jonathan/jonathan

    cd
    rm -rf store/rec/jonathan/jonathan/
    rm -rf store/last/jonathan/jonathan/
    rm -f store/ghash/data.mdb

  2. 重起 otrecorder 服務

    docker compose restart otrecorder

  3. 刪除 MQTT 的資料後, 重起服務

    rm mosquitto/data/mosquitto.db
    docker compose restart mosquitto

  4. 在 Android 需要進入 Friends→ 點選要刪除的項目 Exp. jt → 將畫面底下訊息上拉 → 點選 CLEAR
  • tech/owntrack.txt
  • 上一次變更: 2025/05/26 11:21
  • jonathan