咻揪趣 MVP · v0.19.0
上線作業 · 文件 上線檢查清單與部署說明 · 產生於 2026-09-22 15:45

上線檢查清單與部署說明

適用版本:v0.11.0 · 執行環境:Node ≥ 22.5(僅需內建模組,無第三方套件)

一句話結論: 這份程式碼已經可以直接上線;本機一條 npm start 即可跑起正式模式,雲端則用附帶的 Dockerfile 打包,掛上持久化磁碟與環境變數就能對外服務。上線前把第 7 節的檢查清單逐項打勾,並先跑一次 npm run preflight 自動檢查(0 項「擋上線」才算過)。

1. 部署架構

1
使用者瀏覽器
行動優先 Web App(/)與管理後台(/admin),單一網址,無需安裝。
2
反向代理(Caddy / Nginx)
負責 TLS 憑證、gzip、安全標頭,並用 /api/health 做健康探測。
3
咻揪趣 服務(Node 22)
單一常駐程序,同時服務前端靜態檔、/api/*/admin/api/*/docs/*
4
資料層(SQLite,WAL)
單一檔案 data/mapsync.db,掛載持久化磁碟;scripts/backup.js 產出可離線保存的快照。

2. 環境變數

變數必填預設說明
PORT8848服務監聽埠
HOST0.0.0.0監聽位址
NODE_ENV建議正式環境設 production
MAPSYNC_DATA_DIR正式環境建議./data資料庫目錄,雲端請指向掛載的持久化磁碟(如 /data
MAPSYNC_BACKUP_DIR./backups備份輸出目錄
MAPSYNC_ADMIN_TOKEN正式環境必填自動產生後台權杖。未設定時系統會產生並寫入 data/admin-token.txt
MAPSYNC_LLM_KEY設定後解析引擎自動升級為 LLM
MAPSYNC_LLM_ENDPOINTOpenAI 相容端點自帶相容 API 的服務位址
MAPSYNC_LLM_MODELgpt-4o-mini模型名稱
MAPSYNC_PLACES_KEY設定後解析結果自動補上 place_id/經緯度/地址/營業時間
MAPSYNC_PLACES_ENDPOINTGoogle Places v1可覆寫(測試用)
MAPSYNC_PLACES_TIMEOUT_MS6000Places 查詢逾時,逾時只略過補點
MAPSYNC_PUBLIC_URL對外網址;設定後可供 preflight 檢查外部可達性
MAPSYNC_DRIVE_TOKEN遠端備份用;Google Drive 上傳的 OAuth 存取權杖
MAPSYNC_DRIVE_FOLDER_ID遠端備份目錄(Drive 資料夾 id,不給則放根目錄)
MAPSYNC_RCLONE_REMOTE改用 rclone 模式時的目標,例如 <code>gdrive:mapsync-backups</code>
兩組金鑰都是可選的加速項而非必需品:不設時解析與打點照常運作(規則引擎+內建地標辭典),只是覆蓋率較低。
範本見 <code>.env.example</code>。切勿把真實權杖提交進版本庫(<code>.gitignore</code> 已排除 <code>.env</code> 與 <code>data/</code>)。

3. 部署路徑 A:本機/單機(最快驗收)

npm start
# App    http://127.0.0.1:8848/
# Admin  http://127.0.0.1:8848/admin
# Health http://127.0.0.1:8848/api/health
# Ready  http://127.0.0.1:8848/api/ready

Windows 可直接雙擊專案根目錄的 start.bat(會自動帶入 NODE_ENV=production 並印出網址)。

首次啟動會自動建立資料庫並寫入示範資料。要清空重來:<code>npm run seed</code>。

4. 部署路徑 B:Docker + Caddy(建議的正式環境)

# 1. 準備環境變數
cp .env.example .env
# 編輯 .env,至少設定:
#   MAPSYNC_ADMIN_TOKEN=<一串長隨機字串>
#   DOMAIN=mapsync.example.com

# 2. 啟動(首次會 build 映像)
cd deploy && docker compose --env-file ../.env up -d --build

# 3. 驗證
curl -fsS https://$DOMAIN/api/health
  • Caddy 會自動申請並續期 TLS 憑證,並加上 X-Frame-OptionsX-Content-Type-OptionsReferrer-Policy 等安全標頭。
  • mapsync-data volume 保存資料庫;升級映像不會動到資料。
  • Dockerfile 內建 HEALTHCHECK,平台可據此自動重啟不健康的實例。
  • 5. 部署路徑 C:雲平台(Fly.io / Render / Railway 皆可)

    以 Fly.io 為例:

    fly launch --no-deploy           # 產生 fly.toml,選一個離使用者近的 region
    fly volumes create mapsync_data --size 1   # 1GB 持久化磁碟
    fly secrets set MAPSYNC_ADMIN_TOKEN=<長隨機字串>
    # 在 fly.toml 加入:
    #   [mounts]
    #     source = "mapsync_data"
    #     destination = "/data"
    #   [env]
    #     MAPSYNC_DATA_DIR = "/data"
    fly deploy

    其他平台同理:把 <code>deploy/Dockerfile</code> 當建置來源、<code>MAPSYNC_DATA_DIR</code> 指向持久化磁碟、設定 <code>MAPSYNC_ADMIN_TOKEN</code>,並把健康檢查路徑設為 <code>/api/health</code>。

    6. 服務常駐與啟動腳本

    平台
    做法
    Windows(本機/內網)
    雙擊 start.bat;視窗關閉即停止。要開機自動執行,用工作排程器呼叫 start.bat
    Linux(VPS)
    複製 deploy/mapsync.service/etc/systemd/system/,設定 /etc/mapsync/mapsync.envsystemctl enable --now mapsync。內含 Restart=alwaysNoNewPrivilegesProtectSystem=strict 等硬化設定。
    容器平台
    deploy/Dockerfile 已內建 HEALTHCHECK,平台依 /api/health 判斷實例健康並自動重啟。

    PWA 與分享面板的上線注意事項

  • Service Worker 只快取 App 殼(HTML/CSS/JS/圖示),/api//admin 一律走網路,不會把資料或權杖寫進快取。
  • 必須以 HTTPS(或 localhost)提供服務,否則 Service Worker 與 Web Share Target 不會生效——Caddy 會自動處理憑證。
  • Android Chrome 需先「加入主畫面」,分享面板才會出現 咻揪趣。
  • 反向代理不要快取 /sw.js(建議 Cache-Control: no-cache),避免使用者卡在舊版 App 殼。
  • 服務本身也已內建上線防護(不依賴反向代理):<code>nosniff</code>、<code>X-Frame-Options: DENY</code>、<code>Referrer-Policy</code>、<code>Permissions-Policy</code>、CSP;寫入類 API 每來源每分鐘 120 次上限;請求大小上限 512 KB;啟動時埠被占用會直接以明確錯誤碼退出而不是默默失敗。

    7. 上線檢查清單

    部署前
    部署後立即驗證
    上線後
    標示 [x] 者代表本機正式環境已完成驗證;[ ] 者屬於外部環境設定,需在實際主機上完成。

    8. 監控與回復(Rollback)

    監控面向
    做法
    存活監控
    /api/health 回 200/503,含 uptimeSecdb 狀態;/api/ready 另檢查 schema 是否完整。容器平台與外部 uptime 皆可探測。
    錯誤監控
    所有 API 錯誤與業務事件寫入 app_logsevents,後台可即時查看;level=error 筆數即為告警指標。
    版本追溯
    /api/version 回報版本、Node 版本與環境;每次部署在下方紀錄表留下版本與時間。
    資料回復
    npm run backup 產出快照;node scripts/backup.js --restore <檔名> 還原(會先自動備份現況)。

    回滾流程(3 步)

    1. 程式碼回滾:git checkout v0.9.0(版本錨點)或上一個穩定版後重新部署(Docker:docker compose up -d --build)。
    2. 資料回滾(僅在資料受損時):先停服務 → node scripts/backup.js --restore mapsync-<時間>.db → 重啟服務。腳本會先自動備份現況再覆蓋。
    3. 驗證:curl -fsS /api/health + npm run smoke(16 項)+ 後台確認資料表筆數回到預期。

    實地演練紀錄(2026-09-21)

    步驟動作結果
    1演練前基準圖釘 9 筆
    2npm run backup產出 mapsync-2026-09-21T04-45-01-819Z.db(112 KB)
    3新增標記圖釘圖釘 10 筆(含 p_682ee97d5ab0
    4停服務 → --restore還原成功,且自動先備份現況(另存 04-45-11 快照)
    5重啟服務後查詢圖釘回到 9 筆、標記圖釘消失、/api/health 200
    程式碼回滾不動資料庫;資料回滾會覆蓋現有資料,因此腳本會先自動備份現況。上述流程已實際走過一次,非紙上推演。

    9. 部署紀錄

    時間版本環境方式結果
    2026-09-21 04:35v0.9.0本機正式模式(127.0.0.1:8848)npm start<span class="rich-badge ok">成功</span> 健康檢查 200、核心流程以瀏覽器實機驗證
    2026-09-21 04:43v0.9.0本機正式模式(生產強化版)npm start<span class="rich-badge ok">成功</span> 冒煙 16/16、可用率監控 100%、告警路徑驗證通過
    2026-09-21 04:45v0.9.0本機正式模式停機 → 備份還原 → 重啟<span class="rich-badge ok">成功</span> 回滾演練:10 筆 → 還原 → 9 筆,標記消失
    2026-09-21 04:46v0.9.0版控錨點git tag v0.9.0<span class="rich-badge ok">成功</span> 標籤 v0.9.0、38 檔入版控、修正 Linux 檔名大小寫
    2026-09-21 04:57v0.10.0本機正式模式重啟載入新模組<span class="rich-badge ok">成功</span> 驗收 30/30、冒煙 16/16、AI 鏈路 21/21、資料庫欄位遷移完成
    2026-09-21 04:59v0.10.0本機正式模式瀏覽器開 /share 實測<span class="rich-badge ok">成功</span> 分享內容預填、解析完成並留痕
    2026-09-21 05:10v0.10.0上線前檢查npm run preflight<span class="rich-badge ok">成功</span> 0 項擋上線、6 項待補(皆為環境設定與金鑰)
    (待填)v0.10.0雲端 + 網域Docker + Caddy<span class="rich-badge warn">待執行</span> 需先決定平台與網域(HTTPS 為分享面板前提)
    每次部署後請補一列,這是「留下部署紀錄」的可查驗形式。