【Next.js】Day 4 – Deploy as Winows Service

將各環境的 .env 都加上當然就要部屬囉~
官網看起來部署方式有很多種

  • Vercel
    • Next.js 就是他家開發的框架啊!!!!
  • Node.js server
    • 只要安裝 node.js 的 server 都可以部署
  • Docker container
  • static export

這次選的是 Node.js server,安裝成 windows service

首先,需要於根目錄新增 server.js 做為程式進入點

const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
 
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// 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')
    }
  })
    .once('error', (err) => {
      console.error(err)
      process.exit(1)
    })
    .listen(port, () => {
      console.log(`> Ready on http://${hostname}:${port}`)
    })
})

我們使用 node-windows 將 node.js script 安裝為 windows service

npm install -g node-windows

準備 node.js 安裝 script

//install-windows-service.js
const path = require('path');
const Service = require('node-windows').Service;

const svc = new Service({
  name: 'my-app',
  description: 'This is my app',
  script: path.join(__dirname, 'server.js')
});

svc.on('install', () => {
  svc.start();
});

svc.install();

Terminal 下 command 就安裝完成了

node install-windows-service.js

當然,也可以 uninstall

//uninstall-windows-service.js
const path = require('path');
const Service = require('node-windows').Service;

const svc = new Service({
  name: 'my-app',
  script: path.join(__dirname, 'server.js')
});

svc.on('uninstall', () => {
  console.log('Uninstall complete.');
  console.log('The service exists: ', svc.exists);
});

svc.uninstall();

install 的時候還能傳入環境變數

//install-windows-service.js
const svc = new Service({
  name: 'my-app',
  description: 'This is my app',
  script: path.join(__dirname, 'server.js'),
  env: [
    {
      name: "ENV",
      value: process.env.ENV || "poc"
    }
  ],
});

command 要改成如下,才能抓到環境變數

npx cross-env ENV=poc node install-windows-service.js

name: ‘my-app’,曾經以為安裝出來的 windows service 名稱就是 my-app,後來才發現 my-app 只是顯示名稱。

node-windows 裡面有一段 code 如下:

return require('./winsw').generateXml({
name: this.name,
id: this._exe
});

id 才是 windows service 的唯一值,而 id 並不是直接拿我們傳入的 name,而是這樣產生的:

name.replace(/[^\w]/gi, '').toLowerCase() + '.exe';

所以 name: ‘my-app’,安裝出來的 service 名稱實際上為 myapp.exe


除了使用 node-windows 來安裝部署成 windows service 以外,NSSM 以及 PM2 看起來也能做到同樣的事情,有機會再嘗試。

另外,除了安裝成 windows service,看起來也可以架在 IIS 上

參考資料
https://nextjs.org/docs/pages/building-your-application/deploying
https://nextjs.org/docs/pages/building-your-application/configuring/custom-server
https://medium.com/@deghtani/running-next-js-application-as-windows-service-553959f4de75

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *