共用方式為


Azure 容器應用程式中的 JavaScript 概覽

Azure 容器應用程式可以在雲端執行任何容器化的 JavaScript 應用程式,並提供靈活的應用程式部署選項。

設定

Azure 容器應用程式透過有效的容器化,協助你簡化 JavaScript 應用程式的部署,包括設定環境變數、設計高效的 Dockerfile,以及組織應用程式的建置流程。

環境變數

環境變數對於設定你的應用程式至關重要。 使用 .env 檔案在本地管理這些變數,並確保它們在生產環境中透過像 Azure Key Vault 這樣的服務安全管理。

以下範例說明如何為你的應用程式建立變數。

# .env
NODE_ENV=production
PORT=3000
AZURE_COSMOS_DB_ENDPOINT=https://<YOUR_COSMOSDB_RESOURCE_NAME>.documents.azure.com:443/

容器

一個配置良好的 Dockerfile 對於容器化你的應用程式至關重要:

  • 使用基礎 Dockerfile:如果多個專案共用相同設定,您可以建立包含這些共通步驟的基礎 Dockerfile。 每個專案的 Dockerfile 可以從 FROM 這個基礎映像開始,並加入專案專屬的設定。

  • 建置參數化:你可以在 Dockerfile 中使用建構參數ARG()來增加彈性。 如此一來,在開發、測試或生產時,你可以為這些參數輸入不同的數值。

  • 優化 Node.js 底鏡像:確保你使用的是合適的 Node.js 底鏡像。 請考慮使用較小且最佳化的映像,例如 Alpine 變體,以降低負擔。

  • 檔案量最小——只複製必要內容:專注於只複製必要的檔案到你的容器中。 建立一個 .dockerignore 檔案,以確保開發檔案不會被複製,例如 .envnode_modules。 此檔案有助於加速開發者複製不必要的檔案時的建置速度。

  • 多階段建置分離建置與執行時:利用多階段建置將建置環境與執行環境分離,建立精簡的最終映像。

  • 透過編譯與捆綁預先建構構件:在將應用程式產件(如編譯 TypeScript 或打包 JavaScript)前,先將它們複製到執行階段,可以減少映像檔大小、加速容器部署並提升冷啟動效能。 在 Dockerfile 中仔細排序指令也能優化快取和重建時間。

  • 開發環境用 Docker Compose:Docker Compose 允許你定義並執行多容器 Docker 應用程式。 這種多容器方法對於建立開發環境非常有用。 你可以在 compose 檔案中包含建置上下文和 Dockerfile。 這種封裝層級允許你在必要時為不同服務使用不同的 Dockerfile。

基礎 Dockerfile

這個檔案是你 Node.js 影像的共通的起始點。 您可以在 Dockerfile 中使用 FROM 指示詞來參考此基礎映像。 請使用版本號碼或 Commit,以支援映像的最新且安全版本。

# Dockerfile.base

FROM node:22-alpine

# Set the working directory
WORKDIR /usr/src/app

# Define build arguments with default values
ARG PORT_DEFAULT=3000
ARG ENABLE_DEBUG_DEFAULT=false

# Set environment variables using the build arguments
ENV PORT=${PORT_DEFAULT}
ENV ENABLE_DEBUG=${ENABLE_DEBUG_DEFAULT}

# Copy package manifests and install dependencies
COPY package*.json ./
RUN npm install

# Expose the application and debugging ports
EXPOSE $PORT
EXPOSE 9229

# This image focuses on common steps; project-specific Dockerfiles can extend this.

當你在建置過程中用 --build-arg 旗標傳遞值時,輸入的值會覆蓋你 Dockerfile 裡硬編碼的預設值。

例如:

docker build \
  --build-arg PORT_DEFAULT=4000 \
  --build-arg ENABLE_DEBUG_DEFAULT=true \
  --tag <IMAGE>:<TAG> \
  --file Dockerfile.base .

在此範例中,環境變數 PORTENABLE_DEBUG 被設定為明確值,而非預設值。

容器影像標籤的慣例,例如使用 , latest 就是一種慣例。 了解更多 關於容器映像標籤與版本管理的建議

使用 Docker Compose 建立開發環境

以下範例組態使用專用的開發 Dockerfile (Dockerfile.dev),並搭配磁碟區掛載以支援即時重新載入與本機來源同步。

version: "3.8"
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.base
      args:
        PORT_DEFAULT: ${PORT:-3000}
        ENABLE_DEBUG_DEFAULT: ${ENABLE_DEBUG:-false}
    ports:
      - "${PORT:-3000}:3000"
      - "9229:9229"  # Expose debug port if needed
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules
    environment:
      - NODE_ENV=development
      - PORT=${PORT:-3000}
      - ENABLE_DEBUG=${ENABLE_DEBUG:-false}

