mcpField
G
google-app-engine

google-app-engine

github.com/jezwebクラウド・DevOps1.1k249 回インストール3 週間前に更新
リポジトリ

google-app-engine について

google-app-engineは、Google App Engineにアプリをデプロイする開発者向けの実践ガイドで、PythonとDjangoの例を中心に扱います。環境の選択、データベースや静的ファイルの接続、スケーリング、シークレット管理、障害対応を説明します。

主な機能

  1. 01StandardとFlexible環境の設定
  2. 02Cloud SQL接続例
  3. 03静的ファイルの配信方法
  4. 04Secret Managerによるシークレット管理
  5. 05スケーリングと複数サービスのデプロイ
  6. 06デプロイ時の一般的な問題の調査

活用シーン

  1. 01DjangoアプリをApp Engine向けに設定してデプロイ
  2. 02App EngineアプリをCloud SQLに接続
  3. 03本番環境のシークレットと静的ファイルを管理
  4. 04タイムアウト、メモリ、静的ファイルのエラーを調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jezweb/claude-skills --skill google-app-engine

インストール後、Claude Code で/google-app-engineを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
.claude-plugin/
plugin.json
references/
common-errors.md
rules/
google-app-engine.md
templates/
app-flex.yaml
app.yaml
requirements-gae.txt

詳細

Google App Engine

ステータス: 本番環境対応 最終更新日: 2026-01-24 依存関係: Google Cloud SDK(gcloud CLI) スキルバージョン: 1.0.0


クイックスタート(10 分)

1. 前提条件
# Install Google Cloud SDK
# macOS
brew install google-cloud-sdk

# Or download from https://cloud.google.com/sdk/docs/install

# Authenticate
gcloud auth login
gcloud config set project YOUR_PROJECT_ID

# Enable required APIs
gcloud services enable appengine.googleapis.com
gcloud services enable sqladmin.googleapis.com
gcloud services enable secretmanager.googleapis.com
2. app.yaml を作成する
# app.yaml - Standard Environment (Python 3.12)
runtime: python312
instance_class: F2

env_variables:
  DJANGO_SETTINGS_MODULE: "myproject.settings.production"

handlers:
  # Static files (served directly by App Engine)
  - url: /static
    static_dir: staticfiles/
    secure: always

  # All other requests go to the app
  - url: /.*
    script: auto
    secure: always

automatic_scaling:
  min_instances: 0
  max_instances: 10
  target_cpu_utilization: 0.65
3. デプロイする
# Deploy to App Engine
gcloud app deploy

# Deploy with specific version
gcloud app deploy --version=v1 --no-promote

# View logs
gcloud app logs tail -s default

Standard 環境と Flexible 環境

Standard 環境(ほとんどのアプリに推奨)

使用する場面: ランタイムの制約内で動作する一般的なウェブアプリ、API、サービスを構築する場合。

項目Standard
起動高速(ミリ秒)
スケーリングゼロまでスケール
料金リクエストごとの従量課金
ランタイムPython 3.8-3.12
インスタンスクラスF1, F2, F4, F4_1G
リクエストの最大時間60 秒
バックグラウンドCloud Tasks のみ
# app.yaml - Standard
runtime: python312
instance_class: F2
Flexible 環境

使用する場面: カスタムランタイム、Docker、より長いリクエストタイムアウト、またはバックグラウンドスレッドが必要な場合。

項目Flexible
起動低速(数分)
スケーリング最小 1 インスタンス
料金VM の時間単位課金
ランタイム任意(Docker)
リクエストの最大時間60 分
バックグラウンドネイティブスレッド
# app.yaml - Flexible
runtime: python
env: flex

runtime_config:
  runtime_version: "3.12"

resources:
  cpu: 1
  memory_gb: 0.5
  disk_size_gb: 10

automatic_scaling:
  min_num_instances: 1
  max_num_instances: 5

