Docker: Node.js

如何使用及部署 Node.js 應用程式與 Docker

👋 歡迎來到 Stackhero 文件!

Stackhero 提供一個即用型的 Docker cloud CaaS (Containers as a Service) 解決方案,帶來多種優勢,包括:

  • 只需 docker-compose up 即可輕鬆將您的容器部署到生產環境
  • 使用 HTTPS 保護的可自訂域名(例如,https://api.your-company.comhttps://www.your-company.comhttps://backoffice.your-company.com)。
  • 專用私有 VM提供的最佳性能和強大的安全性
  • 只需點擊即可輕鬆更新

節省時間簡化您的生活:只需 5 分鐘即可嘗試 Stackhero 的 Docker CaaS cloud hosting 解決方案,並將您的容器部署到生產環境!

本指南提供開發 Node.js 應用程式的堅實基礎,並快速輕鬆地將其部署到生產環境。

不需要事先了解 Docker。所有設置都已準備好以確保順暢的體驗;您只需在電腦上安裝 Docker。

此文件適合初學者和有經驗的用戶,想要使用現代、可擴展的技術來部署 Node.js 應用程式而不需要不必要的複雜性。

此解決方案的主要特點包括:

  • 💪 簡單設置,所需努力最小化
  • 🐳 使用 Docker 於開發和生產環境
  • 🔄 使用 nodemon 自動重新載入 Node.js 以應對代碼變更
  • 🚀 單指令部署到生產環境
  • 🔒 TLS 證書管理以確保 HTTPS 加密安全
  • 🚧 支援測試和預生產平台
  • 🧱 模組化和可擴展的架構

如果您的電腦尚未安裝 Docker,您可以從 Docker 官方網站下載。要驗證 Docker 是否正常運行,請打開終端並運行 docker version。您應該會看到版本信息而沒有任何錯誤。

安裝 Docker 後,克隆以下樣板庫:

git clone https://github.com/stackhero-io/nodejsWithDockerGettingStarted/
cd nodejsWithDockerGettingStarted

然後,通過運行 make development-start 啟動開發平台,或使用 make help 查看所有可用命令。

要啟動開發平台,請運行:

make development-start

此命令構建 Docker 映像,運行它,並執行在 my-app/package.json 中定義的 dev 腳本(相當於運行 npm run dev)。

在此示例中,創建了一個使用 Express 的簡單 REST API。您可以通過導航到 http://localhost:5000 查看 API。該頁面應顯示 "Hello World"。

接下來,在您喜歡的 IDE 中打開文件 my-app/src/app.js 並修改以下行:

res.send('Hello World');

將其更改為:

res.send('Updated!');

保存文件。Node.js 代碼將自動重新載入,刷新 http://localhost:5000 將反映更新的 API 響應。

恭喜您 - 您現在擁有一個完全運行的開發平台!

如果您需要安裝其他套件,可以運行 make development-shell 以訪問容器 shell。進入後,使用 NPM 與 npm install <package> 或 Yarn 與 yarn add <package> 安裝所需的套件。

如果您有一個現有的 Node.js 項目想要與 Docker 集成,請按照以下步驟操作:

  1. 在您的項目中創建一個名為 my-app 的新目錄。

  2. 將所有項目文件移動到 my-app 目錄中,排除 .gitignore.git 文件。

  3. 從樣板中將 dockersecretsMakefile 複製到項目的根目錄。

  4. 編輯項目中的 .gitignore 文件並添加以下行:

    node_modules/
    secrets/*.production
    secrets/*.staging
    

此樣板假設您的應用程式在端口 5000 上監聽。如果您偏好其他端口,可以編輯 docker/docker-compose.development.yml 文件,然後使用 make development-start 重新啟動環境。

如果您希望指定不同的 Node.js 版本,請按照以下步驟操作:

  1. 打開文件 docker/my-app.dockerfile,該文件定義了應用程式的 Docker 映像。
  2. 找到第一行 FROM node:<version>-alpine
  3. <version> 替換為您選擇的 Node.js 版本。建議使用長期支持 (LTS) 版本。您可以在 Node.js 網站上查看最新的 LTS 版本。例如,要使用最新的 LTS 版本(目前是 22),將該行更新為 FROM node:22-alpine。如果您偏好特定版本號,可以使用類似 FROM node:22.13.0-alpine 的格式。
  4. 保存對 Dockerfile 的更改。

在文件 secrets/my-app.development 中為開發平台設置環境變數。

對於生產環境,使用 secrets/my-app.production 文件。

不要將 secrets/my-app.production 文件提交到您的 Git 儲存庫!此文件包含敏感信息,並在樣板的 .gitignore 中默認忽略以防止意外共享。

如果您的 Node.js 應用程式需要存儲文件(例如用戶上傳),考慮使用像 MinIO 這樣的對象存儲服務。對象存儲服務有助於您的應用程式無縫擴展,同時減少潛在問題。

如果您偏好本地存儲文件,請確保始終使用 Docker 卷。直接在容器中存儲文件可能導致 數據丟失。此樣板提供了一個掛載在 /persistent 的卷以安全存儲文件。

除非您創建了自定義卷並確信配置,否則不要在 /persistent 目錄之外存儲持久數據。/persistent 之外存儲文件將導致數據丟失!

您可以輕鬆修改此樣板以添加測試環境。要這樣做:

  1. 創建 docker/docker-compose.production.yml 的副本並將其命名為 docker/docker-compose.staging.yml。此文件定義了測試環境的容器和配置。
  2. 創建包含測試所需的任何敏感信息的秘密文件 secrets/my-app.staging,例如數據庫密碼或 API 密鑰。
  3. Makefile 中,找到標記為 "Staging platform" 的部分並取消註釋。

最後,運行 make help 查看現在可用的新測試命令。

如果您尚未擁有 Stackhero for Docker 服務,您可以從您的 Stackhero 儀表板輕鬆創建一個。它將在大約 2 分鐘內激活。

如果您是 Stackhero 的新用戶,您可以免費試用 Docker 容器雲託管 一個月。

在將應用程式部署到生產環境之前,您需要準備一些配置文件:

  1. secrets/global.production.example 複製到 secrets/global.production
  2. 編輯 secrets/global.production 並將 <XXXXXX>.stackhero-network.com 替換為來自 Stackhero 儀表板的 Docker 服務主機名。
  3. secrets/my-app.production.example 複製到 secrets/my-app.production
  4. 編輯 secrets/my-app.production 並插入您的憑證。
  5. 更新 docker/docker-compose.production.yml,將 <XXXXXX>.stackhero-network.com 替換為您的 Docker 服務主機名。

部署到生產環境很簡單:運行:

make production-deploy

此命令創建 Docker 容器,傳輸您的項目數據,並將其發送到生產環境中的 Docker 服務。打開瀏覽器並導航到您的 Docker 服務主機名(例如,https://<XXXXXX>.stackhero-network.com)。您應該看到您的 REST API 回應 "Hello World"。

您也可以使用 make production,它會部署您的容器並顯示實時日誌。

要監控您的生產環境或排除故障,您可以使用以下命令查看日誌:

  • 要流式傳輸實時日誌,運行:make production-logs-live
  • 要檢索所有存儲的日誌,運行:make production-logs
  • 要檢索特定日期的日誌(將 YYYY-MM-DD 替換為所需日期),運行:make production-logs | grep "YYYY-MM-DD"

如果您希望使用不同於 https://<XXXXXX>.stackhero-network.com 的域名,Stackhero for Docker 集成了 Traefik 以簡化域名管理。Traefik 為您處理 HTTP 路由和 TLS 加密(HTTPS)。

以下是自定義域名的幾個示例:

  • 要通過您的容器 my-app 在端口 5000 上提供 api.my-company.com 並使用 TLS 加密,請更新 docker/docker-compose.production.yml 文件,將 labels 部分替換為:

        labels:
          - "traefik.enable=true" # 啟用 Traefik 以路由流量到此容器
          - "traefik.http.routers.my-app.rule=Host(`api.my-company.com`)" # 定義主機
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt" # 使用 letsencrypt 獲取 TLS 證書
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # 指定端口 5000
    
  • 要通過您的容器 my-app 在端口 5000 上提供 my-company.com 並將所有來自 www.my-company.com 的請求重定向到 my-company.com,請在同一文件中更新 labels 部分:

        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.my-app.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # 包含兩個域名
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # 指定端口 5000
    
          # 將 www.my-company.com 重定向到 my-company.com:
          - "traefik.http.routers.my-app.middlewares=redirect-www"
          - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
          - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
          - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
    

不要忘記為 my-company.comwww.my-company.com 配置 DNS,以便每個都指向您的 Docker 服務的 CNAME https://<XXXXXX>.stackhero-network.com