目次

AWS App Runner 完全ガイド v2.0

初心者から実務者向けの包括的解説

AWS App Runner は、「コンテナイメージまたはソースコードを指定し、HTTPS エンドポイントとして即座に公開するフルマネージドコンテナデプロイメントサービス」 です。ECR / GitHub リポジトリを連携し、CI/CD パイプライン・オートスケーリング・カスタムドメイン・VPC 統合を自動管理。インフラ設定不要で REST API・Web アプリを数分で本番化できます。ただし 2026年4月30日以降、新規ユーザーの受付を終了 し、AWS ECS Express Mode への移行が推奨されています。本ドキュメントは App Runner の概念・アーキテクチャ・運用・2025-2026 動向を体系的に解説する包括的ガイドです。

ドキュメントの目的

本ガイドは以下を対象としています。

  • 初心者向け: App Runner とは何か、コンテナデプロイメントの基本を学びたい方
  • 開発者向け: ソースコード・ECR イメージから Web アプリ・API をデプロイしたい方
  • SRE/インフラ向け: オートスケーリング・VPC 統合・監視を構築したい方
  • 意思決定者向け: App Runner vs ECS Fargate vs Cloud Run の選定・2026年移行戦略

2025-2026 年の App Runner エコシステム

  • 保守モード突入(2026年4月30日新規受付終了):既存顧客は継続利用可能だが、新機能追加なし
  • AWS ECS Express Mode が後継:App Runner の簡潔性を ECS レベルで実現、Fargate ベース
  • Runtime Updates: Node.js / PHP / Python / Ruby の定期マイナーバージョン更新(2025年 4月・5月・10月・12月)
  • VPC / Custom Domain / WAF 統合:2024-2025年に機能拡充
  • Cost Optimization: Fargate Spot 拡張・インスタンスプール最適化

目次

  1. 概要
  2. App Runner が解決する課題
  3. 主な特徴
  4. アーキテクチャ
  5. コアコンポーネント
  6. 主要ユースケース
  7. 設定・操作の具体例
  8. 類似サービス比較表
  9. ベストプラクティス
  10. トラブルシューティング
  11. 2025-2026 最新動向
  12. 学習リソース・参考文献
  13. 実装例
  14. チェックリスト
  15. まとめ
  16. 参考文献

概要

初心者向けメモ: App Runner は「コード管理は GitHub・Docker イメージ管理は ECR・デプロイはワンクリック」のシンプルさが特徴です。ECS Fargate + ALB + ACM + Auto Scaling を個別設定する代わりに、App Runner なら「サービス作成 → リポジトリ指定 → 実行」で完了。ただし新規顧客は2026年4月30日以降受け入れなし。既存顧客・非新規利用の場合は ECS Express Mode を検討。

AWS App Runner 公式定義:

“AWS App Runner is an AWS service that provides a fast, simple, and cost-effective way to deploy from source code or a container image directly to a scalable and secure web application in the AWS Cloud.”

App Runner の位置づけ

graph TD
    A[アプリケーション]
    
    subgraph Abstraction["AWS Compute サービスの抽象化階層"]
        Lambda["Lambda<br/>(最高抽象<br/>コード実行のみ)"]
        AppRunner["App Runner<br/>(高抽象<br/>HTTP サービス向け<br/>2026年新規終了)"]
        Fargate["Fargate / ECS Express<br/>(中抽象<br/>完全な制御)"]
        ECS["ECS + EC2<br/>(低抽象<br/>OS レベル管理)"]
        EKS["EKS<br/>(最低抽象<br/>Kubernetes 拡張性)"]
    end
    
    A --> Lambda
    A --> AppRunner
    A --> Fargate
    A --> ECS
    A --> EKS
    
    style Lambda fill:#e6f3ff
    style AppRunner fill:#ffe6e6,stroke:red,stroke-width:3px
    style Fargate fill:#e6ffe6
    style ECS fill:#fff9e6
    style EKS fill:#f0e6ff

このサービスを選ぶ理由

なぜ App Runner(または後継 ECS Express Mode)か?

