本篇示範如何將自己開發的 Node.js 應用程式與 Linux 的 Systemd 服務管理系統者整合,提供正式的網路服務。

Node.js 應用程式在開發階段可能都是放在自己的個人電腦上面執行,等到程式開發完成之後,才會需要佈署至正式的 Linux 伺服器環境,而正式上線的服務跟開發用的環境是有差異的,以下介紹如何將 Node.js 應用程式整合進 Linux 標準的 Systemd 系統中,讓系統自動啟動並管理服務行程。


Systemd 是目前 Linux 系統上標準的服務管理系統,不熟悉 Systemd 的人建議可以參考 Systemd 基本使用教學與以及自訂服務教學

Node.js 應用程式

建立一個測試用的 Node.js 應用程式,然後將這段程式碼儲存於 /opt/my_node_app.js(或是其他任何自己喜歡的地方都可以):

const http = require('http');

const hostname = '0.0.0.0';
const port = process.env.NODE_PORT || 7000;

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write("Hello, world.");
  res.end();
});

server.listen(port, hostname, () => {
  console.log("Server running at http://" + hostname + ":" + port + "/");
});

建立好這個 Node.js 應用程式之後,先以手動啟動的方式,確認這個應用程式可以正常運作:

# 手動啟動 Node.js 應用程式
node /opt/my_node_app.js
Server running at http://0.0.0.0:7000/

預設它會在 7000 連接埠開啟一個網頁伺服器,以瀏覽器打開 http://localhost:7000/http://伺服器IP位址:7000/ 應該就可以看到 Hello, world. 的訊息文字。

整合 Node.js 與 Systemd

參考自訂服務教學,自己建立一個 Systemd 服務設定檔 /etc/systemd/system/my_node_app.service

[Unit]
After=network.target

# 服務名稱
Description=My Node.js App

[Service]
Type=simple

# 設定環境變數
Environment=NODE_PORT=3001 NODE_ENV=production

# 執行服務的使用者
User=ubuntu

# 啟動服務指令
ExecStart=/usr/bin/node /opt/my_app.js

# 不正常停止時重新啟動
Restart=on-failure

[Install]
WantedBy=multi-user.target

其中的 Environment 設定可以指定服務執行時的各種環境變數,這裡的 NODE_PORT 會傳入程式中,作為開啟的連接埠號碼,而 NODE_ENV=production 則是設定 Node.js 以 production 環境執行程式,可增加執行效率。

建立好設定檔之後,設定好權限:

sudo chmod 644 /etc/systemd/system/my_node_app.service

更動設定檔之後,要重新載入 Systemd 設定檔:

# 重新載入 Systemd 設定檔
sudo systemctl daemon-reload

接著就可以按照一般的 Systemd 操作方式,啟動自訂的 my_node_app 伺服器了:

# 啟動自訂的 my_node_app 伺服器
sudo systemctl start my_node_app

啟動後,檢查伺服器運行狀態:

# 查看伺服器狀態
systemctl status my_node_app
● my_node_app.service - My Node.js App
   Loaded: loaded (/etc/systemd/system/my_node_app.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2019-09-23 02:11:15 UTC; 3s ago
 Main PID: 28987 (node)
    Tasks: 7 (limit: 4915)
   CGroup: /system.slice/my_node_app.service
           └─28987 /usr/bin/node /opt/my_app.js

Sep 23 02:11:15 test-vm systemd[1]: Started My Node.js App.
Sep 23 02:11:15 test-vm node[28987]: Server running at http://0.0.0.0:3001/

若要停止伺服器,則執行:

# 停止 my_node_app 伺服器
sudo systemctl stop my_node_app

開機自動啟動的設定方式也都跟一般服務相同:

# 設定開機自動啟動 my_node_app 伺服器
sudo systemctl enable my_node_app

# 取消開機自動啟動 my_node_app 伺服器
sudo systemctl disable my_node_app

參考資料:NodeSourceSimon PrickettTibbo