料金に関する警告: Flexible は常に少なくとも 1 つのインスタンスを実行するため、最低でも月額約 30~40 ドルかかります。


Cloud SQL 接続

Standard 環境(Unix ソケット)

App Engine Standard は TCP/IP ではなく、Unix ソケット経由で Cloud SQL に接続します。

# settings.py
import os

if os.getenv('GAE_APPLICATION'):
    # Production: Cloud SQL via Unix socket
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ['DB_NAME'],
            'USER': os.environ['DB_USER'],
            'PASSWORD': os.environ['DB_PASSWORD'],
            'HOST': f"/cloudsql/{os.environ['CLOUD_SQL_CONNECTION_NAME']}",
            'PORT': '',  # Empty for Unix socket
        }
    }
else:
    # Local development: Cloud SQL Proxy or local DB
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('DB_NAME', 'localdb'),
            'USER': os.environ.get('DB_USER', 'postgres'),
            'PASSWORD': os.environ.get('DB_PASSWORD', ''),
            'HOST': '127.0.0.1',
            'PORT': '5432',
        }
    }
# app.yaml
env_variables:
  DB_NAME: "mydb"
  DB_USER: "myuser"
  CLOUD_SQL_CONNECTION_NAME: "project:region:instance"

# CRITICAL: Beta settings for Cloud SQL socket
beta_settings:
  cloud_sql_instances: "project:region:instance"

重要: beta_settings.cloud_sql_instances によって Unix ソケットが有効になります。これがないと接続に失敗します。

Cloud SQL Proxy を使用したローカル開発
# Download and run Cloud SQL Proxy
cloud-sql-proxy PROJECT:REGION:INSTANCE --port=5432

# Or use Docker
docker run -p 5432:5432 \
  gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.8.0 \
  PROJECT:REGION:INSTANCE

Cloud Storage を使用した静的ファイル

オプション 1: App Engine の静的ハンドラー(簡単)
# app.yaml
handlers:
  - url: /static
    static_dir: staticfiles/
    secure: always
    expiration: "1d"
# Collect static files before deploy
python manage.py collectstatic --noinput
gcloud app deploy

制限事項: ファイルはデプロイ時に同梱され、1 ファイルあたり 32MB までです。

オプション 2: Cloud Storage(本番環境に推奨)
# settings.py
from google.cloud import storage

GS_BUCKET_NAME = os.environ.get('GS_BUCKET_NAME')
STATICFILES_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'

# Or with django-storages
STORAGES = {
    "default": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
        "OPTIONS": {
            "bucket_name": GS_BUCKET_NAME,
            "location": "media",
        },
    },
    "staticfiles": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
        "OPTIONS": {
            "bucket_name": GS_BUCKET_NAME,
            "location": "static",
        },
    },
}
# Install django-storages
pip install django-storages[google]

# Create bucket with public access for static files
gsutil mb -l us-central1 gs://YOUR_BUCKET_NAME
gsutil iam ch allUsers:objectViewer gs://YOUR_BUCKET_NAME

環境変数とシークレット

簡単な方法: app.yaml の env_variables
# app.yaml - NOT for secrets!
env_variables:
  DJANGO_SETTINGS_MODULE: "myproject.settings.production"
  DEBUG: "False"

警告: app.yaml はソース管理にコミットされます。ここにシークレットを記述しないでください。

本番環境: Secret Manager
# settings.py
from google.cloud import secretmanager

def get_secret(secret_id, version="latest"):
    """Fetch secret from Google Secret Manager."""
    client = secretmanager.SecretManagerServiceClient()
    project_id = os.environ.get('GOOGLE_CLOUD_PROJECT')
    name = f"projects/{project_id}/secrets/{secret_id}/versions/{version}"
    response = client.access_secret_version(request={"name": name})
    return response.payload.data.decode("UTF-8")

# Usage
if os.getenv('GAE_APPLICATION'):
    SECRET_KEY = get_secret('django-secret-key')
    DB_PASSWORD = get_secret('db-password')
