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. Make sure that billing is enabled for your Cloud project. Learn how to confirm that billing is enabled for your project.

  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. wget コマンドが見つからない場合は、sudo apt-get install wget abd を実行してダウンロード コマンドを繰り返します。
    3. 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. [追加] をクリックします。

    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 を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