要用自訂值啟動 Docker Compose,可以在命令列匯出環境變數。 例如:

PORT=4000 ENABLE_DEBUG=true docker compose up

生產環境 Dockerfile

這個多階段的 Dockerfile 會建置你的應用程式並產生精簡的執行時映像檔。 確保你的 .dockerignore 檔案已經在原始碼裡,這樣指令 COPY . . 就不會複製到任何你在生產環境中不需要的開發環境特定檔案。

# Stage 1: Builder
FROM node:22 AS build

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .

# Build your project (e.g., compile TypeScript or bundle JavaScript)
RUN npm run build

# Stage 2: Runtime
FROM my-base-image:latest AS runtime

WORKDIR /usr/src/app

# Copy only the compiled output and essential files from the build stage
COPY --from=build /usr/src/app/dist ./dist
COPY --from=build /usr/src/app/package*.json ./

# Install only production dependencies
RUN npm ci --omit=dev

# Copy the entrypoint script for remote debugging
COPY entrypoint.sh /usr/src/app/entrypoint.sh
RUN chmod +x /usr/src/app/entrypoint.sh

# Expose the application port (using the PORT environment variable) and the debug port (9229)
EXPOSE $PORT
EXPOSE 9229

# Use the entrypoint script to conditionally enable debugging
ENTRYPOINT ["sh", "/usr/src/app/entrypoint.sh"]

入口腳本允許你連接容器應用程式進行 遠端除錯

若要從建置好的生產映像檔中執行容器,並使用自訂環境變數,執行:

docker run \
  --env PORT=4000 \
  --env ENABLE_DEBUG=true \
  --publish 4000:4000 \
  --publish 9229:9229 \
  <IMAGE>:<TAG>

對於生產版本,請確保使用正確的版本標籤,但這可能不是 latest。 容器影像標籤的慣例,例如使用 , latest 就是一種慣例。 了解更多 關於容器映像標籤與版本管理的建議

部署

為了支援持續整合/持續部署(CI/CD),請使用 GitHub Actions、Azure DevOps 或其他 CI/CD 工具建立 CI/CD 管線,以自動化部署流程。

# .github/workflows/deploy.yml
name: Deploy to Azure

on:
push:
    branches:
    - main

jobs:
build-and-deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
          node-version: '22'

    - name: Install dependencies
      run: npm ci

    - name: Build the app
      run: npm run build

    - name: Log in to Azure
      uses: azure/login@v2
      with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

    - name: Deploy to Azure Container Apps
      run: |
          az containerapp up \
          --name my-container-app \
          --resource-group my-resource-group \
          --image my-image:my_tag \
          --environment my-environment \
          --cpu 1 --memory 2Gi \
          --env-vars NODE_ENV=production PORT=3000

使用 Docker Registry 時,先登入你的登錄檔,然後將 Docker 映像推送到像 Azure Container Registry(ACR)或 Docker Hub 這類容器登錄檔。

# Tag the image
docker tag \
  <IMAGE>:<TAG> \
  <AZURE_REGISTRY>.azurecr.io/<IMAGE>:<TAG>

# Push the image
docker push <AZURE_REGISTRY>.azurecr.io/<IMAGE>:<TAG>

冷啟動

請僅包含必要的程式碼與相依性,以最佳化您的生產環境建置。 為確保您的承載盡可能精簡,請使用下列其中一種方法:

  • 多階段 Docker 建置或捆綁器:使用像 Webpack 或 Rollup 這類建置與打包工具,幫助你為容器打造最小的有效載荷。 當你只彙整並打包生產所需的資料時,你有助於縮小容器大小,並幫助改善冷啟動時間。

  • 謹慎管理相依: 保持 node_modules 資料夾精簡,只包含執行生產程式碼所需的套件。 不要在你的 package.jsondependencies 區段中列出開發或測試依賴項。 移除所有未使用的相依性,並確保你的package.json和鎖定檔保持一致。

安全性

使用 Azure 容器應用程式的 JavaScript 開發者需注意的安全措施包括保護環境變數(如使用 Azure Key Vault)、確保 HTTPS 並妥善管理憑證、進行定期依賴性稽核以保持相依關係更新,以及實施強化的日誌記錄與監控,以便迅速偵測和回應威脅。

安全環境變數

確保敏感資訊如資料庫連接字串和 API 金鑰安全儲存。 使用 Azure Key Vault 來安全地管理秘密和環境變數。

