用 nssm 把 Node.js 程式包成 Windows Service

這個做法來自一個事件警報服務:TypeScript 寫的 MQTT 訂閱程式,需要在 Windows 機器上開機自動啟動、崩潰自動重啟、不占用任何登入畫面。nssm(Non-Sucking Service Manager)是我目前找到最省事的解法。

為什麼是 nssm

  • Windows 原生的 service 要求執行檔實作 service 協定,Node.js 程式做不到
  • nssm 當中介層:它自己是合法的 Windows service,負責啟動、監控、重啟你的程式
  • 免安裝(單一 exe)、設定有 GUI 也有 CLI

安裝服務

# 開啟設定 GUI(最直覺)
nssm install <service-name>

# 或純 CLI
nssm install <service-name> "C:\Program Files\nodejs\node.exe"
nssm set <service-name> AppDirectory "C:\path\to\app"
nssm set <service-name> AppParameters "dist\index.js"

設定重點:

欄位用途
Applicationnode.exe 的完整路徑
AppDirectory程式的工作目錄(影響相對路徑與 .env 讀取)
AppParameters要執行的進入點(編譯後的 js)
AppStdout / AppStderr導出日誌到檔案,除錯必設

日常管理

nssm start <service-name>
nssm stop <service-name>
nssm restart <service-name>
nssm status <service-name>
nssm edit <service-name>     # 重開設定 GUI
nssm remove <service-name>   # 移除服務

注意事項

  • TypeScript 專案先編譯成 js 再讓 nssm 指向產物,不要在 service 裡跑 ts-node
  • 服務以 Local System 身分執行,讀不到使用者層級的環境變數——需要的設定放 AppDirectory 下的 .env 或 nssm 的 AppEnvironmentExtra
  • 有音訊輸出的服務(例如接 mpg123 播警示音)