App Engine スタンダード環境での Django の実行

App Engine スタンダード環境で実行される Django アプリは、トラフィックに応じて動的に拡張されます。

このチュートリアルは、Django ウェブ開発の知識があることを前提としています。Django 開発を初めて使用する場合は、続行する前に最初の Django アプリを作成するを実施することをおすすめします。

このチュートリアルでは Django について具体的に説明しますが、このデプロイ プロセスは WagtailDjango CMS などの他の Django ベースのフレームワークでも使用できます。

このチュートリアルでは Django 3 を使用します。Django 3 には Python 3.7 以降が必要です。App Engine スタンダード環境では、Python 3.7 以降がサポートされています。

目標

このチュートリアルの内容は次のとおりです。

  • Cloud SQL データベースを作成して接続します。
  • Secret Manager のシークレット値を作成して使用します。
  • Django アプリを App Engine スタンダード環境にデプロイする。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使用すると、予想使用量に基づいて費用の見積もりを算出できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

始める前に

  1. Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. Cloud SQL Admin API, Secret Manager, and Cloud Build API を有効にします。

    API を有効にする

  5. Cloud SDK をインストールして初期化します。
  6. App Engine を初期化し、希望のリージョンを選択します(まだ行っていない場合)。

    gcloud app create
    

環境を準備する

サンプルアプリのクローンを作成する

Django サンプルアプリのコードは、GitHub の GoogleCloudPlatform/python-docs-samples リポジトリにあります。

  1. ZIP ファイルとしてサンプルをダウンロードして展開するか、ローカルマシンにリポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
    
  2. サンプルコードのあるディレクトリに移動します。

    Linux / macOS

    cd python-docs-samples/appengine/standard_python3/django
    

    Windows

    cd python-docs-samples\appengine\standard_python3\django
    

Python の設定を確認する

このチュートリアルでは、マシン上でサンプル アプリケーションを実行するために Python を使用します。サンプルコードは依存関係もインストールする必要があります。

詳細については、Python 開発環境ガイドをご覧ください。

  1. Python のバージョンが 3.7 以降であることを確認します。

     python -V
    

    Python 3.7.3 以上が表示される必要があります。

  2. Python 仮想環境を作成し、依存関係をインストールします。

    Linux / macOS

    python -m venv venv
    source venv/bin/activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

    Windows

    python -m venv env
    venv\scripts\activate
    pip install --upgrade pip
    pip install -r requirements.txt
    

ローカルマシンから Cloud SQL Auth プロキシをダウンロードして Cloud SQL に接続する

デプロイすると、アプリは App Engine スタンダード環境に組み込まれている Cloud SQL Auth プロキシを使用して Cloud SQL インスタンスと通信します。ただし、アプリをローカルでテストするには、プロキシのローカルコピーを開発環境にインストールして使用する必要があります。詳細については、Cloud SQL Auth プロキシガイドをご覧ください。

Cloud SQL Auth プロキシは、Cloud SQL API を使用して SQL インスタンスとやり取りします。そのためには、gcloud でアプリケーションの認証を行う必要があります。

  1. API の認証情報を取得して認証します。

    gcloud auth application-default login
    
  2. Cloud SQL Auth プロキシをローカルマシンにダウンロードしてインストールします。

    Linux 64 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    Linux 32 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 -O cloud_sql_proxy
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    macOS 64 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    macOS 32 ビット

    1. Cloud SQL Auth Proxy をダウンロードします。
      curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.386
      
    2. Cloud SQL Auth Proxy を動作可能にします。
      chmod +x cloud_sql_proxy
      

    Windows 64 ビット

    https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe を右クリックして [名前を付けてリンク先を保存] を選択し、Cloud SQL Auth Proxy をダウンロードします。ファイル名を cloud_sql_proxy.exe に変更します。

    Windows 32 ビット

    https://dl.google.com/cloudsql/cloud_sql_proxy_x86.exe を右クリックして [名前を付けてリンク先を保存] を選択し、Cloud SQL Auth Proxy をダウンロードします。ファイル名を cloud_sql_proxy.exe に変更します。

    Cloud SQL Auth Proxy Docker イメージ

    便宜上、Cloud SQL Auth プロキシを含む複数のコンテナ イメージを GitHub の Cloud SQL Auth プロキシ リポジトリで入手できます。次のコマンドを使用して、最新のイメージをローカルマシンに Docker で pull できます。
    docker pull gcr.io/cloudsql-docker/gce-proxy:1.19.1
    

    その他の OS

    ここに記載されていないその他のオペレーティング システムの場合は、ソースから Cloud SQL Auth Proxy をコンパイルできます。

    ダウンロード ファイルを PATH やホーム ディレクトリなどの一般的な場所に移動することもできます。これを選択した場合、チュートリアルの後半で Cloud SQL Auth プロキシを起動する際に、cloud_sql_proxy コマンドを使用するときに選択したロケーションを必ず参照してください。