執行這個指令前,務必將周圍 <> 的佔位符換成你的值。

az keyvault secret set \
  --vault-name <KEY_VAULT_APP> \
  --name "<SECRET_NAME>" \
  --value "<CONNECTION_STRING>"

HTTPS 與憑證

請確保您的申請是透過 HTTPS 送達。 Azure Container Apps 可以幫你管理 憑證 。 在 Azure 入口網站中設定 你的自訂網域 和憑證。

相依性管理

定期更新你的相依系統,以避免安全漏洞。 使用像npm audit這樣的工具來檢查漏洞。

npm audit

錯誤處理

在您的 Node.js 應用程式中實作穩健的錯誤處理。 在 Express 或 Fastify 中使用中介軟體來優雅地處理錯誤。

// src/middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';

export function errorHandler(err: any, req: Request, res: Response, next: NextFunction) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
}

優雅關閉

正確關閉您的應用程式至關重要,可確保處理中的要求完成,並正確釋放資源。 這有助於防止資料遺失,並在部署或擴充活動期間維持流暢的使用者體驗。 以下範例展示了利用 Node.js 和 Express 優雅處理關機訊號的一種方法。

import express from 'express';
import healthRouter from './health.js';

const app = express();

app.use(healthRouter);

const server = app.listen(process.env.PORT || 3000);

// Graceful shutdown
process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down...');
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });

  // Force close after 30s
  setTimeout(() => {
    console.error('Could not close connections in time, forcing shutdown');
    process.exit(1);
  }, 30000);
});

森林伐木業

在 Azure 容器應用程式中, console.log 通話 console.error 會自動被擷取並記錄。 Azure 容器應用程式會擷取你應用程式的標準輸出(stdout)和標準誤差(stderr)串流,並提供在 Azure Monitor 和日誌分析中。

在 Azure 容器應用程式中設定記錄

為了確保你的日誌被正確擷取並可存取,你需要為 Azure 容器應用程式設定診斷設定。 設定是一個兩步驟的過程。

  1. 啟用診斷設定:使用 Azure CLI 來啟用 Azure 容器應用程式的診斷設定。

    執行這個指令前,務必將周圍 <> 的佔位符換成你的值。

    az monitor diagnostic-settings create \
    --resource /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Web/containerApps/<CONTAINER_APP_NAME> \
    --name "containerapp-logs" \
    --workspace <LOG_ANALYTICS_WORKSPACE_ID> \
    --logs '[{"category": "ContainerAppConsoleLogs","enabled": true}]'
    
  2. 在入口網站中存取日誌,方法是前往你的 Log Analytics 工作區查詢日誌。

使用記錄程式庫

雖然 console.logconsole.error 會自動被擷取,但使用 Winston 這類日誌庫能提供更多彈性與控制。 這種彈性讓你能格式化日誌、設定日誌等級,並將日誌輸出到多個目的地,如檔案或外部日誌服務。

以下範例示範如何設定 Winston 以儲存高保真度日誌。

// src/logger.ts
import { createLogger, transports, format } from 'winston';

const logger = createLogger({
  level: 'info',
  format: format.combine(
    format.timestamp(),
    format.json()
  ),
  transports: [
    new transports.Console(),
    new transports.File({ filename: 'app.log' })
  ]
});

export default logger;

要使用記錄器,請在你的應用程式中使用以下語法:

import logger from './logger';

logger.info('This is an info message');
logger.error('This is an error message');

遠端偵錯

要啟用遠端除錯,可以使用 Node 內建的檢查器。 你不用把除錯設定硬編碼進 Dockerfile CMD裡,而是可以用 shell 腳本作為容器的入口,動態啟用遠端除錯。

以下腳本會在容器啟動時檢查環境變數(例如 ENABLE_DEBUG)。 若變數設為 true,腳本會以除錯模式啟動 Node.js(使用 --inspect--inspect-brk)。 否則,容器會正常啟動應用程式。

