Running Next.js as Windows Service

為測試紀錄。next.js, windows service, Node Server

參考文章

主要流程參數此篇文章。

步驟中的 server.js 檔內容以Next.js官網建議的 Custom Server 為準。

用來註冊 next.js app 成 windows service。 此qckwinsvc已不再維護,然仍有作用。 而qckwinsvc2取代qckwinsvc,名稱也延續。只是這一回使用經驗上沒有發揮作用。

更多資訊

node-windows 工具,留參用。

問題處理

SSL/TLS未實作,留存未來參考。

補充:部署到Linux等平台

Next.js 部署對象若非直接支援者,經多方嘗試一定要轉成 Node.js Server 模式才能成功部署到他方。若部署對象是windows service則一定要搭配node_windows模組,不管直接或間接。

若部署對象是Linux此時,建議用 PM2部署 Node.js Server。PM2非常易用可惜不直接支援windows service模式,要轉一大圈才行。

關鍵步驟

  1. 把 next.js web app 轉成 Node.js Server 型式。

    1. 加入 server.js 檔並編寫。此檔是實作 Node.js Server 的關鍵步驟。

  2. 再把 node.js server 包裝成 deaman 並註冊成window service。

    1. 使用工具 qckwinsvc。未來可能要改用 qckwinsvc2

意外狀況

爬了數篇文章,把Node.js Server註冊成 windows service 有三種方法:

  • 使用qckwinsvc工具,已過時然仍有作用。

  • 使用qckwinsvc2工具,這指令有執行成功訊息但實際上無效用。(囧)

  • 使用node-windows工具,可執行但無作用,不知缺了什麼。

紀錄

一、實作成 Node.js Server

(1)在專案目錄加入 server.js 檔並編寫。

server.js
// server.js
// ref→[Custom Server](https://nextjs.org/docs/advanced-features/custom-server)
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 8080
// when using middleware `hostname` and `port` must be provided below
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  createServer(async (req, res) => {
    try {
      // Be sure to pass `true` as the second argument to `url.parse`.
      // This tells it to parse the query portion of the URL.
      const parsedUrl = parse(req.url, true)
      const { pathname, query } = parsedUrl

      if (pathname === '/a') {
        await app.render(req, res, '/a', query)
      } else if (pathname === '/b') {
        await app.render(req, res, '/b', query)
      } else {
        await handle(req, res, parsedUrl)
      }
    } catch (err) {
      console.error('Error occurred handling', req.url, err)
      res.statusCode = 500
      res.end('internal server error')
    }
  }).listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://${hostname}:${port}`)
  })
})

(2) 加入改用 package.json 中 scripts 的 start 設定。

package.json
{
  "scripts": {
    "dev": "next",
    "build": "next build", 
    // "start": "next start", 改寫如下
    "start": "set NODE_ENV=production && set PORT=8080 && node server.js", // for windows
    //"start": "cross-env NODE_ENV=production PORT=8080 node server.js", 
    // for linux/MAC 或安裝 cross-env 模組就能跨平台。
    "lint": "next lint",
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    "cross-env": "^7.0.3",
    ...
  }
}

(3)下達啟動指令確認可成功啟動新設定的 Node.js Server。

> npm run start

二、把 Node.js Server 註冊成window service

在專案目錄中使用qckwinsvc工具協助註冊。指令紀錄畫面:

其中設定過程中出現了警告不過還是成功且有作用。

打開 services.msc 可以看到服務註冊成功並已啟動,本例名為:NextJsLab。

成功的話,專案會增加deamon目錄與相關執行檔,此例是nextjslab.exe,它才是服務啟動進入點。

EOF

Last updated