在本節中,將創建一個Node.js的“Hello World”應用程序,并將該應用構建成Docker鏡像,并從容器啟動。正常情況下,該鏡像可以部署到生產服務器上,Docker Compose 將用于覆蓋一些設置以創建開發和調試環境。這樣可以在主機PC上進行編碼開發,這樣文件將在一個持續運行的容器中執行。這有幾個好處:

  • Docker 將管理所有依賴項—— 不需要安裝和維護runtimes
  • 這個過程與本地開發沒什么不同——可以使用任何喜歡的編輯器和工具
  • 容器是隔離的——應用程序影響到主機PC,如使刪除文件
  • 任何時候都可以將應用程序分發給其他開發人員或測試人員——應用程序可以在任何其他設備上以零配置相同的方式運行。

本節創建的代碼文件在項目 https://github.com/QuintionTang/docker-nodejs

基于容器的應用開發

Docker 簡化了 Web 開發:任何的 Web 應用程序都可以在單個容器中運行。

但是……如果想將類似的容器部署到實時生產服務器,應用程序通常是無狀態的。這樣可以啟動任意數量的實例,任何實例都可以對請求做出響應。實際上,應用程序不應該將基本狀態數據存儲在本地文件或內存中。

例如:當用戶登錄時,應用程序將登錄憑據存儲在內存中。在開發過程中使用單個容器,都可以按預期運行沒有問題。

如果將應用程序部署到生產服務器并在兩個以上容器中運行,這些容器通過負載均衡接收請求。用戶訪問系統由 container1 處理其登錄。那么下一個請求可能就由 container2 提供服務,容器之間并沒有共享登錄狀態,這個時候就會出現未登錄的情況。

當然上面的問題是可以通過解決的,為隔離的容器提供一個中心存儲服務,維護應用的持久化存儲數據,例如數據庫。

無狀態 Web 應用程序是一個不錯的方式。這樣在生產環境中隨著用戶情況的增加可以快速進行擴縮容,自動添加更多的機器/容器。在解決實際需求的時候就需要考慮是否適合無狀態,如果對有狀態的應用程序進行轉換可能是不可行的。

這些在開發過程中都無關緊要,因為通常只會在單個容器中運行應用程序。如果不實用,就不必在生產中使用容器。

什么是 Node.js

這個想必大部份掘金的小伙伴都知道,這里不展開介紹,引用一段簡單的說明。

Node.js 是一種流行的、高性能 JavaScript 運行時,使用 Chrome 瀏覽器的 V8 JavaScript 引擎構建。它通常用于服務器端 Web 開發,但也已被前端或客戶端用來構建工具、桌面應用程序、嵌入式系統等所采用。

安裝 Node.js 后,可以使用以下命令執行 JavaScript 文件:

node index.js

單入口腳本文件是什么?理論上它可以命名為任何名稱,通常項目都使用index.js 作為入口。

前面的內容一直在使用 Docker Hub 提供的 Docker 鏡像。本節將介紹如何構建自己的 Docker 鏡像,該鏡像可以在開發和生產環境中安裝和執行應用程序。

可能你對 Node.js 不感興趣,但是不管使用何種語言(PHP、Python、Ruby、Go、Rust等)都適合使用 Docker 。

Hello World應用概述

該項目將使用Node.js的Express.js框架創建了一個“Hello World”應用程序。

應用運行地址為:http://localhost:3000/,返回純文本格式:Hello World!

從客戶端 Ajax 請求調用相同的 URL 會返回 JSON 編碼的對象:

{ "message": "Hello World!" }

當傳入請求的HTTP 標頭設置為時,可以識別 Ajax 調用。這是由大多數 Ajax 庫添加了:X-Requested-WithXMLHttpRequest

可以向 URL 路徑添加字符串,例如http://localhost:3000/devpoint 將返回 Hello Devpint!,響應內容為:

{ "message": "Hello Devpoint!" }

項目初始化

在項目目錄中執行以下代碼初始化項目:

npm init

Docker 調試NODE應用

輸入基本的信息后,會在項目根目錄下生成 package.json

接下來安裝 express ,執行一下命令:

npm install express --save

為了開發過程中能夠響應代碼的變更,接下來安裝 Nodemon,執行以下命令:

npm install nodemon --save-dev

nodemo 用來監聽 node.js 項目中文件的更改并自動重啟服務的工具,接下來為項目增加監聽規則,如需要忽略的目錄:

{
    "script": "./index.js",
    "ext": "js json",
    "ignore": [
        "node_modules/"
    ],
    "legacyWatch": true,
    "delay": 200,
    "verbose": true
}

修改項目 package.json ,在scripts屬性下添加啟動命令:

"start": "node ./index.js",
"debug": "nodemon --trace-warnings --inspect=0.0.0.0:9229 ./index.js",

這樣在終端可以執行一下的命令:

  • npm start : 一般用于生產環境
  • npm run debug :用于開發調試

應用腳本 index.js

腳本在根路由下定義簡單的響應請求

"use strict";
const port = process.env.NODE_PORT || 3005, // 定義HTTP默認端口或者從NODE_PORT環境變量獲取
    express = require("express"),
    app = express();
// 根路由
app.get("/:title?", (req, res) => {
    const message = `Hello ${req.params.title || "Devpoint"}!`;
    if (req.xhr) {
        res.set("Access-Control-Allow-Origin", "*").json({ message });
    } else {
        res.send(message);
    }
});
// 啟動HTTP服務
app.listen(port, () => console.log(`server running on port ${port}`));

接下來開始執行腳本:

npm run debug

打開瀏覽器輸入http://localhost:3005/,可以看到響應的響應,如下

Docker 運行node應用效果

現在可以嘗試去修改腳本 index.js 的內容,當有更新的時候,終端會重啟服務,刷新瀏覽器即可看到更新。

docker 環境下調試node應用

到目前為止,一個簡單的NodeJS應用程序已經完成。接下來將介紹如何在Docker環境里面運行調試。

后續可以結合谷歌瀏覽器調試Node.js應用