次の方法で共有


Azure Container Apps 上の JavaScript の概要

Azure Container Apps では、コンテナー化された JavaScript アプリケーションをクラウドで実行しながら、アプリケーションのデプロイ方法に関する柔軟なオプションを提供できます。

コンフィギュレーション

Azure Container Apps を使用すると、環境変数の設定、効率的な Dockerfile の設計、アプリケーションのビルド プロセスの整理など、効果的なコンテナー化によって JavaScript アプリケーションのデプロイを合理化できます。

環境変数

環境変数は、アプリケーションの構成に不可欠です。 .env ファイルを使用して、これらの変数をローカルで管理し、Azure Key Vault などのサービスを使用して運用環境で安全に管理されるようにします。

次の例は、アプリケーションの変数を作成する方法を示しています。

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

Containers

適切に構成された Dockerfile は、アプリケーションをコンテナー化するために不可欠です。

  • 基本 Dockerfile を使用する: 複数のプロジェクトが共通のセットアップを共有している場合は、これらの一般的な手順を含む基本 Dockerfile を作成できます。 各プロジェクトの Dockerfile は、この基本イメージ FROM から開始し、プロジェクト固有の構成を追加できます。

  • ビルド引数のパラメーター化: Dockerfile でビルド引数 (ARG) を使用して、柔軟性を高めることができます。 これにより、開発、ステージング、または運用環境用にビルドするときに、これらの引数に異なる値を渡すことができます。

  • 最適化された Node.js 基本イメージ: 適切な Node.js 基本イメージを使用していることを確認します。 オーバーヘッドを減らすために、Alpine バリアントなどの最適化された小さな画像を使用することを検討してください。

  • 最小限のファイル – 要点のみをコピーする: 必要なファイルのみをコンテナーにコピーすることに重点を置きます。 .dockerignore ファイルを作成して、.envnode_modules などの開発ファイルがコピーされないようにします。 このファイルは、開発者が不要なファイルにコピーした場合にビルドを高速化するのに役立ちます。

  • 複数ステージ ビルドを使用してビルドとランタイムを分離する: ビルド環境をランタイム環境から分離することで、マルチステージ ビルドを使用してリーン最終イメージを作成します。

  • コンパイルとバンドルによる成果物のビルド前: ランタイム ステージにコピーする前にアプリケーション成果物 (TypeScript のコンパイルや JavaScript のバンドルなど) を事前構築すると、イメージ サイズを最小限に抑え、コンテナーのデプロイを高速化し、コールド スタートのパフォーマンスを向上させることができます。 Dockerfile で命令を慎重に順序付けすると、キャッシュと再構築の時間も最適化されます。

  • 開発環境用の Docker Compose: Docker Compose を使用すると、複数コンテナーの Docker アプリケーションを定義して実行できます。 このマルチコンテナー アプローチは、開発環境の設定に役立ちます。 作成ファイルには、ビルド コンテキストと Dockerfile を含めることができます。 このレベルのカプセル化により、必要に応じて異なるサービスに異なる Dockerfile を使用できます。

基本 Dockerfile

このファイルは、Node.js イメージの共通の開始点として機能します。 この基本イメージを参照する Dockerfile の 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 .

この例では、環境変数 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

Production 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 レジストリを使用する場合は、レジストリにサインインし、Azure Container Registry (ACR) や Docker Hub などのコンテナー レジストリに Docker イメージをプッシュします。

# 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 フォルダーをスリムに保ちます。 dependenciespackage.json セクションに開発依存関係やテスト依存関係を一覧表示しないでください。 未使用の依存関係を削除し、 package.json とロック ファイルの一貫性を維持します。

セキュリティ

Azure Container Apps を使用する JavaScript 開発者のセキュリティに関する考慮事項には、環境変数 (Azure Key Vault の使用など) のセキュリティ保護、適切な証明書管理による HTTPS の確保、定期的な監査による up-to-date 依存関係の維持、脅威の迅速な検出と対応のための堅牢なログ記録と監視の実装が含まれます。

環境変数をセキュリティで保護する

データベース接続文字列や 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 portal で カスタム ドメイン と証明書を構成します。

依存関係の管理

セキュリティの脆弱性を回避するために、依存関係を定期的に更新します。 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 を使用してシャットダウン信号を適切に処理する 1 つの方法を示します。

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 Container Apps では、 console.log 呼び出しと console.error 呼び出しの両方が自動的にキャプチャされ、ログに記録されます。 Azure Container Apps は、アプリケーションから標準出力 (stdout) ストリームと標準エラー (stderr) ストリームをキャプチャし、Azure Monitor と Log Analytics で使用できるようにします。

Azure Container Apps でのログ記録の設定

ログが適切にキャプチャされ、アクセス可能であることを確認するには、Azure Container App の診断設定を構成する必要があります。 セットアップは 2 段階のプロセスです。

  1. 診断設定を有効にする: Azure CLI を使用して、Azure Container App の診断設定を有効にします。

    このコマンドを実行する前に、 <> で囲まれたプレースホルダーを実際の値に置き換えてください。

    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にデバッグ設定をハードコーディングする代わりに、コンテナーのエントリ ポイントとしてシェル スクリプトを使用してリモート デバッグを動的に有効にすることができます。

次のスクリプトは、コンテナーの起動時に環境変数 (たとえば、 ENABLE_DEBUG) を確認します。 変数が true に設定されている場合、スクリプトは ( --inspect または --inspect-brk を使用して) デバッグ モードで Node.js を起動します。 それ以外の場合、コンテナーはアプリケーションを正常に起動します。

リモート デバッグは、次の手順で実装できます。

  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_DEBUGtrueに設定して、デバッグ モードをトリガーします。 たとえば、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

Scaling

アプリケーションの負荷に基づいて自動スケールを構成します。 Azure Container Apps では、水平方向のスケーリングがサポートされています。これは、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 Container Apps でアプリケーションの実行時の問題が発生した場合は、ログ記録、リモート デバッグ、正常性チェックアラートを使用して問題を見つけて解決できます。

ログ記録

アプリケーション ログをキャプチャするためのログ記録を有効にして構成します。 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 Container Apps が応答しなくなった場合にコンテナーを再起動できます。

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