理由 詳細
インフラ設定ゼロ ECS + Fargate + ALB + ACM の複合設定を不要化、開発に集中可能
自動 CI/CD GitHub / ECR push で即座に自動デプロイ、GitHub Actions 設定不要
自動スケーリング 同時接続数ベースで自動スケール、最小 1 インスタンスまたはゼロスケール
HTTPS 自動化 ACM 証明書の自動取得・管理・更新
予測可能な料金 プロビジョニング + アクティブ課金モデル、アイドル時にメモリのみ課金

具体的なユースケース

  • マイクロサービスの素早い試作・MVP 開発
  • スタートアップの Web API ホスティング(インフラエンジニア不要)
  • DevOps スモールチーム(1-3名)の Web アプリ運用
  • 学習用プロジェクトの即座のクラウド化
  • サイドプロジェクト・ポートフォリオサイト公開

App Runner が解決する課題

課題 従来(ECS Fargate) App Runner 解決方法
セットアップ時間 VPC / SG / ALB / TG / ACM / ECS Cluster / Task Definition / Service で数時間 リポジトリ指定でワンステップ、15分以内に完了
CI/CD パイプライン GitHub Actions / CodePipeline / CodeBuild 等の複合構築が必要 GitHub / ECR 連携の自動デプロイ標準装備
HTTPS 証明書管理 ACM で手動取得・ALB にバインド・有効期限監視 自動取得・更新・インスタンスへの自動配置
キャパシティ管理 予測困難、スケーリングポリシー調整が複雑 同時接続数・CPU ベースで自動調整
セキュリティグループ設定 ALB / ECS インスタンス間の複数 SG を設定 最小限の SG 設定で動作

主な特徴

1. デプロイメントソース

ECR イメージベース

  • Docker イメージ を ECR にプッシュ
  • 自動デプロイ有効化で push 後、App Runner が即座にサービス更新
  • プライベート ECR リポジトリ対応(IAM ロール必須)

ソースコードベース

  • GitHub リポジトリ直接指定(OAuth 連携)
  • サポート言語:Python / Node.js / Ruby / Java / Go / PHP / .NET
  • ビルドコマンド・起動コマンドを apprunner.yaml または指定

2. リソース設定

インスタンス仕様

  • vCPU:0.25 / 0.5 / 1 / 2 / 4 vCPU
  • メモリ:0.5 GB〜12 GB(vCPU に応じて組み合わせ制限あり)
  • ネットワーク:1 Gbps までの帯域幅
  • CPU ファミリー:X86 のみ(ARM / Graviton 未対応)

スケーリング設定

  • 最小インスタンス数:1-100(0 は設定不可)
  • 最大インスタンス数:1-100
  • 最大同時接続数:1-200(インスタンスあたり)

3. ネットワーク

VPC コネクタ

  • RDS / ElastiCache / 内部 API 等のプライベートリソースへのアクセスを実現
  • Egress トラフィックのみ対応(Ingress は公開 HTTPS エンドポイント固定)
  • 複数コネクタ設定で複数 VPC/サブネットへの同時アクセス

カスタムドメイン

  • Route 53 またはサードパーティ DNS で CNAME レコード設定
  • ACM 証明書自動管理
  • Subdomain(www)対応

4. オートスケーリング

graph LR
    A["リクエスト受信"]
    B["同時接続数計測"]
    C{"max-concurrency<br/>超過?"}
    D["新インスタンス起動"]
    E["最大インスタンス数<br/>到達?"]
    F["リクエスト処理"]
    
    A --> B
    B --> C
    C -->|Yes| D
    D --> E
    E -->|Yes| F
    E -->|No| D
    C -->|No| F

コアコンポーネント

1. Service(サービス)

App Runner 実行エンティティ。以下を管理:

  • コンテナイメージ / ソースコード
  • リソース仕様(vCPU / メモリ)
  • 環境変数・シークレット(Secrets Manager 連携)
  • ロギング(CloudWatch Logs)
  • ヘルスチェック設定

2. Auto Scaling Configuration