你可以透過以下步驟實作遠端除錯:

  1. 在專案根目錄 entrypoint.sh 命名的檔案中建立一個入口腳本,內容如下:

    #!/bin/sh
    # If ENABLE_DEBUG is set to "true", start Node with debugging enabled
    if [ "$ENABLE_DEBUG" = "true" ]; then
      echo "Debug mode enabled: starting Node with inspector"
      exec node --inspect=0.0.0.0:9229 dist/index.js
    else
      echo "Starting Node without debug mode"
      exec node dist/index.js
    fi
    
  2. 修改你的 Dockerfile 將腳本複製 entrypoint.sh 到容器,並設定它作為入口點。 另外,如果需要,也要公開除錯埠:

    # Copy the entrypoint script to the container
    COPY entrypoint.sh /usr/src/app/entrypoint.sh
    
    # Ensure the script is executable
    RUN chmod +x /usr/src/app/entrypoint.sh
    
    # Expose the debugging port (if using debug mode)
    EXPOSE 9229
    
    # Set the shell script as the container’s entrypoint
    ENTRYPOINT ["sh", "/usr/src/app/entrypoint.sh"]
    
  3. 透過將環境變數 ENABLE_DEBUG 設為 true來觸發除錯模式。 例如,使用 Azure CLI:

    az containerapp update \
      --name <CONTAINER_APP> \
      --env-vars ENABLE_DEBUG=true
    

執行這個指令前,務必將周圍 <> 的佔位符換成你的值。

這種方法提供了一種彈性的解決方案,允許你在啟動時更新環境變數,以除錯模式重新啟動容器。 這樣可避免每次需要偵錯應用程式時,都必須以不同的 CMD 設定建立新的修訂版本。

維護與性能考量

為了長期維護並優化應用程式的效能,請確保你有效管理環境變數的變更、監控資源、保持相依性更新、正確配置擴展機制,並設定監控警示。

環境變數變更

由於每次環境變數的變更都需要新的部署版本,所以請一次對應用程式的所有秘密進行修改。 變更完成後,將秘密連結到版本的環境變數。 此方法減少修訂次數,並有助於維持部署歷史的乾淨。

資源配置

根據應用程式的效能與使用模式,監控並調整容器的 CPU 與記憶體配置。 過度配置可能導致不必要的成本,而配置不足則可能導致效能問題。

相依性更新

請定期更新您的相依性,以獲得效能改進與安全性修補。 使用像 npm-check-updates 這樣的工具來自動化這個流程。

npm install -g npm-check-updates
ncu -u
npm install

調整大小

根據應用程式的負載設定自動縮放。 Azure 容器應用程式支援水平縮放,會根據 CPU 或記憶體使用率自動調整容器實例數量。

以下範例示範如何設定基於 CPU 的擴展規則。 執行這個指令前,務必將周圍 <> 的佔位符換成你的值。

az containerapp revision set-scale \
  --name <CONTAINER_APP> \
  --resource-group <RESOURCE_GROUP> \
  --min-replicas 1 \
  --max-replicas 10 \
  --cpu 80

監視警示

設置監控與警示,追蹤應用程式的效能與健康狀況。 使用 Azure Monitor 來針對特定指標(如 CPU 使用率、記憶體使用率和回應時間)建立警示。

執行這個指令前,務必將周圍 <> 的佔位符換成你的值。

az monitor metrics alert create \
  --name "HighCPUUsage" \
  --resource-group <RESOURCE_GROUP> \
  --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.ContainerInstance/containerGroups/<CONTAINER_GROUP> \
  --condition "avg Percentage CPU > 80" \
  --description "Alert when CPU usage is above 80%"

資源管理

使用 Visual Studio Code 的 Azure Container Apps 擴充功能,直接從 Visual Studio Code 快速建立、編輯並部署容器化應用程式。

故障排除

當你的應用程式在 Azure 容器應用程式中遇到執行時問題時,你可以利用日誌記錄、遠端除錯和健康檢查警示來找出並解決問題。

森林伐木業

啟用並設定日誌以擷取應用程式日誌。 使用 Azure Monitor 和 Log Analytics 來收集和分析日誌。 執行這些指令前,務必將周圍 <> 的佔位符換成你的值。

  1. 建立新工作區。

    az monitor log-analytics workspace create \
        --resource-group <RESOURCE_GROUP> \
        --workspace-name <WORKSPACE_NAME>
    
  2. 然後建立一個新的工作區設定。

    az monitor diagnostic-settings create \
        --resource <CONTAINER_APP> \
        --workspace <WORKSPACE_NAME> \
        --logs '[{"category": "ContainerAppConsoleLogs","enabled": true}]'
    

偵錯

你用 遠端除錯 工具連接正在運行的容器。 確保你的 Dockerfile 有公開除錯所需的埠口。

# Expose the debugging port
EXPOSE 9229

健康檢查

設定健康檢查以監控應用程式的健康狀況。 此功能確保 Azure 容器應用程式能在容器失去回應時重新啟動。

# Azure Container Apps YAML configuration
properties:
configuration:
    livenessProbe:
    httpGet:
        path: /health
        port: 3000
    initialDelaySeconds: 30
    periodSeconds: 10