Azure 容器应用可以在云中运行任何容器化的 JavaScript 应用程序,同时提供灵活选项来部署应用程序。
配置
借助 Azure 容器应用,可以通过有效的容器化简化 JavaScript 应用程序的部署,包括设置环境变量、设计高效的 Dockerfiles 以及组织应用程序的生成过程。
环境变量
环境变量对于配置应用程序至关重要。 .env
使用文件在本地管理这些变量,并确保在生产环境中使用 Azure Key Vault 等服务安全地管理这些变量。
以下示例演示如何为应用程序创建变量。
# .env
NODE_ENV=production
PORT=3000
AZURE_COSMOS_DB_ENDPOINT=https://<YOUR_COSMOSDB_RESOURCE_NAME>.documents.azure.cn:443/
容器
配置良好的 Dockerfile 对于容器化应用程序至关重要:
使用基本 Dockerfile:如果多个项目共享一个通用设置,则可以创建包含这些常见步骤的基本 Dockerfile。 然后,每个项目的 Dockerfile 都可以以此基本映像
FROM
开始,并添加特定于项目的配置。生成参数的参数化:可以使用 Dockerfile 中的生成参数(
ARG
)使其更加灵活。 这样,您可以在构建开发环境、测试环境或生产环境时为这些参数传入不同的值。优化 Node.js 基础映像:确保使用适当的 Node.js 基础映像。 为了减少开销,请考虑使用更小的经过优化的映像(例如 Alpine 变体)。
最小文件 - 仅复制基本文件:专注于仅将必要的文件复制到容器中。 创建一个
.dockerignore
文件,以确保开发文件不会被复制到例如.env
和node_modules
中。 此文件有助于加快编译速度,尤其是在开发人员复制不必要的文件的情况下。使用多阶段构建分离构建和运行时:通过将构建环境与运行时环境分开来创建精简的最终映像。
通过编译和捆绑预构建项目:在将项目复制到运行时阶段之前,预构建应用程序项目(例如编译 TypeScript 或捆绑 JavaScript),可以最大程度地减小映像大小、加快容器部署并提高冷启动性能。 在 Dockerfile 中仔细排序说明也会优化缓存和重新生成时间。
Docker Compose 用于开发环境:Docker Compose 允许您定义和运行多容器的 Docker 应用程序。 此多容器方法可用于设置开发环境。 可以在 Compose 文件中包括构建上下文和 Dockerfile。 这种封装级别允许在必要时为不同的服务使用不同的 Dockerfile。
基本 Dockerfile
此文件用作 Node.js 映像的常见起点。 可以在引用此基本映像的 Dockerfiles 中将它与 FROM
指令一起使用。 可以使用版本号或提交记录来指定映像的最新安全版本。
# 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 .
在此示例中,环境变量 PORT
设置为 ENABLE_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 注册表时,登录到注册表,然后将 Docker 映像推送到容器注册表,例如 Azure 容器注册表(ACR)或 Docker 中心。
# Tag the image
docker tag \
<IMAGE>:<TAG> \
<AZURE_REGISTRY>.azurecr.cn/<IMAGE>:<TAG>
# Push the image
docker push <AZURE_REGISTRY>.azurecr.cn/<IMAGE>:<TAG>
冷启动
通过只包含必要的代码和依赖项来优化生产构建。 若要确保有效负载尽可能精简,请使用以下方法之一:
多阶段 Docker 生成或捆绑程序:使用生成和捆绑工具(如 Webpack 或汇总)来帮助为容器创建最小的有效负载。 仅编译和捆绑生产所需的内容,有助于最大程度地减少容器大小,并帮助改善冷启动时间。
仔细管理依赖项:
node_modules
仅包括运行生产代码所需的包,使文件夹保持精简。 请勿在package.json
的dependencies
部分中列出开发或测试依赖项。 删除任何未使用的依赖项,并确保你的package.json
和锁定文件保持一致。
安全
使用 Azure 容器应用的 JavaScript 开发人员的安全注意事项包括保护环境变量(例如使用 Azure Key Vault)、确保 HTTPS 与适当的证书管理、使用定期审核维护 up-to日期依赖项,以及实现可靠的日志记录和监视,以快速检测和响应威胁。
保护环境变量
确保安全地存储数据库连接字符串和 API 密钥等敏感信息。 使用 Azure Key Vault 安全地管理机密和环境变量。
在运行此命令之前,请确保将用 <>
括起来的占位符替换为你的值。
az keyvault secret set \
--vault-name <KEY_VAULT_APP> \
--name "<SECRET_NAME>" \
--value "<CONNECTION_STRING>"
HTTPS 和证书
确保通过 HTTPS 提供应用程序。 Azure 容器应用可以为你管理 证书 。 在 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 和 Log Analytics 中提供它们。
在 Azure 容器应用中设置日志记录
若要确保正确捕获和访问日志,需要为 Azure 容器应用配置诊断设置。 设置是一个两个步骤的过程。
启用诊断设置:使用 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}]'
在门户中访问日志,可以转到 Log Analytics 工作区并查询日志。
使用日志记录库
console.log
和 console.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 的内置检查器。 可以使用 shell 脚本作为容器的入口点来动态启用远程调试,而不是将调试设置硬编码到 Dockerfile CMD
中。
以下脚本在容器启动时检查环境变量(例如 ENABLE_DEBUG
)。 如果变量设置为 true
,脚本将在调试模式下启动 Node.js(使用 --inspect
或 --inspect-brk
)。 否则,容器通常会启动应用程序。
可以使用以下步骤实现远程调试:
在项目根目录下命名
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
修改 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"]
通过将环境变量
ENABLE_DEBUG
设置为true
来触发调试模式。 例如,使用 Azure CLI:az containerapp update \ --name <CONTAINER_APP> \ --env-vars ENABLE_DEBUG=true
在运行此命令之前,请确保用您的值替换 <>
所围绕的占位符。
此方法提供了一种灵活的解决方案,通过更新启动时的环境变量,可以在调试模式下重启容器。 这避免了每次需要调试应用程序时,都要通过不同的 CMD
设置创建新的修订。
维护和性能注意事项
若要在一段时间内维护和优化应用程序的性能,请确保有效地管理环境变量更改、监视资源、保持依赖项 up-to日期、正确配置缩放以及设置监视警报。
环境变量更改
由于对环境变量的每次更改都需要一个新部署的修订版本,请一次性更改应用程序的所有密钥。 更改完成后,将机密链接到修订的环境变量。 此方法可最大程度地减少修订数,并帮助维护干净的部署历史记录。
资源分配
根据应用程序的性能和使用模式监视和调整容器的 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 容器应用 扩展直接从 Visual Studio Code 快速创建、编辑和部署容器化应用。
故障排除
当应用程序在 Azure 容器应用中遇到运行时问题时,可以使用日志记录、远程调试和运行状况检查警报来查找和解决问题。
伐木业
启用和配置日志记录以捕获应用程序日志。 使用 Azure Monitor 和 Log Analytics 收集和分析日志。 在运行这些命令之前,请确保将用 <>
括起来的占位符替换为你的值。
创建新工作区。
az monitor log-analytics workspace create \ --resource-group <RESOURCE_GROUP> \ --workspace-name <WORKSPACE_NAME>
然后创建新的工作区设置。
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