同時接続数ベースのスケーリング定義:

  • max-concurrency:1インスタンスが処理する同時コネクション数上限
  • min-size / max-size:プロビジョニングするインスタンス数範囲
  • デフォルト設定と カスタム設定 が選択可能

3. VPC Connector

App Runner サービスをプライベート VPC に接続:

  • サブネット選択(最低 2 つの AZ にまたがる推奨)
  • セキュリティグループ(Egress ルール)
  • ENI(Elastic Network Interface)自動生成

4. Observability

CloudWatch 統合

  • Container Logs(stdout / stderr)
  • CloudWatch Logs グループへの自動配置
  • Request / Response ログ

**X-Ray 統合(オプション)

  • トレーシング有効化で分散トレース記録
  • バックエンド API 応答時間分析

主要ユースケース

1. REST API のホスティング

シナリオ

  • Node.js Express / Flask / Spring Boot API
  • リアルタイムデータ処理
  • マイクロサービス統合

実装例

aws apprunner create-service \
  --service-name product-api \
  --source-configuration '{
    "ImageRepository": {
      "ImageIdentifier": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/api:v1.2",
      "ImageRepositoryType": "ECR"
    },
    "AutoDeploymentsEnabled": true
  }' \
  --instance-configuration '{"Cpu": "1 vCPU", "Memory": "2 GB"}'

2. Web アプリケーション

シナリオ

  • Next.js / React / Vue.js フロントエンド + バックエンド統合
  • CMS ホスティング
  • ダッシュボード・管理画面

利点

  • 単一デプロイで フロント・API を同時管理
  • ステティック /ダイナミック コンテンツ混在対応

3. ジョブワーカー

注意

  • App Runner は HTTP/HTTPS のみ対応
  • 長時間バッチ処理には不向き(タイムアウト最大 120秒)
  • キューベースのワーカーは SQS + Lambda / ECS を推奨

4. プライベートリソースアクセス

VPC コネクタ経由

  • RDS / PostgreSQL / MySQL へのデータベースアクセス
  • ElastiCache / Redis へのキャッシュ接続
  • VPC 内部 API への呼び出し

設定・操作の具体例

CLI 例 1:ECR イメージからサービス作成

# 前提:ECR リポジトリに Docker イメージが存在
# 例:123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:latest

aws apprunner create-service \
  --service-name my-rest-api-prod \
  --source-configuration '{
    "ImageRepository": {
      "ImageIdentifier": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:latest",
      "ImageRepositoryType": "ECR",
      "ImageConfiguration": {
        "Port": "8080",
        "RuntimeEnvironmentVariables": {
          "NODE_ENV": "production",
          "LOG_LEVEL": "info",
          "API_TIMEOUT": "30"
        },
        "RuntimeEnvironmentSecrets": {
          "DATABASE_URL": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:db-prod-url",
          "JWT_SECRET": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:jwt-key"
        }
      }
    },
    "AutoDeploymentsEnabled": true,
    "AuthenticationConfiguration": {
      "AccessRoleArn": "arn:aws:iam::123456789012:role/AppRunnerECRAccess"
    }
  }' \
  --instance-configuration '{
    "Cpu": "1 vCPU",
    "Memory": "2 GB",
    "InstanceRoleArn": "arn:aws:iam::123456789012:role/AppRunnerInstanceRole"
  }' \
  --auto-scaling-configuration-arn arn:aws:apprunner:ap-northeast-1:123456789012:autoscalingconfiguration/prod-scaling/1/xxxxx \
  --tags '[{"Key": "Environment", "Value": "production"}, {"Key": "Team", "Value": "api"}]'

CLI 例 2:GitHub ソースコードからデプロイ

# 前提:GitHub OAuth 接続を作成済み
# aws apprunner create-connection \
#   --provider-type GITHUB \
#   --connection-name github-oauth

aws apprunner create-service \
  --service-name web-app-from-github \
  --source-configuration '{
    "CodeRepository": {
      "RepositoryUrl": "https://github.com/myorg/my-web-app",
      "SourceCodeVersion": {
        "Type": "BRANCH",
        "Value": "main"
      },
      "CodeConfiguration": {
        "ConfigurationSource": "REPOSITORY",
        "CodeConfigurationValues": {
          "Runtime": "NODEJS_18",
          "BuildCommand": "npm ci && npm run build",
          "StartCommand": "npm run start",
          "Port": "3000"
        }
      }
    },
    "AutoDeploymentsEnabled": true,
    "AuthenticationConfiguration": {
      "ConnectionArn": "arn:aws:apprunner:ap-northeast-1:123456789012:connection/github/xxxxxx"
    }
  }' \
  --instance-configuration '{
    "Cpu": "0.5 vCPU",
    "Memory": "1 GB"
  }'

CLI 例 3:VPC コネクタでプライベート RDS にアクセス

# Step 1: VPC コネクタ作成
aws apprunner create-vpc-connector \
  --vpc-connector-name rds-connector \
  --subnets subnet-private-1a subnet-private-1c \
  --security-groups sg-private-rds-access

# Step 2: サービスに VPC コネクタ関連付け
aws apprunner update-service \
  --service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/my-api/xxxx \
  --network-configuration '{
    "EgressConfiguration": {
      "EgressType": "VPC",
      "VpcConnectorArn": "arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/rds-connector/1/xxxxx"
    }
  }'

# Step 3:環境変数で DB URL 指定(Secrets Manager から取得)
aws apprunner update-service \
  --service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/my-api/xxxx \
  --source-configuration '{
    "ImageConfiguration": {
      "RuntimeEnvironmentSecrets": {
        "DB_HOST": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds-endpoint"
      }
    }
  }'

CLI 例 4:カスタムドメイン + WAF 統合

# Step 1: カスタムドメイン関連付け
aws apprunner associate-custom-domain \
  --service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/my-api/xxxx \
  --domain-name api.example.com \
  --enable-www-subdomain false

# Route 53 で CNAME レコード追加(API 出力から確認)
# api.example.com CNAME xxxxx.awsapprunner.com

# Step 2: WAF Web ACL 関連付け(SQLi / XSS ルール)
aws apprunner associate-web-acl \
  --service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/my-api/xxxx \
  --web-acl-arn arn:aws:wafv2:ap-northeast-1:123456789012:regional/webacl/api-protection/xxxxx

CLI 例 5:オートスケーリング設定

# カスタムオートスケーリング設定
aws apprunner create-auto-scaling-configuration \
  --auto-scaling-configuration-name api-production-scaling \
  --max-concurrency 100 \
  --min-size 2 \
  --max-size 10

# パラメータ詳細
# max-concurrency: 1 インスタンスが同時処理するリクエスト数
# min-size: 常時稼働インスタンス数(0 不可、最小 1)
# max-size: 最大スケールアップ時のインスタンス数

# サービスに適用
aws apprunner update-service \
  --service-arn arn:aws:apprunner:ap-northeast-1:123456789012:service/my-api/xxxx \
  --auto-scaling-configuration-arn arn:aws:apprunner:ap-northeast-1:123456789012:autoscalingconfiguration/api-production-scaling/1/xxxxx

SDK 例(Python)

import boto3

apprunner_client = boto3.client('apprunner', region_name='ap-northeast-1')

# サービス作成
response = apprunner_client.create_service(
    ServiceName='my-api-python',
    SourceConfiguration={
        'ImageRepository': {
            'ImageIdentifier': '123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:latest',
            'ImageRepositoryType': 'ECR',
            'ImageConfiguration': {
                'Port': '8000',
                'RuntimeEnvironmentVariables': {
                    'FLASK_ENV': 'production'
                }
            }
        },
        'AutoDeploymentsEnabled': True,
        'AuthenticationConfiguration': {
            'AccessRoleArn': 'arn:aws:iam::123456789012:role/AppRunnerECRAccess'
        }
    },
    InstanceConfiguration={
        'Cpu': '1 vCPU',
        'Memory': '2 GB'
    }
)

print(f"Service ARN: {response['Service']['ServiceArn']}")
print(f"Service URL: {response['Service']['ServiceUrl']}")

# サービス詳細取得
service_detail = apprunner_client.describe_service(
    ServiceArn=response['Service']['ServiceArn']
)

