Cloud SQL for PostgreSQL を使用して JavaScript アプリケーションを Cloud Run にデプロイする

1. 概要

Cloud Run は、HTTP リクエスト経由で呼び出し可能なステートレス コンテナを実行できるフルマネージド サーバーレス プラットフォームです。この Codelab では、Cloud Run 上の Node.js アプリケーションを Cloud SQL for PostgreSQL データベースに接続する方法について説明します。

学習内容

このラボでは、次の方法について学びます。

  • Cloud SQL for PostgreSQL インスタンス(Private Service Connect を使用するように構成)を作成する
  • Cloud SQL データベースに接続するアプリケーションを Cloud Run にデプロイする
  • Gemini Code Assist を使用してアプリケーションに機能を追加する

学習内容

  • Cloud SQL for PostgreSQL インスタンス(Private Service Connect を使用するように構成)を作成する
  • Cloud SQL データベースに接続するアプリケーションを Cloud Run にデプロイする
  • Gemini Code Assist を使用してアプリケーションに機能を追加する

2. 前提条件

  1. Google アカウントをお持ちでない場合は、Google アカウントを作成する必要があります。
    • 仕事用または学校用のアカウントではなく、個人アカウントを使用している。職場用アカウントや学校用アカウントには、このラボに必要な API を有効にできない制限が適用されている場合があります。

3. プロジェクトの設定

  1. Google Cloud コンソールにログインします。
  2. Cloud コンソールで課金を有効にする
    • このラボを完了しても、Cloud リソースの費用は 1 米ドル未満です。
    • このラボの最後にある手順に沿ってリソースを削除すると、それ以上の請求が発生しなくなります。
    • 新規ユーザーは、300 米ドル分の無料トライアルをご利用いただけます。
  3. 新しいプロジェクトを作成するか、既存のプロジェクトを再利用するかを選択します。

4. Cloud Shell エディタを開く

  1. Cloud Shell エディタに移動します。
  2. ターミナルが画面の下部に表示されない場合は、開きます。
    • ハンバーガー メニュー ハンバーガー メニュー アイコン をクリックします。
    • [Terminal] をクリックします。
    • [New Terminal] をクリックします。Cloud Shell エディタで新しいターミナルを開く
  3. ターミナルで、次のコマンドを使用してプロジェクトを設定します。
    • 形式:
      gcloud config set project [PROJECT_ID]
      
    • 例:
      gcloud config set project lab-project-id-example
      
    • プロジェクト ID がわからない場合:
      • すべてのプロジェクト ID を一覧表示するには、次のコマンドを使用します。
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Cloud Shell エディタのターミナルでプロジェクト ID を設定する
  4. 承認を求められたら、[承認] をクリックして続行します。クリックして Cloud Shell を承認する
  5. 次のようなメッセージが表示されます。
    Updated property [core/project].
    
    WARNING が表示され、Do you want to continue (Y/N)? を求められた場合は、プロジェクト ID が正しく入力されていない可能性があります。N キー、Enter キーを押して、gcloud config set project コマンドをもう一度実行してみてください。

5. API を有効にする

ターミナルで、API を有効にします。

gcloud services enable \
  compute.googleapis.com \
  sqladmin.googleapis.com \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  networkconnectivity.googleapis.com \
  servicenetworking.googleapis.com \
  cloudaicompanion.googleapis.com

承認を求められたら、[承認] をクリックして続行します。クリックして Cloud Shell を承認する

このコマンドが完了するまで数分かかる場合がありますが、最終的には次のような成功メッセージが表示されます。

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.

6. サービス アカウントを設定する

Cloud Run で使用する Google Cloud サービス アカウントを作成し、Cloud SQL に接続するための適切な権限を付与します。

  1. 次のように gcloud iam service-accounts create コマンドを実行して、新しいサービス アカウントを作成します。
    gcloud iam service-accounts create quickstart-service-account \
      --display-name="Quickstart Service Account"
    
  2. 次のように gcloud projects add-iam-policy-binding コマンドを実行して、作成した Google Cloud サービス アカウントにログ書き込みのロールを追加します。
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
      --member="serviceAccount:quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter"
    

7. Cloud SQL インスタンスを作成する

  1. Private Service Connect を使用して Cloud Run から Cloud SQL へのネットワーク接続を許可する Service Connection ポリシーを作成する
    gcloud network-connectivity service-connection-policies create quickstart-policy \
        --network=default \
        --project=${GOOGLE_CLOUD_PROJECT} \
        --region=us-central1 \
        --service-class=google-cloud-sql \
        --subnets=https://www.googleapis.com/compute/v1/projects/${GOOGLE_CLOUD_PROJECT}/regions/us-central1/subnetworks/default
    
  2. データベースの一意のパスワードを生成する
    export DB_PASSWORD=$(openssl rand -base64 20)
    
  3. gcloud sql instances create コマンドを実行して Cloud SQL インスタンスを作成する
    gcloud sql instances create quickstart-instance \
        --project=${GOOGLE_CLOUD_PROJECT} \
        --root-password=${DB_PASSWORD} \
        --database-version=POSTGRES_17 \
        --tier=db-perf-optimized-N-2 \
        --region=us-central1 \
        --ssl-mode=ENCRYPTED_ONLY \
        --no-assign-ip \
        --enable-private-service-connect \
        --psc-auto-connections=network=projects/${GOOGLE_CLOUD_PROJECT}/global/networks/default
    