# Create secrets
echo -n "your-secret-key" | gcloud secrets create django-secret-key --data-file=-
echo -n "db-password" | gcloud secrets create db-password --data-file=-

# Grant App Engine access
gcloud secrets add-iam-policy-binding django-secret-key \
    --member="serviceAccount:[email protected]" \
    --role="roles/secretmanager.secretAccessor"

スケーリング設定

自動スケーリング(デフォルト)
automatic_scaling:
  min_instances: 0        # Scale to zero when idle
  max_instances: 10       # Cap maximum instances
  target_cpu_utilization: 0.65
  target_throughput_utilization: 0.6
  max_concurrent_requests: 80
  min_pending_latency: 30ms
  max_pending_latency: automatic
基本スケーリング(バックグラウンドタスク)
basic_scaling:
  max_instances: 5
  idle_timeout: 5m

使用する場面: すぐにゼロまでスケールせずにバックグラウンド処理を実行する必要があるサービス。

手動スケーリング(インスタンス固定)
manual_scaling:
  instances: 3

使用する場面: 予測可能なワークロード、WebSocket 接続、または容量の保証が必要な場合。


インスタンスクラス

クラスメモリCPU1 時間あたりの料金
F1256 MB600 MHz$0.05
F2512 MB1.2 GHz$0.10
F41 GB2.4 GHz$0.20
F4_1G2 GB2.4 GHz$0.30
# Recommended for Django
instance_class: F2  # 512MB usually sufficient

メモリ関連のエラーが発生したり、応答時間が遅かったりする場合は、F4 にアップグレードしてください。


既知の問題の予防

このスキルは、文書化された 6 件の問題を予防します。

問題 #1: Cloud SQL 接続拒否

エラー: could not connect to server: Connection refused 発生理由: app.yaml に beta_settings.cloud_sql_instances がない 予防策: 必ず次を含めてください。

beta_settings:
  cloud_sql_instances: "project:region:instance"
問題 #2: 静的ファイルが 404 になる

エラー: デプロイ後に静的ファイルが 404 を返す 発生理由: collectstatic が実行されていない、またはハンドラーの順序が誤っている 予防策:

python manage.py collectstatic --noinput

また、静的ハンドラーがすべてに一致するハンドラーより前にあることを確認してください。

handlers:
  - url: /static
    static_dir: staticfiles/
  - url: /.*
    script: auto
問題 #3: 502 Bad Gateway

エラー: 初回リクエスト時または高負荷時に 502 エラーが発生する 発生理由: コールドスタートのタイムアウト、またはアプリの初期化に時間がかかりすぎる 予防策:

  • アプリの起動を最適化する(遅延インポート、コネクションプーリング)
  • コールドスタートを避けるために min_instances: 1 を使用する
  • CPU/メモリを増やすために instance_class を引き上げる
問題 #4: メモリ制限超過

エラー: ログに Exceeded soft memory limit が表示される 発生理由: F1 クラス(256MB)では Django と依存関係を実行するには小さすぎる 予防策: Django アプリでは最低でも instance_class: F2 を使用してください

問題 #5: リクエストタイムアウト

エラー: 60 秒後に DeadlineExceededError 発生する理由: 標準環境には 60 秒のリクエスト制限があります 防止策:

  • 長時間実行されるタスクを Cloud Tasks に移動する
  • より長いタイムアウトにはフレキシブル環境を使用する
  • データベースクエリを最適化する
問題 #6: ソース管理内のシークレットキー

エラー: Django の SECRET_KEY が git 履歴内で露出している 発生する理由: シークレットを app.yaml の env_variables に記述している 防止策: Secret Manager を使用する(環境変数のセクションを参照)


デプロイコマンド

# Deploy default service
gcloud app deploy

# Deploy specific service
gcloud app deploy app.yaml --service=api

# Deploy without promoting (for testing)
gcloud app deploy --version=v2 --no-promote