print(f"Status: {service_detail['Service']['Status']}")
print(f"Created: {service_detail['Service']['CreatedAt']}")

IaC 例(CloudFormation)

AWSTemplateFormatVersion: '2010-09-09'
Description: 'App Runner Service - CloudFormation Example'

Resources:
  AppRunnerService:
    Type: AWS::AppRunner::Service
    Properties:
      ServiceName: my-api-cf
      SourceConfiguration:
        ImageRepository:
          ImageIdentifier: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/my-api:latest'
          ImageRepositoryType: ECR
          ImageConfiguration:
            Port: '8080'
            RuntimeEnvironmentVariables:
              NODE_ENV: production
              LOG_LEVEL: info
        AutoDeploymentsEnabled: true
        AuthenticationConfiguration:
          AccessRoleArn: !GetAtt AppRunnerECRRole.Arn
      InstanceConfiguration:
        Cpu: 1 vCPU
        Memory: 2 GB
        InstanceRoleArn: !GetAtt AppRunnerInstanceRole.Arn
      Tags:
        - Key: Environment
          Value: production
        - Key: Team
          Value: api-team

  AppRunnerECRRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: apprunner.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly

  AppRunnerInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: tasks.apprunner.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: SecretsManagerAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:GetSecretValue
                Resource: 'arn:aws:secretsmanager:*:*:secret:*'

Outputs:
  ServiceUrl:
    Description: App Runner Service URL
    Value: !GetAtt AppRunnerService.ServiceUrl
  ServiceArn:
    Description: App Runner Service ARN
    Value: !GetAtt AppRunnerService.ServiceArn

IaC 例(Terraform)

# Provider setup
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

# IAM Role for ECR Access
resource "aws_iam_role" "app_runner_ecr_access" {
  name = "app-runner-ecr-access"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "apprunner.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "app_runner_ecr" {
  role       = aws_iam_role.app_runner_ecr_access.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
}

# IAM Role for App Runner Instance
resource "aws_iam_role" "app_runner_instance" {
  name = "app-runner-instance-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "tasks.apprunner.amazonaws.com"
        }
      }
    ]
  })
}

# App Runner Auto Scaling Configuration
resource "aws_apprunner_auto_scaling_configuration_version" "example" {
  auto_scaling_configuration_name = "api-scaling"
  max_concurrency                 = 100
  min_size                        = 2
  max_size                        = 10
}

# App Runner Service
resource "aws_apprunner_service" "example" {
  service_name = "my-api-terraform"
  auto_scaling_configuration_arn = aws_apprunner_auto_scaling_configuration_version.example.arn

  source_configuration {
    image_repository {
      image_identifier      = "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:latest"
      image_repository_type = "ECR"

      image_configuration {
        port = "8080"
        runtime_environment_variables = {
          NODE_ENV = "production"
          LOG_LEVEL = "info"
        }
      }
    }

    auto_deployments_enabled = true

    authentication_configuration {
      access_role_arn = aws_iam_role.app_runner_ecr_access.arn
    }
  }

  instance_configuration {
    cpu               = "1 vCPU"
    memory            = "2 GB"
    instance_role_arn = aws_iam_role.app_runner_instance.arn
  }

  tags = {
    Environment = "production"
    Team        = "api-team"
  }
}

output "service_url" {
  value       = aws_apprunner_service.example.service_url
  description = "The URL of the App Runner service"
}

output "service_arn" {
  value       = aws_apprunner_service.example.arn
  description = "The ARN of the App Runner service"
}

類似サービス比較表