このコマンドは完了までに数分かかる場合があります。

  1. gcloud sql databases create コマンドを実行して、quickstart-instance 内に Cloud SQL データベースを作成します。
    gcloud sql databases create quickstart_db \
      --instance=quickstart-instance
    

8. 申請書類を準備する

HTTP リクエストに応答する Node.js アプリケーションを準備します。

  1. Cloud Shell で、helloworld という名前の新しいディレクトリを作成し、そのディレクトリに移動します。
    mkdir helloworld
    cd helloworld
    
  2. package.json ファイルをモジュールとして初期化します。
    npm init -y
    npm pkg set type="module"
    npm pkg set main="index.mjs"
    npm pkg set scripts.start="node index.mjs"
    
  3. pg をインストールして、PostgreSQL データベースを操作します。
    npm install pg
    
  4. express をインストールして、受信 HTTP リクエストを受け入れます。
    npm install express
    
  5. アプリケーション コードを含む index.mjs ファイルを作成します。このコードは次のことができます。
    • HTTP リクエストを承認する
    • データベースに接続する
    • HTTP リクエストの時刻をデータベースに保存する
    • 過去 5 件のリクエストの時間を返す
    Cloud Shell で次のコマンドを実行します。
    cat > index.mjs << "EOF"
    import express from 'express';
    import pg from 'pg';
    const { Pool } = pg;
    
    const pool = new Pool({
      host: process.env.DB_HOST,
      user: process.env.DB_USER,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME,
      ssl: {
        require: true,
        rejectUnauthorized: false, // required for self-signed certs
        // https://node-postgres.com/features/ssl#self-signed-cert
      }
    });
    
    const app = express();
    
    app.get('/', async (req, res) => {
      await pool.query('INSERT INTO visits(created_at) VALUES(NOW())');
      const {rows} = await pool.query('SELECT created_at FROM visits ORDER BY created_at DESC LIMIT 5');
      console.table(rows); // prints the last 5 visits
      res.send(rows);
    });
    
    const port = parseInt(process.env.PORT) || 8080;
    app.listen(port, async () => {
      console.log('process.env: ', process.env);
      await pool.query(`CREATE TABLE IF NOT EXISTS visits (
        id SERIAL NOT NULL,
        created_at timestamp NOT NULL,
        PRIMARY KEY (id)
      );`);
      console.log(`helloworld: listening on port ${port}`);
    });
    
    EOF
    

このコードは、PORT 環境変数で定義されたポートをリッスンする基本的なウェブサーバーを作成します。これで、アプリケーションをデプロイする準備が整いました。

9. アプリケーションを Cloud Run にデプロイする

  1. 次のように gcloud projects add-iam-policy-binding コマンドを実行して、作成する Cloud Run サービスの Cloud Run サービス アカウントにネットワーク ユーザーのロールを追加します。
    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
    --member "serviceAccount:service-$(gcloud projects describe ${GOOGLE_CLOUD_PROJECT} --format="value(projectNumber)")@serverless-robot-prod.iam.gserviceaccount.com" \
    --role "roles/compute.networkUser"
    
  1. 次のコマンドを実行して、アプリケーションを Cloud Run にデプロイします。
    gcloud run deploy helloworld \
      --region=us-central1 \
      --source=. \
      --set-env-vars DB_NAME="quickstart_db" \
      --set-env-vars DB_USER="postgres" \
      --set-env-vars DB_PASSWORD=${DB_PASSWORD} \
      --set-env-vars DB_HOST="$(gcloud sql instances describe quickstart-instance --project=${GOOGLE_CLOUD_PROJECT} --format='value(settings.ipConfiguration.pscConfig.pscAutoConnections.ipAddress)')" \
      --service-account="quickstart-service-account@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
      --network=default \
      --subnet=default \
      --allow-unauthenticated
    
  2. メッセージが表示されたら、YEnter を押して続行することを確認します。
    Do you want to continue (Y/n)? Y
    

数分後、アクセスする URL がアプリケーションに表示されます。

URL に移動して、アプリケーションの動作を確認します。URL にアクセスするたび、またはページを更新するたびに、直近 5 件のアクセスが JSON として返されます。

10.完了

このラボでは、以下の操作について学習しました。

  • Cloud SQL for PostgreSQL インスタンス(Private Service Connect を使用するように構成)を作成する
  • Cloud SQL データベースに接続するアプリケーションを Cloud Run にデプロイする
  • Gemini Code Assist を使用してアプリケーションに機能を追加する

クリーンアップ

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

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}