バッキング サービスの作成

このチュートリアルでは、いくつかの Google Cloud サービスを使用して、デプロイ済みの Django プロジェクトをサポートするデータベース、メディア ストレージ、シークレット ストレージを準備します。これらのサービスは、特定のリージョンにデプロイされます。サービス間の効率性を高めるには、すべてのサービスが同じリージョンにデプロイされるのが最適です。最も近いリージョンの詳細については、リージョン別に提供されるプロダクトをご覧ください。

このチュートリアルでは、App Engine スタンダードの統合静的アセット ホスティング メカニズムを使用します。

Cloud SQL for PostgreSQL インスタンスを設定する

Django では公式な形で複数のリレーショナル データベースをサポートしており、PostgreSQL に対してはほとんどのサポートを提供しています。PostgreSQL は Cloud SQL でサポートされているため、このチュートリアルではその種類のデータベースを使用します。

以降のセクションでは、アプリの PostgreSQL インスタンス、データベース、データベース ユーザーの作成について説明します。

  1. PostgreSQL インスタンスを作成します。

    Console

    1. Cloud Console で、[Cloud SQL インスタンス] ページに移動します。

      Cloud SQL インスタンス ページに移動

    2. [インスタンスを作成] をクリックします。

    3. [PostgreSQL] をクリックします。

    4. [インスタンス ID] フィールドに「INSTANCE_NAME」と入力します。

    5. postgres ユーザーのパスワードを入力します。

    6. 他のフィールドはデフォルト値を使用します。

    7. [作成] をクリックします。

    インスタンスの作成と使用準備が完了するまでに数分かかります。

    gcloud

    • PostgreSQL インスタンスを作成します。

      gcloud sql instances create INSTANCE_NAME \
          --project PROJECT_ID \
          --database-version POSTGRES_13 \
          --tier db-f1-micro \
          --region REGION
      

    以下を置き換えます。

    インスタンスの作成と使用準備が完了するまでに数分かかります。

  2. 作成したインスタンス内で、データベースを作成します。

    Console

    1. インスタンス ページで、[データベース] タブに移動します。
    2. [データベースを作成] をクリックします。
    3. [データベース名] ダイアログで「DATABASE_NAME」と入力します。
    4. [作成] をクリックします。

    gcloud

    • 最近作成したインスタンス内にデータベースを作成します。

      gcloud sql databases create DATABASE_NAME \
          --instance INSTANCE_NAME
      

      DATABASE_NAME を、このインスタンス内のデータベースの名前に置き換えます。

  3. データベース ユーザーの作成

    Console

    1. インスタンス ページで [ユーザー] タブに移動します。
    2. [ユーザー アカウントを追加] をクリックします。
    3. [ユーザー アカウントをインスタンスに追加] ダイアログの [組み込みアルゴリズム] で次の操作を行います。
    4. DATABASE_USERNAME というユーザー名を入力します。
    5. DATABASE_PASSWORD というパスワードを入力します。
    6. [Add] をクリックします。

    gcloud

    • 最近作成したインスタンス内にデータベースを作成します。

      gcloud sql users create DATABASE_USERNAME \
          --instance INSTANCE_NAME \
          --password DATABASE_PASSWORD
      

      PASSWORD は安全なパスワードに置き換えてください。