観点 App Runner(2026終了) ECS Express Mode ECS Fargate Lambda Cloud Run Heroku
抽象化レベル 最高(HTTP のみ) 高(制御可能) 最高(関数型) 高(コンテナ) 高(PaaS)
セットアップ時間 5分 10分 1時間 15分 10分 2分
設定の複雑さ 最小 最小
VPC サポート VPC コネクタ フル フル フル フル(2024) 有限
スケール範囲 1-100 インスタンス 1-300+ 無制限 0-1000s 0-N 自動
ゼロスケール オプション 可能 不可 可能 可能 不可
長時間処理 最大 120秒 可能 可能 最大 900秒 最大 60分 可能
Spot / Preempt 未対応 Fargate Spot Spot 対応 - 未対応 限定
カスタマイズ
価格(アイドル時) メモリのみ 0 0 0 0 $7/月〜
推奨用途 MVP / スタートアップ Web API・マイクロサービス エンタープライズ・複雑ワークロード イベント駆動・API Cloud Native・GCP Rails / Node.js 習熟者
サポート状況 2026年4月30日新規終了 推奨後継 標準 標準 標準 商用

ベストプラクティス

チェックリスト(優先順)

✅ 推奨事項

  • [ ] ECR イメージは latest タグ避ける → バージョン明示(v1.2.0)で本番デプロイ管理
  • [ ] 環境変数は Secrets Manager で管理RuntimeEnvironmentSecrets 使用、ログ漏洩防止
  • [ ] VPC コネクタ使用時は複数 AZ に配置 → az1 と az2 のサブネット両方指定で高可用性
  • [ ] ヘルスチェックエンドポイント実装/health で 200 OK 返却、App Runner 自動確認
  • [ ] min-size は 1 以上に設定 → 0 は不可(常時 1 インスタンス必須)
  • [ ] CloudWatch Logs グループ自動作成確認 → ログ出力が /aws/apprunner/SERVICE_NAME に集約
  • [ ] WAF Web ACL 関連付け → SQLi / XSS / Bot Control ルール有効化
  • [ ] カスタムドメイン時は CNAME レコード追加 → Route 53 or サードパーティ DNS 確認
  • [ ] 自動デプロイ前に パイプラインテスト → GitHub Actions / ECR push テストで動作確認
  • [ ] IAM Role に最小権限設定 → Secrets Manager / S3 等への限定的アクセスのみ許可

❌ アンチパターン

アンチパターン 問題 代替
全ワークロードに App Runner 適用 HTTP のみ対応、VPC Ingress 未対応、カスタマイズ性低 ECS Express Mode / Fargate 検討
環境変数に直接シークレット記載 コンソール・ログに露出、セキュリティリスク Secrets Manager + RuntimeEnvironmentSecrets
min-size を 0 に設定 設定不可(最小 1)、コールドスタート発生 min-size: 1 で常時稼働
非 HTTP プロトコル(WebSocket / gRPC) サポート外、デプロイ失敗 ALB + ECS / 専用ゲートウェイ
バッチ処理に使用 常時コスト発生、120秒タイムアウト Lambda / AWS Batch 推奨
カスタムドメイン CNAME ミス サービス到達不可 DNS レコード検証・伝播確認
Auto Scaling 未設定 デフォルト同時接続数で CPU 逼迫 カスタム設定で max-concurrency 調整

トラブルシューティング

症状 原因 解決策
「Service in FAILED state」エラー イメージが見つからない / IAM Role 権限不足 ECR リポジトリ確認、AccessRoleArn の ECR 権限確認
起動後すぐに FAILED ヘルスチェック失敗(ポート不一致 / エンドポイント無応答) apprunner.yaml ポート指定確認、/health エンドポイント実装確認
VPC コネクタ経由 DB 接続失敗 SG ルール不足 / ルート不正 EC2 インスタンスから VPC コネクタ → DB への通信テスト
カスタムドメイン CNAME validation エラー CNAME レコード未伝播 / 名前空間ミス dig api.example.com で CNAME 確認、DNS TTL 待機
Auto Scaling が反応しない max-concurrency 設定見直し / リクエスト数不足 CloudWatch Metrics 確認、負荷テスト実施
秘密情報がログに出力 環境変数に直接記載 RuntimeEnvironmentSecrets で Secrets Manager 参照
WAF により正常リクエストがブロック ルール過度に厳密 WAF ルール再調整 / IP ホワイトリスト追加
メモリ不足(OOM Killer) Memory 設定不足 / アプリメモリリーク メモリ増加(1GB → 2GB)、アプリ最適化
デプロイ後スケーリング遅延 min-size 増加に伴う起動時間 max-concurrency 低めに設定(即座に新インスタンス起動)
CI/CD 自動デプロイ失敗 GitHub OAuth 接続期限切れ / ECR IAM Role 有効期限 Connection 再設定、IAM Role 有効期限確認