# Split traffic between versions
gcloud app services set-traffic default --splits=v1=0.5,v2=0.5

# Promote version
gcloud app versions migrate v2

# View logs
gcloud app logs tail -s default

# Open app in browser
gcloud app browse

# List versions
gcloud app versions list

# Delete old versions
gcloud app versions delete v1 v2 --quiet

マルチサービスアーキテクチャ

myproject/
├── app.yaml              # Default service
├── api/
│   └── app.yaml          # API service
├── worker/
│   └── app.yaml          # Background worker
└── dispatch.yaml         # URL routing
# dispatch.yaml
dispatch:
  - url: "*/api/*"
    service: api
  - url: "*/tasks/*"
    service: worker
# Deploy all services
gcloud app deploy app.yaml api/app.yaml worker/app.yaml dispatch.yaml

一般的なパターン

ヘルスチェックエンドポイント
# urls.py
urlpatterns = [
    path('_ah/health', lambda r: HttpResponse('ok')),
    # ... other urls
]
# app.yaml
liveness_check:
  path: "/_ah/health"
  check_interval_sec: 30
  timeout_sec: 4
  failure_threshold: 2
  success_threshold: 2

readiness_check:
  path: "/_ah/health"
  check_interval_sec: 5
  timeout_sec: 4
  failure_threshold: 2
  success_threshold: 2
ウォームアップリクエスト
# app.yaml
inbound_services:
  - warmup
# urls.py
urlpatterns = [
    path('_ah/warmup', warmup_view),
]

# views.py
def warmup_view(request):
    """Pre-warm caches and connections."""
    from django.db import connection
    connection.ensure_connection()
    return HttpResponse('ok')
HTTPS リダイレクト
# app.yaml
handlers:
  - url: /.*
    script: auto
    secure: always  # Redirects HTTP to HTTPS

ローカル開発

Cloud SQL Proxy の使用
# Terminal 1: Run Cloud SQL Proxy
cloud-sql-proxy PROJECT:REGION:INSTANCE --port=5432

# Terminal 2: Run Django
export DB_HOST=127.0.0.1
export DB_PORT=5432
python manage.py runserver
dev_appserver の使用(レガシー)
# Not recommended - use Django's runserver instead
dev_appserver.py app.yaml
環境の検出
# settings.py
import os

# Detect App Engine environment
IS_GAE = os.getenv('GAE_APPLICATION') is not None
IS_GAE_LOCAL = os.getenv('GAE_ENV') == 'localdev'

if IS_GAE:
    DEBUG = False
    ALLOWED_HOSTS = ['.appspot.com', '.your-domain.com']
else:
    DEBUG = True
    ALLOWED_HOSTS = ['localhost', '127.0.0.1']

同梱リソース

テンプレート (templates/)
  • app.yaml - 標準環境の設定
  • app-flex.yaml - フレキシブル環境の設定
  • requirements.txt - App Engine の一般的な依存関係
リファレンス (references/)
  • instance-classes.md - インスタンスクラスの詳細な比較
  • common-errors.md - エラーメッセージと解決策

公式ドキュメント


依存関係

# requirements.txt
gunicorn>=21.0.0
google-cloud-secret-manager>=2.16.0
google-cloud-storage>=2.10.0
django-storages[google]>=1.14.0
psycopg2-binary>=2.9.9  # For PostgreSQL

本番チェックリスト

  • SECRET_KEY が Secret Manager にある(app.yaml ではない)
  • 本番設定で DEBUG = False になっている
  • ALLOWED_HOSTS があなたのドメイン用に設定されている
  • デプロイ前に collectstatic が実行される
  • beta_settings.cloud_sql_instances が設定されている
  • インスタンスクラスが適切である(Django には F2 以上)
  • HTTPS が強制されている(secure: always)
  • ヘルスチェックエンドポイントが設定されている
  • エラー監視が設定されている(Cloud Error Reporting)

最終確認日: 2026-01-24 | スキルバージョン: 1.0.0

コメント