Secret Manager にシークレット値を保存する

バッキング サービスが構成されたので、Django はこれらのサービスに関する情報を必要とします。このチュートリアルでは、これらの値を Django のソースコードに直接入力せず、Secret Manager を使用してこの情報を安全に保存します。

App Engine スタンダードでは、サービス アカウントを使用して シークレット を操作します。

Secret Manager シークレットとして Django 環境ファイルを作成する

Django の起動に必要な設定を、保護された env ファイルに保存します。サンプルアプリは、Secret Manager API を使用してシークレット値を取得し、django-environ パッケージを使用して Django 環境に値を読み込みます。シークレットは、App Engine 標準でアクセスできるように構成されています。

  1. .env という名前のファイルを作成し、データベースの接続文字列、メディア バケット名、新しい SECRET_KEY 値を定義します。

    echo DATABASE_URL=postgres://DATABASE_USERNAME:DATABASE_PASSWORD@//cloudsql/PROJECT_ID:REGION:INSTANCE_NAME/DATABASE_NAME > .env
    echo GS_BUCKET_NAME=PROJECT_ID_MEDIA_BUCKET >> .env
    echo SECRET_KEY=$(cat /dev/urandom | LC_ALL=C tr -dc '[:alpha:]'| fold -w 50 | head -n1) >> .env
    
  2. シークレットを Secret Manager に保存します。

    Console

    1. Cloud Console で、[シークレット マネージャー] ページに移動します。

      シークレット マネージャー ページに移動

    2. [シークレットの作成] をクリックします。

    3. [名前] フィールドに「django_settings」と入力します。

    4. [シークレット値] ダイアログで、.env ファイルの内容を貼り付けます。

    5. [シークレットの作成] をクリックします。

    6. ローカル設定のオーバーライドを防ぐため、ローカル ファイルを削除してください。

    gcloud

    1. 新しいシークレット django_settings.env ファイルの値で作成します。

      gcloud secrets create django_settings --data-file .env
      
    2. シークレットの作成を確認するには、次のことを確認します。

      gcloud secrets describe django_settings
      
      gcloud secrets versions access latest --secret django_settings
      
    3. ローカル ファイルを削除して、ローカル設定のオーバーライドを防ぎます。

      rm .env
      
  3. シークレットへのアクセスを構成します。

    Console

    1. [権限] タブをクリックします。
    2. [Add] をクリックします。
    3. [新しいメンバー] フィールドに「PROJECT_ID@appspot.gserviceaccount.com」と入力し、Enter を押します。
    4. [ロール] プルダウン メニューで [Secret Manager のシークレット アクセサー] を選択します。
    5. [保存] をクリックします。

    gcloud

    1. App Engine スタンダード サービス アカウントにシークレットへのアクセス権を付与します。

      gcloud secrets add-iam-policy-binding django_settings \
          --member serviceAccount:PROJECT_ID@appspot.gserviceaccount.com \
          --role roles/secretmanager.secretAccessor
      

ローカル コンピュータでアプリを実行する