2025-2026 最新動向

2026年4月30日:新規顧客受付終了

AWS公式アナウンス

  • App Runner は 保守モード に移行
  • 既存顧客は継続利用可能
  • 新機能開発なし
  • ECS Express Mode が後継推奨

推奨移行パス

現在の App Runner ユーザー
        ↓
    ECS Express Mode へ移行
   (同じシンプルさ + より多機能)
        ↓
   Fargate ベース、完全な VPC 制御可能

2025年ランタイム更新

  • 2025年4月3日:Node.js / PHP マイナーバージョン更新
  • 2025年5月5日:Ruby / Python パッケージ更新
  • 2025年10月1日:Node.js / PHP / Corretto 更新
  • 2025年12月1日:全言語の年末セキュリティパッチ

2024-2025年機能拡張(新規受付終了前の追加)

  • VPC Connector GA:RDS / ElastiCache への完全なプライベートアクセス
  • Custom Domain Support:カスタムドメイン + ACM 自動管理
  • WAF Integration:Web ACL の直接統合、SQLi / XSS ブロック
  • Container Insights(オプション):メトリクス詳細監視

学習リソース・参考文献

公式ドキュメント

  1. AWS App Runner Developer Guide

  2. AWS App Runner API Reference

  3. AWS App Runner Pricing

  4. App Runner Release Notes(2025 Updates)

AWS ブログ・サンプルコード

  1. AWS Containers Blog

    • App Runner チュートリアル・ベストプラクティス記事
  2. AWS Samples on GitHub

    • aws-containers リポジトリ内 App Runner サンプル

OSS / サードパーティリソース

  1. Awesome AWS App Runner(GitHub)

    • コミュニティ製サンプル・ツール集
  2. CloudFormation / Terraform Modules

    • terraform-aws-modules/apprunner
    • awslabs/cloudformation-registry-apprunner

ベンダー・学習プラットフォーム

  1. A Cloud Guru / Linux Academy

    • App Runner ハンズオンコース
  2. Pluralsight

    • AWS コンテナサービス比較コース

実装例

例 1:Python Flask API(GitHub + App Runner)

リポジトリ構成

my-flask-api/
├── app.py
├── requirements.txt
├── apprunner.yaml
├── Dockerfile
└── README.md

apprunner.yaml

version: 1.0
build:
  commands:
    build:
      - pip install -r requirements.txt
run:
  command: gunicorn app:app --bind 0.0.0.0:8080
  runtime-version: 3.11
network:
  port: 8080

app.py

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/health', methods=['GET'])
def health():
    return jsonify({'status': 'healthy'}), 200

@app.route('/api/users', methods=['GET'])
def get_users():
    return jsonify([
        {'id': 1, 'name': 'Alice'},
        {'id': 2, 'name': 'Bob'}
    ]), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

デプロイ(GitHub OAuth 連携)

aws apprunner create-service \
  --service-name my-flask-api \
  --source-configuration '{
    "CodeRepository": {
      "RepositoryUrl": "https://github.com/myorg/my-flask-api",
      "SourceCodeVersion": {"Type": "BRANCH", "Value": "main"},
      "CodeConfiguration": {
        "ConfigurationSource": "REPOSITORY"
      }
    },
    "AutoDeploymentsEnabled": true,
    "AuthenticationConfiguration": {
      "ConnectionArn": "arn:aws:apprunner:ap-northeast-1:123456789012:connection/github/xxxxx"
    }
  }' \
  --instance-configuration '{"Cpu": "0.5 vCPU", "Memory": "1 GB"}'

例 2:Node.js Express API(ECR + VPC コネクタ + RDS)

Dockerfile

FROM node:18-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

server.js

const express = require('express');
const { Pool } = require('pg');

const app = express();
const pool = new Pool({
  connectionString: process.env.DATABASE_URL
});

