目次
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 拡張・インスタンスプール最適化
目次
- 概要
- App Runner が解決する課題
- 主な特徴
- アーキテクチャ
- コアコンポーネント
- 主要ユースケース
- 設定・操作の具体例
- 類似サービス比較表
- ベストプラクティス
- トラブルシューティング
- 2025-2026 最新動向
- 学習リソース・参考文献
- 実装例
- チェックリスト
- まとめ
- 参考文献
概要
初心者向けメモ: 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. ジョブワーカー
注意
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/月〜 |
| 推奨用途 | 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(オプション):メトリクス詳細監視
学習リソース・参考文献
公式ドキュメント
-
AWS App Runner Developer Guide
-
AWS App Runner API Reference
-
AWS App Runner Pricing
-
App Runner Release Notes(2025 Updates)
AWS ブログ・サンプルコード
-
AWS Containers Blog
- App Runner チュートリアル・ベストプラクティス記事
-
AWS Samples on GitHub
aws-containersリポジトリ内 App Runner サンプル
OSS / サードパーティリソース
-
Awesome AWS App Runner(GitHub)
- コミュニティ製サンプル・ツール集
-
CloudFormation / Terraform Modules
terraform-aws-modules/apprunnerawslabs/cloudformation-registry-apprunner
ベンダー・学習プラットフォーム
-
A Cloud Guru / Linux Academy
- App Runner ハンズオンコース
-
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
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