バッキング サービスが構成されたら、パソコン上でアプリを実行できます。この設定により、ローカルでの開発、スーパーユーザーの作成、データベースの移行が可能になります。

  1. 別のターミナルで Cloud SQL Auth プロキシを開始します。

    Linux / macOS

    ./cloud_sql_proxy -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
    

    Windows

    cloud_sql_proxy.exe -instances="PROJECT_ID:REGION:INSTANCE_NAME"=tcp:5432
    

    このステップで、ローカルのパソコンから Cloud SQL インスタンスへのローカルテスト用接続が確立されます。ローカルでのアプリのテストが終了するまで、Cloud SQL Auth プロキシを実行したままにしてください。このプロセスを別のターミナルで実行すると、このプロセスの実行中に作業を続行できます。次のステップが別のターミナルで完了していることを確認します。

  2. 新しいターミナルで、プロジェクト ID をローカルに設定します。

    Linux / macOS

      export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    

    Windows

      set GOOGLE_CLOUD_PROJECT=PROJECT_ID
    
  3. Cloud SQL Auth プロキシを使用していることを示す環境変数を設定します(この値はコードで認識できます)。

    Linux / macOS

      export USE_CLOUD_SQL_AUTH_PROXY=true
    

    Windows

      set USE_CLOUD_SQL_AUTH_PROXY=true
    
  4. Django の移行を実行してモデルとアセットを設定します。

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    python manage.py collectstatic
    
  5. Django ウェブサーバーを起動します。

    python manage.py runserver
    
  6. ブラウザで、http://localhost:8000 にアクセスします。

    「Hello, world. You're at the polls index.」というテキストを含む簡単なウェブページが表示されます。コンピュータで実行されている Django ウェブサーバーは、サンプルアプリのページを配信します。

  7. Control+C キーを押して、ローカル ウェブサーバーを停止します。

Django 管理コンソールを使用する

Django の管理コンソールにログインするには、スーパー ユーザーを作成する必要があります。データベースにはローカルにアクセス可能な接続があるため、管理コマンドを実行できます。

  1. スーパーユーザーを作成します。ユーザー名、メールアドレス、パスワードの入力を求められます。

    python manage.py createsuperuser
    
  2. ローカル ウェブサーバーを起動します。

    python manage.py runserver
    
  3. ブラウザで、http://localhost:8000/admin にアクセスします。

  4. createsuperuser の実行時に使用したユーザー名とパスワードで管理サイトにログインします。

App Engine スタンダード環境のアプリをデプロイする

すべてのバッキング サービスを設定し、アプリケーションをローカルでテストしたら、アプリを App Engine スタンダード環境にデプロイできます。

  1. 次のコマンドを実行してアプリをアップロードします。app.yaml の説明に従ってアプリがデプロイされ、新しくデプロイされるバージョンがデフォルト バージョンとして設定され、新しいトラフィックがすべて処理されます。
    gcloud app deploy
  2. プロンプトが表示されたら、「yes」と入力して設定を確認します。
  3. 更新が完了したことを通知するメッセージが表示されるまで待ちます。

デプロイされたアプリを実行する

アプリがデプロイされ、アクセスできるようになりました。

  • デプロイされたウェブサイトを開きます。

    gcloud app browse
    
  • または、URL を表示して手動で開くこともできます。

    gcloud app describe --format "value(defaultHostname)"
    

リクエストは、App Engine スタンダード環境で実行されているウェブサーバーによって処理されます。

アプリケーションを更新する

アプリケーションを更新するには、コードを変更してから、gcloud app deploy コマンドを再度実行します。

デプロイでアプリの新しいバージョンが作成され、デフォルトのバージョンに設定されます。 アプリの古いバージョンはそのまま残ります。これらのアプリ バージョンはすべて課金対象のリソースとなります。コストを抑えるには、アプリのデフォルト以外のバージョンを削除します。

本番環境用の構成

これで Django のデプロイが機能するようになりました。しかし、アプリケーションが本番環境に対応できるよう、さらに対策を講じる必要があります。

デバッグが無効になっていることを確認する

mysite/settings.pyDEBUG 変数が False に設定されていることを確認します。これにより、構成に関する情報が漏洩する可能性がある、詳細なエラーページがユーザーに表示されなくなります。

データベース ユーザーの権限を制限する

Cloud SQLを使用して作成されたすべてのユーザーには、cloudsqlsuperuser ロールに関連付けられた特権(CREATEROLECREATEDB、および LOGIN)があります。

Django データベース ユーザーがこれらの権限を持っていないようにするには、PostgreSQL でユーザーを手動で作成します。psql インタラクティブ ターミナルをインストールするか、このツールがプリインストールされている Cloud Shell を使用する必要があります。