app.get('/health', (req, res) => {
  res.json({ status: 'ok' });
});

app.get('/api/products', async (req, res) => {
  const result = await pool.query('SELECT id, name, price FROM products');
  res.json(result.rows);
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

デプロイ(VPC コネクタ有効)

# ECR にプッシュ
docker build -t my-api:1.0 .
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
docker tag my-api:1.0 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:1.0
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:1.0

# App Runner サービス作成(VPC コネクタ有効)
aws apprunner create-service \
  --service-name express-api-prod \
  --source-configuration '{
    "ImageRepository": {
      "ImageIdentifier": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-api:1.0",
      "ImageRepositoryType": "ECR",
      "ImageConfiguration": {
        "Port": "3000",
        "RuntimeEnvironmentSecrets": {
          "DATABASE_URL": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:rds-postgres-prod"
        }
      }
    },
    "AutoDeploymentsEnabled": true,
    "AuthenticationConfiguration": {
      "AccessRoleArn": "arn:aws:iam::123456789012:role/AppRunnerECRAccess"
    }
  }' \
  --instance-configuration '{
    "Cpu": "1 vCPU",
    "Memory": "2 GB",
    "InstanceRoleArn": "arn:aws:iam::123456789012:role/AppRunnerInstanceRole"
  }' \
  --network-configuration '{
    "EgressConfiguration": {
      "EgressType": "VPC",
      "VpcConnectorArn": "arn:aws:apprunner:ap-northeast-1:123456789012:vpcconnector/rds-connector/1/xxxxx"
    }
  }'

例 3:Next.js フルスタックアプリ

package.json

{
  "name": "nextjs-app",
  "scripts": {
    "build": "next build",
    "start": "next start",
    "dev": "next dev"
  },
  "dependencies": {
    "next": "^14.0.0",
    "react": "^18.0.0"
  }
}

apprunner.yaml

version: 1.0
build:
  commands:
    build:
      - npm ci
      - npm run build
run:
  command: npm start
  runtime-version: 18
network:
  port: 3000

チェックリスト

デプロイ前

  • [ ] Docker イメージビルド・テスト完了
  • [ ] ECR リポジトリ作成・イメージプッシュ完了
  • [ ] IAM Role(ECR Access / Instance Role)作成完了
  • [ ] VPC コネクタが必要な場合、サブネット・SG 準備完了
  • [ ] Secrets Manager でシークレット保存完了
  • [ ] CloudWatch Logs グループ自動作成確認

デプロイ後

  • [ ] サービス STATUS が「RUNNING」確認
  • [ ] サービス URL にアクセス、200 OK 確認
  • [ ] /health エンドポイント動作確認
  • [ ] ログが CloudWatch に集約確認
  • [ ] カスタムドメイン使用時、CNAME 伝播確認
  • [ ] WAF ルール有効化・テスト完了
  • [ ] Auto Scaling 設定・負荷テスト完了
  • [ ] バックアップ・災害復旧計画確認

運用時

  • [ ] 週1回 CloudWatch メトリクス確認
  • [ ] 月1回 セキュリティ監査実施
  • [ ] Runtime セキュリティパッチ適用(AWS 通知時)
  • [ ] ログ保持期限設定確認
  • [ ] コスト最適化の定期レビュー

まとめ

AWS App Runner は 「コンテナ化された HTTP Web アプリを秒単位で本番化するフルマネージドサービス」 でしたが、2026年4月30日に新規顧客受付を終了 します。既存ユーザーには AWS ECS Express Mode への移行が推奨されます。

App Runner が向いていた場合

  • マイクロサービス MVP・スタートアップ
  • インフラ管理を最小化したい小規模チーム
  • シンプルな HTTP Web API

現在の推奨

  • 新規利用:ECS Express Mode / Fargate(よりシンプルに、より多機能)
  • 既存利用:継続利用可能(ただし新機能なし)

App Runner のシンプルさを活かしたい場合、後継サービス(ECS Express Mode)の機能進化に注視し、段階的な移行を検討してください。


最終更新:2026-04-26 バージョン:v2.0