Console

  1. Cloud Console で、Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

  2. Cloud Shell で、組み込みターミナルを使用して INSTANCE_NAME インスタンスに接続します。

    gcloud sql connect INSTANCE_NAME --user postgres
    
  3. postgres ユーザー パスワードを入力します。

    現在、psql を使用しています。postgres=> プロンプトが表示されます。

  4. ユーザーを作成します。

    CREATE USER DATABASE_USERNAME WITH PASSWORD 'DATABASE_PASSWORD';
    

    PASSWORD は、ランダムな一意のパスワードに置き換えます。

  5. 新しいデータベースに対する完全な権限を新しいユーザーに付与します。

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO DATABASE_USERNAME;
    
  6. psql を終了します。

    \q
    

gcloud

  1. SQL インスタンスへの接続を開始します。

    gcloud sql connect INSTANCE_NAME --user postgres
    

    INSTANCE_NAME は、作成した Cloud SQL インスタンスに置き換えます。

  2. postgres ユーザー パスワードを入力します。

    現在、psql を使用しています。postgres=> プロンプトが表示されます。

  3. ユーザーを作成します。

    CREATE USER DATABASE_USERNAME WITH PASSWORD 'DATABASE_PASSWORD';
    
  4. 新しいデータベースに対する完全な権限を新しいユーザーに付与します。

    GRANT ALL PRIVILEGES ON DATABASE DATABASE_NAME TO DATABASE_USERNAME;
    
  5. psql を終了します。

    \q
    

コードを理解する

サンプル アプリケーション

Django サンプルアプリは、Django の標準ツールを使用して作成されています。以下のコマンドは、プロジェクトと polls アプリを作成します。

django-admin startproject mysite
python manage.py startapp polls

ベースビュー、モデル、ルート構成は、最初の Django アプリを作成するパート 1およびパート 2)からコピーされました。

Secret Manager のシークレット

settings.py ファイルには、Secret Manager Python API を使用して指定されたシークレットの最新バージョンを取得し、(django-environ を使用して)その環境に pull するコードが含まれています。

env = environ.Env(DEBUG=(bool, False))
env_file = os.path.join(BASE_DIR, ".env")

if os.path.isfile(env_file):
    # Use a local secret file, if provided

    env.read_env(env_file)
# ...
elif os.environ.get("GOOGLE_CLOUD_PROJECT", None):
    # Pull secrets from Secret Manager
    project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")

    client = secretmanager.SecretManagerServiceClient()
    settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
    name = f"projects/{project_id}/secrets/{settings_name}/versions/latest"
    payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")

    env.read_env(io.StringIO(payload))
else:
    raise Exception("No local .env or GOOGLE_CLOUD_PROJECT detected. No secrets found.")

シークレットは、構成する必要のあるさまざまなシークレットの数を減らすために、複数のシークレット値を格納するために使用されます。

ローカル シークレットのオーバーライド

.env ファイルがローカル ファイル システムで見つかった場合は、Secret Manager の値の代わりに使用されます。ローカルで .env ファイルを作成すると、ローカルでのテストに役立ちます(例: SQLite データベースに対してローカルで開発する場合など)。

データベースへの接続

settings.pyファイルには、SQL データベースの構成が含まれています。USE_CLOUD_SQL_AUTH_PROXY を設定すると、DATABASES 設定が Cloud SQL Auth プロキシの使用を推測するように変更されます。

# Use django-environ to parse the connection string
DATABASES = {"default": env.db()}

# If the flag as been set, configure to use proxy
if os.getenv("USE_CLOUD_SQL_AUTH_PROXY", None):
    DATABASES["default"]["HOST"] = "127.0.0.1"
    DATABASES["default"]["PORT"] = 5432

ホストされる静的コンテンツ

app.yamlファイルには、App Engine にデプロイするための構成情報が含まれています。 この app.yaml ファイルは、App Engine が static/ ディレクトリから静的ファイルを提供することを示します。

runtime: python39

handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
  static_dir: static/

# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
  script: auto

アプリを DEBUG を有効にしてローカルで実行すると、これらのファイルは Django によってローカルで提供されます。

from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("", include("polls.urls")),
    path("admin/", admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトの削除

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