アプリ モダナイゼーションのワークショップ

1. はじめに

最終更新日: 2024 年 11 月 1 日

古い PHP アプリケーションを Google Cloud にモダナイズするにはどうすればよいですか?

この Codelab の7 分間の紹介動画をご覧ください)

オンプレミスで実行されているレガシー アプリケーションをモダナイズする必要があることはよくあります。つまり、スケーラブルで安全であり、さまざまな環境にデプロイできるようにする必要があります。

このワークショップでは、次の作業を行います。

  1. PHP アプリケーションをコンテナ化します。
  2. マネージド データベース サービス(Cloud SQL)に移行します。
  3. Cloud Run にデプロイします(GKE/Kubernetes のゼロオペレーション オプション)。
  4. Identity and Access Management(IAM)と Secret Manager を使用してアプリケーションを保護します。
  5. Cloud Build を使用して CI/CD パイプラインを定義します。Cloud Build は、GitHub や GitLab などの一般的な Git プロバイダでホストされている Git リポジトリに接続し、メインへの push などでトリガーできます。
  6. アプリケーションの写真を Cloud Storage でホストします。これはマウントを介して実現され、アプリを変更するためのコードは必要ありません。
  7. Cloud Functions(サーバーレス)でオーケストレーションされた Gemini を通じて生成 AI の機能を導入する。
  8. SLO と、新しく更新したアプリの運用について理解します。

次の手順に沿って PHP アプリケーションを段階的にモダナイズすると、スケーラビリティ、セキュリティ、デプロイの柔軟性が向上します。さらに、Google Cloud に移行すると、Google Cloud の強力なインフラストラクチャとサービスを活用して、クラウドネイティブ環境でアプリケーションをスムーズに実行できます。

これらの簡単な手順で学んだことは、言語やスタック、ユースケースが異なる独自のアプリケーションや組織にも適用できると考えています。

アプリについて

フォークするアプリケーション(MIT ライセンスコード)は、MySQL 認証を使用した基本的な PHP 5.7 アプリケーションです。このアプリの主な目的は、ユーザーが写真をアップロードし、管理者が不適切な画像にタグを付けることができるプラットフォームを提供することです。このアプリケーションには 2 つのテーブルがあります。

  • ユーザー: 管理者とともに事前コンパイル済みで提供されます。新規ユーザーは登録できます。
  • 画像:いくつかのサンプル画像が付属しています。ログインしたユーザーは新しい写真をアップロードできます。ここに魔法の要素を追加します。

目標

古いアプリケーションをモダナイズして Google Cloud に移行したいと考えています。これらのツールとサービスを活用して、スケーラビリティの向上、セキュリティの強化、インフラストラクチャ管理の自動化を行い、Cloud SQL、Cloud Run、Cloud Build、Secret Manager などのサービスを使用して、画像処理、モニタリング、データ ストレージなどの高度な機能を統合します。

445f7a9ae37e9b4d.png

さらに重要なのは、ステップごとに学習できるようにすることです。これにより、各ステップの背後にある思考プロセスを学習できます。通常、各ステップは次のステップの新しい可能性を開きます(例: モジュール 2 -> 3、6 -> 7)。

まだご納得いただけていないでしょうか?YouTube の7 分間の動画をご覧ください。

必要なもの

  • ブラウザを搭載し、インターネットに接続されているパソコン。
  • GCP のクレジット。近くの Google ファンに聞いてみてください。
  • gcloud コマンドが動作している。
  • ローカルで作業している場合は、こちらからダウンロードしてください。また、優れたエディタ(vscode や intellij など)も必要です。
  • すべてを「クラウド」で行う場合は、その場合は Cloud Shell を使用できます。
  • GitHub ユーザー。これは、元のコード 🧑🏻‍💻 gdgpescara/app-mod-workshop を独自の git リポジトリでブランチするために必要です。これは、独自の CI/CD パイプライン(自動 commit -> build -> deploy)を構築するために必要です。

サンプル ソリューションは次のとおりです。

このワークショップは、ローカル コンピュータから利用することも、ブラウザですべて行うこともできます。

2. クレジットの設定とフォーク

6dafc658860c0ce5.png

GCP クレジットを利用し、GCP 環境を設定する [省略可]

このワークショップを実施するには、クレジットがある請求先アカウントが必要です。独自の課金システムがすでにある場合は、この手順をスキップできます。

新しい Google Gmail アカウント(*)を作成して、GCP クレジットにリンクします。講師に GCP クレジットの利用用リンクを案内するか、bit.ly/PHP-Amarcord-credits からクレジットを利用します。

新しく作成したアカウントでログインし、手順に沿って操作します。

ff739240dbd84a30.png

(

)新しい Gmail アカウントが必要なのはなぜですか?*

アカウント(特に仕事用または生徒用のメールアドレス)が GCP に以前に接触したことがあり、組織のポリシーにより、その機能を制限されているため、Codelab を完了できないという報告が寄せられています。新しい Gmail アカウントを作成するか、GCP に慣れていない既存の Gmail アカウント(gmail.com)を使用することをおすすめします。

ボタンをクリックしてクレジットを適用してください。

331658dc50213403.png

次のフォームに名前と姓を入力し、利用規約に同意します。

https://console.cloud.google.com/billing に請求先アカウントが表示されるまでに数秒かかることがあります。

完了したら、Google Cloud コンソールを開き、左上のプルダウン メニューにある [プロジェクトの選択] をクリックして、[組織なし] が表示されている新しいプロジェクトを作成します。以下をご覧ください。

bd7548f78689db0b.png

プロジェクトがない場合は、次のスクリーンショットに示すように新しいプロジェクトを作成します。右上に [新しいプロジェクト] オプションがあります。

6c82aebcb9f5cd47.png

新しいプロジェクトを GCP トライアルの請求先アカウントにリンクします。

f202527d254893fb.png

Google Cloud Platform を使用する準備が整いました。初心者の方や、Cloud 環境ですべての操作を行う場合は、左上の次のボタンから Cloud Shell とそのエディタにアクセスできます。

7d732d7bf0deb12e.png

左上で新しいプロジェクトが選択されていることを確認します。

未選択(悪い):

c2ffd36a781b276a.png

選択済み(良好):

594563c158f4f590.png

GitHub からアプリをフォークする

  1. デモアプリ(https://github.com/gdgpescara/app-mod-workshop)に移動します。
  2. XXXXX のフォークをクリックします。
  3. GitHub アカウントをお持ちでない場合は、新しいアカウントを作成する必要があります。
  4. 必要に応じて内容を編集します。

734e51bfc29ee5df.png

  1. git clone https://github.com/<YOUR-GITHUB-USER>/<YOUR-REPO-NAME> を使用して、アプリコードのクローンを作成します。
  1. クローンを作成したプロジェクト フォルダを任意のエディタで開きます。Cloud Shell を使用する場合は、以下のように [エディタを開く] をクリックして開くことができます。

40f5977ea4c1d1cb.png

次の図に示すように、Google Cloud Shell エディタには必要なものがすべて揃っています。

a4e5ffb3e9a35e84.png

3. モジュール 1: SQL インスタンスを作成する

645902e511a432a6.png

Google Cloud SQL インスタンスを作成する

PHP アプリは MySQL データベースに接続するため、スムーズに移行するには、そのデータベースを Google Cloud に複製する必要があります。Cloud SQL は、Cloud でフルマネージド MySQL データベースを実行できるため、最適な選択肢です。手順は次のとおりです。

  1. Cloud SQL ページ(https://console.cloud.google.com/sql/instances)に移動します。
  2. [インスタンスを作成] をクリックします。
  3. API を有効にします(必要な場合)。この処理には数秒かかることがあります。
  4. MySQL を選択します。
  5. (Google は、より長持ちする最も安価なバージョンをお届けできるよう努めています)。
  • エディション: Enterprise
  • プリセット: 開発(サンドボックスを試しましたが、うまくいきませんでした)
  • Mysql Ver: 5.7(懐かしい!)
  1. インスタンス ID: appmod-phpapp を選択します(変更する場合は、今後のスクリプトとソリューションも変更してください)。
  2. パスワード: 任意のパスワードを指定します。ただし、CLOUDSQL_INSTANCE_PASSWORD としてメモしておきます。
  3. リージョン: アプリの他の部分で選択したものと同じ値を維持します(例: ミラノ = europe-west8
  4. ゾーン アベイルズ: シングルゾーン(このデモでは費用を節約できます)

[インスタンスの作成] ボタンをクリックして Cloud SQL データベースをデプロイします。⌛完了まで 10 分ほどかかります⌛。その間、ドキュメントの続きを読むことができます。また、次のモジュール(「PHP アプリをコンテナ化する」)の解決を開始することもできます。このモジュールは、最初のパートのこのモジュールに依存していません(DB 接続を修正するまで)。

注: このインスタンスの費用は 1 日あたり約 7 ドルです。ワークショップの終了後に必ず分離してください。

Cloud SQL に image_catalog DB とユーザーを作成する

アプリ プロジェクトには、次の 2 つの sql ファイルを含む db/ フォルダが付属しています。

  1. 01_schema.sql : Users データと Images データを含む 2 つのテーブルを作成する SQL コードが含まれています。
  2. 02_seed.sql: 前に作成したテーブルにデータをシードする SQL コードが含まれています。

これらのファイルは、後で image_catalog データベースが作成されたときに使用されます。手順は次のとおりです。

  1. インスタンスを開き、[データベース] タブをクリックします。
  2. [データベースを作成] をクリックします。
  3. image_catalog という名前を付けます(PHP アプリの構成と同じ)。

997ef853e5ebd857.png

次に、データベース ユーザーを作成します。これにより、image_catalog データベースへの認証が可能になります。

  1. [ユーザー] タブをクリックします。
  2. [ユーザー アカウントを追加] をクリックします。
  3. ユーザー: ユーザーを作成します。
  • ユーザー名: appmod-phpapp-user
  • パスワード: 覚えやすいパスワードを入力するか、[生成] をクリックします。
  • [すべてのホストを許可する(%)] のままにします。
  1. [追加] をクリックします。

DB を既知の IP に開く。

Cloud SQL のすべての DB は「分離」状態で作成されます。アクセス元となるネットワークを明示的に設定する必要があります。

  1. インスタンスをクリックします。
  2. メニュー [接続] を開きます。
  3. [ネットワーキング] タブをクリックします。
  4. [承認済みネットワーク] をクリックします。次に、サブネットを追加します。
  • アプリを動作させるため、今は安全でない状態にします。
  • 名前: 「世界中の全員 - 安全でない」(この安価なソリューションは安全でないことにも注意してください)。
  • ネットワーク: 「0.0.0.0/0」(注: 安全ではありません)

[保存] をクリックします。

次のように表示されます。

5ccb9062a7071964.png

注: このソリューションは、ワークショップを O(時間) で終了するための良い妥協案です。ただし、本番環境でソリューションを保護するには、セキュリティのドキュメントをご覧ください。

DB 接続をテストします。

前に作成した image_catalog ユーザーが機能するかどうかを確認しましょう。インスタンス内の Cloud SQL Studio にアクセスし、認証するデータベース、ユーザー、パスワードを次のように入力します。

d56765c6154c11a4.png

これで、SQL エディタを開いて次のセクションに進むことができます。

コードベースからデータベースをインポートする

SQL エディタを使用して、image_catalog テーブルとそのデータをインポートします。リポジトリ内の SQL ファイルから SQL コードを取得し、順番に実行します。01_schema.sql02_seed.sql の順に実行します。

その後、image_catalog に 2 つのテーブル(usersimages)が作成されます。

65ba01e4c6c2dac0.png

エディタで select * from images; を実行してテストできます。

また、パブリック IP アドレスもメモしておいてください。後で必要になります。

4. モジュール 2: PHP アプリをコンテナ化する

e7f0e9979d8805f5.png

このアプリをクラウド用に構築します。

つまり、Cloud で実行するためのすべての情報を含む ZIP ファイルにコードをパッケージ化します。

パッケージ化にはいくつかの方法があります。

  • Docker。非常に人気がありますが、正しく設定するのは非常に複雑です。
  • Buildpack。あまり一般的ではありませんが、何をビルドして何を実行するかを「自動的に推測」する傾向があります。多くの場合、問題なく動作します。

このワークショップでは、Docker を使用するものと想定しています。

Docker

ご自身で管理したい場合は、これが最適なソリューションです。これは、特定のライブラリを構成し、特定のわかりにくい動作(アップロードの chmod、アプリ内の標準以外の実行可能ファイルなど)を挿入する必要がある場合に適しています。

最終的にはコンテナ化されたアプリケーションを Cloud Run にデプロイするため、次のドキュメントを確認し、空白に記入してみます。現時点では、簡単に使用できるように必要な機能のみを提供しています。最終的な Dockerfile は次のようになります。

# Use an official PHP image with Apache
# Pull a suitable php image
FROM __________# Define the env variable for the Apache listening port 8080
ENV __________

# Set working directory inside the container
WORKDIR __________

# Install required PHP extensions: PDO, MySQL, and other dependencies
RUN __________

# Copy all application files into the container
COPY __________

# Configure Apache to listen on port 8080. Use ‘sed' command to change the default listening port.
RUN __________

# When in doubt, always expose to port 8080
EXPOSE __________

# Start Apache in the foreground
CMD __________

また、ローカルでアプリケーションをテストするには、config.php ファイルを変更して、PHP アプリが Google CloudSQL で利用可能な MYSQL データベースに接続するようにする必要があります。以前に設定した内容に基づいて、空欄に入力します。

  • db_host は Cloud SQL のパブリック IP アドレスです。コンソールで確認できます。

bd27071bf450a8d0.png

  • db_name は変更しないでください。image_catalog
  • Db_user は appmod-phpapp-user にする必要があります。
  • db_pass は任意の値です。単一引用符で設定し、必要に応じてエスケープします。
<?php
// Database configuration
$db_host = '____________';
$db_name = '____________';
$db_user = '____________';
$db_pass = '____________';

try {
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Errore di connessione: " . $e->getMessage());
}

session_start();
?>

また、Gemini を使って、イタリア語の文章を英語に翻訳することもできます。

Dockerfile を入手し、データベースに接続するように PHP アプリを構成したので、試してみましょう。

Docker をまだインストールしていない場合は、インストールします(リンク)。Cloud Shell を使用している場合は、これは必要ありません(これは素晴らしい機能です)。

適切な Docker ビルドと実行コマンドを使用して、コンテナ化された PHP アプリをビルドして実行してみましょう。

  • docker build -t <IMAGE_TAG_NAME> .
  • docker run -it -p <CONTAINER PORT>:<LOCAL MACHINE PORT> <IMAGE_TAG_NAME>

すべてが正常に動作している場合は、ローカルホストに接続すると次のウェブページが表示されます。

Cloud Shell を使用している場合は、次のようにローカルポート(8080 など)をブラウザにエクスポートすることもできます。

docker build -t my-php-app-docker app-mod-workshop/ -f Dockerfile

docker run -it -p 8080:8080 my-php-app-docker

アプリがポート 8080 で実行されていることを確認したら、[ウェブでプレビュー] アイコン(目付きのブラウザ)をクリックし、[ポート 8080 でプレビュー](または他のポートの場合は [ポートの変更])をクリックします。

33a24673f4550454.png

ブラウザで結果をテストする

アプリケーションは次のようになります。

2718ece96b1f18b6.png

Admin/admin123 でログインすると、次のように表示されます。

68b62048c2e86aea.png

ありがとうございます。動作しています 🎉🎉🎉

Docker 化は問題ないが DB 認証情報が間違っている場合は、次のようなエラーが発生することがあります。

e22f45b79bab86e1.png

もう一度お試しください。

Buildpack [省略可]

Buildpack を使用すると、アプリが自動的にビルドされます。残念ながら、完全に制御できないため、予期しない構成が発生する可能性があります。

ローカル環境に新しい Docker イメージが作成されているはずです。コンテナを実行することもできますが、Google ではイメージのビルド方法を完全に制御できないため、アプリが動作しない可能性があります。いずれにしても、テストしていただき、うまくいけばご意見をお聞かせください。

Artifact Registry への保存 [省略可]

これで、クラウドにデプロイする準備ができているコンテナ化された PHP アプリケーションが完成しました。次に、Docker イメージを保存し、Cloud Run などの Google Cloud サービスにデプロイできるようにアクセスできる場所をクラウド内に用意する必要があります。このストレージ ソリューションは Artifact Registry と呼ばれ、Docker コンテナ イメージ、Maven パッケージ、npm モジュールなどのアプリケーション アーティファクトを保存するように設計されたフルマネージド Google Cloud サービスです。

適切なボタンを使用して、Google Cloud Artifact Registry にリポジトリを作成しましょう。

e1123f0c924022e6.png

アーティファクトの保存に適した有効な名前、形式、リージョンを選択します。

4e516ed209c470ee.png

ローカル開発環境のタグに戻り、作成した Artifact Registry リポジトリに App コンテナ イメージを push します。次のコマンドを実行します。

  • docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
  • docker push TARGET_IMAGE[:TAG]

結果は次のスクリーンショットのようになります。

1e498feb4e88be9f.png

やったね🎉?🎉?🎉?次のレベルに進みましょう。

注:また、/upload.php エンドポイントを試して、画像をアップロードしてみます。「権限が拒否されました」というメッセージが表示されることがあります。その場合は、Dockerfilechmod/chown の修正を行う必要があります。

5. モジュール 3: アプリを Cloud Run にデプロイする

9ffca42774f6c5d1.png

Cloud Run を選ぶ理由

お問い合わせいただきありがとうございます。数年前であれば、Google App Engine を選択していたでしょう。

簡単に言うと、Cloud Run は新しいテクノロジー スタックを使用しており、デプロイが簡単で、費用が低く、使用していないときは 0 にスケールダウンします。任意のステートレス コンテナを柔軟に実行でき、さまざまな Google Cloud サービスと統合できるため、オーバーヘッドを最小限に抑え、効率を最大限に高めてマイクロサービスと最新のアプリケーションをデプロイするのに最適です。

具体的には、Cloud Run は Google Cloud のフルマネージド プラットフォームであり、サーバーレス環境でステートレスなコンテナ化されたアプリケーションを実行できます。すべてのインフラストラクチャを自動的に処理し、受信トラフィックに合わせてゼロからスケールアップし、アイドル状態のときにスケールダウンするため、費用対効果が高く効率的です。Cloud Run は、コンテナにパッケージ化されている限り、任意の言語やライブラリをサポートしているため、開発の柔軟性が大幅に向上します。他の Google Cloud サービスと統合が容易で、サーバー インフラストラクチャを管理することなく、マイクロサービス、API、ウェブサイト、イベント ドリブン アプリケーションを構築するのに適しています。

前提条件

このタスクを実行するには、ローカルマシンに gcloud がインストールされている必要があります。表示されていない場合は、こちらの手順をご覧ください。Google Cloud Shell を使用している場合は、何もする必要はありません。

デプロイする前に...

ローカル環境で作業している場合は、次のコマンドを使用して Google Cloud で認証します。

  • $ gcloud auth login –update-adc # not needed in Cloud Shell

これにより、ブラウザで OAuth ログインによる認証が行われます。課金が有効になっている Google Cloud にログインしているユーザー(vattelapesca@gmail.com など)で Chrome からログインしていることを確認します。

次のコマンドで Cloud Run API を有効にします。

  • $ gcloud services enable run.googleapis.com

これで、Cloud Run にデプロイする準備が整いました。

gcloud を使用してアプリを Cloud Run にデプロイする

Cloud Run にアプリをデプロイできるコマンドは gcloud run deploy です。目標を達成するために設定できるオプションはいくつかあります。最小セットは次のとおりです。

  1. アプリにデプロイする Cloud Run サービスの名前。Cloud Run サービスは、アプリのエンドポイントを提供する URL を返します。
  2. アプリを実行する Google Cloud リージョン
  3. アプリをラップするコンテナ イメージ
  4. 環境変数。アプリが実行時に使用する必要があります。
  5. すべてのユーザーが追加の認証なしでアプリにアクセスできるようにする Allow-Unauthenticated フラグ

このオプションをコマンドに適用する方法については、ドキュメントをご覧ください。デプロイには数分かかります。すべてが正しい場合は、Google Cloud コンソールに次のように表示されます。

ef1029fb62f8de81.png

f7191d579c21ca3e.png

Cloud Run から提供された URL をクリックして、アプリケーションをテストします。認証が完了すると、次のように表示されます。

d571a90cd5a373f9.png

「質問なし」の「gcloud run deploy」

gcloud run deploy は適切な質問を投げかけ、空白を埋めてくれることにお気づきかと思います。これは素晴らしい!

ただし、一部のモジュールでは、このコマンドを Cloud Build トリガーに追加するため、質問を許可できません。コマンドのすべてのオプションを入力する必要があります。黄金の gcloud run deploy --option1 blah --foo bar --region your-fav-region を作成します。どうすればよいですか。

  1. gcloud が質問を停止するまで、手順 2~3~4 を繰り返します。
  2. [ループ] これまでに見つかったオプションを含む gcloud run deploy
  3. [ループ] システムがオプション X を要求する
  4. [ループ] オプション --my-option [my-value] を追加して CLI から X を設定する方法を公開ドキュメントで検索します。
  5. 他に質問なしで gcloud が完了した場合を除き、ここでステップ 2 に戻ります。
  6. この gcloud run deploy BLAH BLAH BLAH Rocks!コマンドを任意の場所に保存します。後で Cloud Build のステップで必要になります。

考えられる解決策はこちらにあります。

やったね 🎉🎉🎉 Google Cloud にアプリを正常にデプロイし、モダナイゼーションの最初のステップを完了しました。

6. モジュール 4: Secret Manager でパスワードをクリーンアップする

95cd57b03b4e3c73.png

前のステップでは、Cloud Run にアプリをデプロイして実行することができました。ただし、セキュリティの悪い方法(シークレットをクリアテキストで提供する)で実現しました。

最初の反復処理: ENV を使用するように config.php を更新する

config.php ファイルのコードに DB のパスワードが直接入力されていることにお気づきかもしれません。これは、テスト目的やアプリが動作するかどうかを確認する目的では問題ありません。ただし、本番環境でこのようなコードを commit または使用することはできません。パスワード(およびその他の DB 接続パラメータ)は動的に読み取られ、実行時にアプリに提供される必要があります。ENV 変数から db パラメータを読み取るように config.php ファイルを変更します。失敗した場合は、デフォルト値の設定を検討してください。これは、ENV の読み込みに失敗した場合に、デフォルト値が使用されているかどうかをページ出力で確認できるため便利です。config.php で空欄を埋めてコードを置き換えます。

<?php
// Database configuration with ENV variables. Set default values as well 
$db_host = getenv('DB_HOST') ?: _______;
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: _______;
// Note getenv() is PHP 5.3 compatible
try {
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Errore di connessione: " . $e->getMessage());
}

session_start();
?>

アプリがコンテナ化されているため、ENV 変数をアプリに提供する方法を提供する必要があります。これは、次の方法で行うことができます。

  • ビルド時に Dockerfile で。前の Dockerfile に構文 ENV DB_VAR=ENV_VAR_VALUE を使用して、4 つのパラメータを追加します。これによりデフォルト値が設定され、実行時にオーバーライドできます。たとえば、「DB_NAME」と「DB_USER」は、ここでのみ設定できます。
  • 実行時。Cloud Run のこれらの変数は、CLI または UI の両方で設定できます。(Dockerfile でデフォルトを設定する場合を除き)4 つの変数をすべてここに配置します。

localhost では、ENV 変数を .env ファイルに配置することをおすすめします(solutions フォルダを参照)。

また、.env が .gitignore に追加されていることを確認してください。シークレットを GitHub に push したくありません。

echo .env >> .gitignore

その後、インスタンスをローカルでテストできます。

docker run -it -p 8080:8080 --env-file .env my-php-app-docker

これで次のことができるようになりました。

  1. アプリは ENV から変数を動的に読み取ります。
  2. コードから DB パスワードを削除したため、セキュリティが強化されました)。

これで、新しいリビジョンを Cloud Run にデプロイできます。UI に移動して、環境変数を手動で設定しましょう。

  • https://console.cloud.google.com/run に移動します。
  • アプリをクリックします。
  • [新しいリビジョンの編集とデプロイ] をクリックします。
  • 最初のタブ [コンテナ] で、下のタブ [変数とシークレット] をクリックします。
  • [+ 変数を追加] をクリックして、必要な変数をすべて追加します。結果は次のようになります。

7a5fbfa448544d3.png

f2780c35585388ca.png

これで問題ないでしょうか?いいえ。PASS は引き続き、ほとんどのオペレーターに表示されます。これは、Google Cloud Secret Manager で軽減できます。

2 つ目のイテレーション: Secret Manager

コードからパスワードが消えました。勝利です。では、安全になったのでしょうか?

Google Cloud コンソールにアクセスできるユーザーは、引き続きパスワードを確認できます。実際、Cloud Run YAML デプロイ ファイルにアクセスすると、そのファイルを取得できます。また、Cloud Run の新しいリビジョンを編集またはデプロイしようとすると、以下のスクリーンショットに示すように、[変数とシークレット] セクションにパスワードが表示されます。

Google Cloud Secret Manager は、API キー、パスワード、証明書などのシークレットなどの機密情報を管理するための安全で集中的なサービスです。

きめ細かな権限と堅牢な暗号化により、シークレットの保存、管理、アクセスを行うことができます。Secret Manager は Google Cloud の Identity and Access Management(IAM)と統合されているため、特定のシークレットにアクセスできるユーザーを制御し、データ セキュリティと規制遵守を確保できます。

また、シークレットの自動ローテーションとバージョニングもサポートしているため、シークレットのライフサイクル管理を簡素化し、Google Cloud サービス全体のアプリケーションのセキュリティを強化できます。

Secret Manager にアクセスするには、ハンバーガー メニューから [セキュリティ] サービスに移動し、下のスクリーンショットに示すように [データ保護] セクションで見つけます。

6df83a1c3cb757f6.png

次の図のように、Secret Manager API を有効にします。

a96c312e2c098db1.png

  • [シークレットを作成] をクリックします。合理的な名前を付けましょう。
  • 名前: php-amarcord-db-pass
  • Secret の値: DB パスワード(「upload file」の部分は無視)
  • このシークレット リンクにアノテーションを付けます。projects/123456789012/secrets/php-amarcord-db-pass のようになります。これは、シークレットへの一意のポインタです(Terraform、Cloud Run など)。この番号は固有のプロジェクト番号です。

ヒント: シークレットには、左から右に特化した一貫した命名規則を使用することをおすすめします(例: cloud-devrel-phpamarcord-dbpass)。

  • 組織(会社)
  • チーム(組織内)
  • 申請(チーム内)
  • 変数名(アプリ内)

これにより、単一アプリのすべてのシークレットを簡単に正規表現で見つけることができます。

新しい Cloud Run リビジョンを作成する

新しい Secret を用意できたので、DB_PASS ENV 変数を削除し、新しい Secret で置き換える必要があります。それによって次のようになります。

  • Google Cloud コンソールを使用した Cloud Run へのアクセス
  • アプリを選択します。
  • [新しいリビジョンの編集とデプロイ] をクリックします。
  • [変数とシークレット] タブを見つけます。
  • [+ シークレットを参照] ボタンを使用して、DB_PASS ENV 変数をリセットします。
  • 参照されるシークレットには同じ「DB_PASS」を使用し、最新バージョンを使用します。

9ed4e35be7654dcb.png

完了すると、次のようなエラーが表示されます。

da0ccd7af39b04ed.png

解決方法を探します。この問題を解決するには、[IAM と管理] セクションにアクセスして、付与する権限を変更する必要があります。ぜひデバッグをお楽しみください!

原因を特定したら、Cloud Run に戻って新しいリビジョンを再デプロイします。結果は次の図のようになります。

e89f9ca780169b6b.png

ヒント: デベロッパー コンソール(UI)は、権限に関する問題を特定するのに便利です。時間をかけて Cloud エンティティのすべてのリンクをナビゲートしてください。

7. モジュール 5: Cloud Build を使用して CI/CD を設定する

ba49b033c11be94c.png

CI / CD パイプラインを使用する理由

ここまでで、gcloud run deploy を数回入力し、同じ質問に何度も回答したはずです。

gcloud run deploy を使用してアプリを手動でデプロイするのは面倒ですか?新しい変更を Git リポジトリに push するたびに、アプリが自動的にデプロイされたら便利だと思いませんか?

CI / CD パイプラインを使用するには、次の 2 つが必要です。

  1. 個人用 Git リポジトリ: 幸いなことに、ステップ 2 ですでにワークショップ リポジトリが GitHub アカウントにフォークされているはずです。実行されていない場合は、前のステップに戻って完了します。フォークされたリポジトリは次のようになります。https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
  2. Cloud Build。この驚くべき安価なサービスを使用すると、Terraform、Docker 化されたアプリなど、ほぼすべてのビルド自動化を構成できます。

このセクションでは、Cloud Build の設定に焦点を当てます。

そこで、Cloud Build の登場です。

Cloud Build を使用して、次の操作を行います。

  • (Dockerfile を使用して)ソースをビルドします。これは、ビルドと実行に必要なすべてのもの(ビルド アーティファクト)を含む「大きな .zip ファイル」だと考えてください。
  • そのアーティファクトを Artifact Registry(AR)に push します。
  • 次に、アプリ「php-amarcord」の AR から Cloud Run へのデプロイを行います。
  • これにより、既存のアプリの新しいバージョン(新しいコードを含むレイヤ)が作成され、プッシュが成功するとトラフィックを新しいバージョンに転送するように構成されます。

以下は、php-amarcord アプリのビルドの例です。

f30f42d4571ad5e2.png

これらはどのように行いますか?

  1. 完璧な YAML ファイル cloudbuild.yaml を作成します。
  2. Cloud Build トリガーを作成する。
  3. Cloud Build UI から GitHub リポジトリに接続します。

トリガーを作成する(およびリポジトリを接続)

  • https://console.cloud.google.com/cloud-build/triggers に移動します。
  • [トリガーを作成] をクリックします。
  • コンパイル:
  • 名前: on-git-commit-build-php-app のようなわかりやすい名前
  • イベント: ブランチへの push
  • ソース: [新しいリポジトリに接続] 代替テキスト
  • 右側に [リポジトリを接続] ウィンドウが開きます。
  • ソース プロバイダ: 「Github」(1 つ目)
  • [続行]
  • 認証すると、GitHub でクロス認証を行うウィンドウが開きます。手順に沿って対応し、忍耐強く待ちます。リポジトリが多い場合は、時間がかかることがあります。
  • [Select repo] でアカウントまたはリポジトリを選択し、[I understand...] にチェックを入れます。
  • 「GitHub アプリは、どのリポジトリにもインストールされていません」というエラーが表示された場合は、[Google Cloud Build をインストール] をクリックして手順に沿って操作します。
  • 23e0e0f1219afea3.png[接続] をクリックします
  • bafd904ec07122d2.png
  • 当たり!これでリポジトリが接続されました。
  • トリガー部分に戻ります。
  • 構成: 自動検出 (*)
  • 詳細: サービス アカウント「[PROJECT_NUMBER]-compute@developer.gserviceaccount.com」を選択します。
  • xxxxx はプロジェクト ID です。
  • デフォルトのコンピューティング サービス アカウントはラボ環境では適切ですが、本番環境では使用しないでください。(詳細)。
  • 他はそのままにします。
  • [作成] ボタンをクリックします。

(*) Dockerfile または cloudbuild.yaml をチェックするため、最も簡単な方法です。ただし、cloudbuild.yaml を使用すると、どのステップで何を行うかを柔軟に決定できます。

電源が入りました。

これで、Cloud Build サービス アカウント(サービス アカウントとはユーザーの代わりにタスク(この場合は、クラウドでのものの構築)を代行する「ロボット」のメール)。

SA に権限を付与しない限り、SA はビルドとデプロイを行うことができません。幸い、手順は簡単です。

  • [Cloud Build] > [Settings] に移動します。
  • 「[PROJECT_NUMBER]- compute@developer.gserviceaccount.com」サービス アカウント
  • 次のチェックボックスをオンにします。
  • Cloud Run
  • Secret Manager
  • サービス アカウント
  • Cloud Build
  • [優先サービス アカウントとして設定] もオンにします。

8715acca72286a46.png

Cloud Build YAML はどこにありますか?

独自の Cloud Build YAML を作成することを強くおすすめします。

ただし、時間がない、または時間を割けない場合は、.solutions ソリューション フォルダでヒントを得ることができます。

これで、変更を GitHub に push し、Cloud Build をモニタリングできるようになりました。

Cloud Build の設定は複雑な場合があります。以下の点にご留意ください。

  • https://console.cloud.google.com/cloud-build/builds;region=global でログを確認する
  • エラーを見つける。
  • コードを修正し、git commit / git push を再発行します。
  • エラーがコードではなく、設定にある場合もあります。その場合は、UI から新しいビルドを発行できます([Cloud Build] > [トリガー] > [実行])。

97acd16980a144ab.png

このソリューションを使用する場合は、まだいくつかの作業が必要です。たとえば、新しく作成された dev/prod エンドポイントの ENV 変数を設定する必要があります。

3da8723e4ff80c0a.png

作成する方法は次の 2 つです。

  • UI 経由 - ENV 変数を再度設定する
  • CLI で「完璧」なスクリプトを作成します。例は、gcloud-run-deploy.sh にあります。エンドポイントやプロジェクト番号など、いくつかの調整が必要です。プロジェクト番号は [Cloud の概要] で確認できます。

GitHub にコードを commit するにはどうすればよいですか?

GitHub に git push を移行する最適な方法については、このワークショップの範囲外です。ただし、Cloud Shell で先に進まない場合は、次の 2 つの方法があります。

  1. CLI。ローカルに SSH 認証鍵を追加し、git@github.com:YOUR_USER/app-mod-workshop.git(http の代わりに)を使用してリモートを追加します。
  2. VSCode。Cloud Shell エディタを使用している場合は、[ソース管理](Ctrl+Shift+G)タブを使用して [変更を同期] をクリックし、手順に沿って操作します。自分の GitHub アカウントを vscode で認証すれば、そこから簡単に pull/push できます。

f0d53f839c7fa3b6.png

他のファイルと一緒に git add clodubuild.yaml にする必要があります。そうしないと機能しません。

深い部分と浅い部分の「開発/本番環境の同等」 [省略可]

こちらからモデル バージョンをコピーした場合、DEV バージョンと PROD バージョンが 2 つ作成されます。これは、The Twelve-Factor App のルール 10 に沿っています。

しかし、2 つの異なるウェブ エンドポイントを使用して、アプリが同じデータベースを参照するようにしています。これはワークショップでは十分ですが、実際の環境では、適切な本番環境を構築するために時間をかける必要があります。つまり、2 つのデータベース(1 つは開発用、もう 1 つは本番環境用)を用意し、障害復旧 / 高可用性のためにそれらを配置する場所を選択する必要があります。これはこのワークショップの範囲を超えていますが、検討の余地があります。

本番環境の「詳細」バージョンを作成できる場合は、複製する必要があるすべてのリソース(以下に例を示します)を念頭に置いてください。

  • Cloud SQL データベース(およびおそらく SQL インスタンス)。
  • GCS バケット
  • Cloud Functions 関数。
  • たとえば、開発中のモデルとして Gemini 1.5 Flash(低コストで高速)を使用し、本番環境では Gemini 1.5 Pro(より強力)を使用するなどです。

通常、アプリに対して何かを行うたびに、本番環境でも同じ値を使用するべきかどうかを慎重に検討してください。そうでない場合は、作業を重複させます。もちろん、Terraform を使用すると、環境(-dev、-prod)をリソースの接尾辞として挿入できるため、この作業ははるかに簡単になります。

8. モジュール 6: Google Cloud Storage に移行する

a680e0f287dd2dfb.png

ストレージ

現在、アプリは状態を Docker コンテナに保存しています。マシンが故障したり、アプリが爆発したりした場合、または単に新しいリビジョンを push すると、新しいリビジョンがスケジュールされ、ストレージはリセット(=>空)されます。🙈

解決方法はいくつかあります。

  1. 画像を DB に保存します。以前の PHP アプリでは、この方法を採用しました。複雑さを増さないため、最も簡単なソリューションです。ただし、DB のレイテンシと負荷は確実に増加します。
  2. Cloud Run アプリをストレージに優しいソリューション(GCE + 永続ディスク)に移行しますか?GKE + Storage でしょうか?
  3. GCS に移行します。Google Cloud Storage は、Google Cloud 全体に最高水準のストレージを提供し、最もクラウドに特化したソリューションです。ただし、PHP ライブラリを扱う必要があります。GCS 用の PHP 5.7 ライブラリはありますか?PHP 5.7Composer をサポートしていますか(Composer でサポートされている最も古いバージョンは PHP 5.3.2 のようです)?
  4. Docker サイドカーを使用するとよいでしょう。
  5. または、GCS の Cloud Run ボリューム マウントを使用することもできます。便利な機能ですね。

🤔 ストレージを移行する(自由形式)

[自由形式] この演習では、なんらかの方法で永続的に画像を移動するソリューションを見つけます。

受け入れテスト

解決策は申し上げませんが、次のようにしていただく必要があります。

  1. newpic.jpg をアップロードします。アプリに表示されます。
  2. アプリを新しいバージョンにアップグレードします。
  3. newpic.jpg は引き続き表示されます。

💡? 考えられる解決策(GCS Cloud Run ボリューム マウント)

これは非常にエレガントなソリューションであり、コードにまったく変更を加えずにステートフルなファイルアップロードを実現できます(画像の説明を表示する以外は、簡単な処理で視覚的な満足感を得ることができます)。

これにより、Cloud Run から GCS にフォルダをマウントできるようになります。

  1. GCS へのすべてのアップロードは、実際にアプリに表示されます。
  2. アプリへのすべてのアップロードは実際には GCS にアップロードされます
  3. GCS にアップロードされたオブジェクトに魔法が起こります(第 7 章)。

注: FUSE の利用規約をご確認ください。パフォーマンスが問題の場合は、これは適切ではありません。

GCS バケットを作成する

GCS は、Google Cloud のあらゆる場所に存在するストレージ サービスです。実証済みで、ストレージを必要とするすべての GCP サービスで使用されています。

Cloud Shell は PROJECT_ID を GOOGLE_CLOUD_PROJECT としてエクスポートします。

$ export PROJECT_ID=$GOOGLE_CLOUD_PROJECT

#!/bin/bash

set -euo pipefail

# Your Cloud Run Service Name, eg php-amarcord-dev
SERVICE_NAME='php-amarcord-dev'
BUCKET="${PROJECT_ID}-public-images"
GS_BUCKET="gs://${BUCKET}"

# Create bucket
gsutil mb -l "$GCP_REGION" -p "$PROJECT_ID" "$GS_BUCKET/"

# Copy original pictures there - better if you add an image of YOURS before.
gsutil cp ./uploads/*.png "$GS_BUCKET/"

/uploads/ フォルダにバケットをマウントするように Cloud Run を構成します。

次に、エレガントな部分に移ります。ボリューム php_uploads を作成し、MOUNT_PATH/var/www/html/uploads/ など)に FUSE マウントを実行するよう Cloud Run に指示します。

#!/bin/bash

set -euo pipefail

# .. keep variables from previous script..

# Uploads folder within your docker container.
# Tweak it for your app code.
MOUNT_PATH='/var/www/html/uploads/'

# Inject a volume mount to your GCS bucket in the right folder.
gcloud --project "$PROJECT_ID" beta run services update "$SERVICE_NAME" \
    --region $GCP_REGION \
    --execution-environment gen2 \
    --add-volume=name=php_uploads,type=cloud-storage,bucket="$BUCKET"  \
    --add-volume-mount=volume=php_uploads,mount-path="$MOUNT_PATH"

Cloud Storage を参照するすべてのエンドポイントに対して、この手順を繰り返します。

UI から同じ操作を行うこともできます。

  1. [ボリューム] タブで、バケットを参照するボリューム マウントを作成します。タイプは「Cloud Storage バケット」で、名前は「php_uploads」などです。
  2. [コンテナ] > [ボリューム マウント] で、作成したボリュームをアプリがリクエストしたボリューム ポイントにマウントします。これは Dockerfile によって異なりますが、var/www/html/uploads/ のように表示されます。

どちらの方法でも、動作すると、新しい Cloud Run リビジョンを編集すると次のような結果になります。

6c2bb98fc1b0e077.png

次に、/upload.php エンドポイントに新しい画像を 1 つアップロードする新しいアプリケーションをテストします。

PHP を 1 行も記述しなくても、画像が GCS 上でシームレスに流れるはずです。

70032b216afee2d7.png

何が起きたのですか?

魔法のようなことが起こりました。

古いコードの古いアプリケーションが今でも機能している。新しいモダナイズされたスタックにより、アプリ内のすべての画像をステートフルな Cloud バケットに簡単に配置できます。可能性は無限大です。

  • 「危険」または「ヌード」の画像が検出されるたびにメールを送信したい場合は、これは PHP コードを変更せずに行うことができます。
  • 画像が届くたびに Gemini マルチモーダル モデルを使用して画像を説明し、その説明とともに DB をアップロードしたいですか?この操作は PHP コードに手を加えずに実行できます。信じられないですか?第 7 章を続けてお読みください。

大きなビジネスチャンスが開かれました。

9. モジュール 7: Google Gemini でアプリを強化する

c00425f0ad83b32c.png

これで、Cloud に移行したストレージを備えた、最新の素晴らしい PHP アプリ(2024 Fiat 126 など)が完成しました。

用途

前提条件

前の章では、モデル ソリューションを使用して画像 /uploads/ を GCS にマウントできました。これは、アプリのロジックを画像ストレージから分離する事実です。

この演習では、次の操作を行います。

  • 6 章(ストレージ)のエクササイズを正常に完了している。
  • 画像アップロード用の GCS バケットを用意します。ユーザーがアプリで写真をアップロードすると、その写真がバケットに転送されます。

Cloud Functions の関数を設定する(Python の場合)

イベント ドリブン型のアプリケーションを実装する方法を探している次のような内容です。

  • <event> が発生したとき => メールを送信する
  • <event> が発生したとき => <condition> が true の場合、データベースを更新します。

イベントは、BigQuery で利用可能な新しいレコード、GCS のフォルダで変更された新しいオブジェクト、Pub/Sub のキューにある新しいメッセージなど、あらゆるものになります。

Google Cloud は、これを実現するために複数のパラダイムをサポートしています。主な変更点は次のとおりです。

この演習では、Cloud Functions を詳しく調べて、非常に素晴らしい結果を達成します。オプションの演習も提供されます。

サンプルコードは .solutions/ で提供されています。

Cloud Functions の関数を設定する(🐍? Python)

Google は、非常に意欲的な GCF を構築しようとしています。

  1. GCS で新しいイメージが作成された場合。(おそらく、誰かがアプリにアップロードしたためですが、それだけではありません)
  2. .. Gemini を呼び出して画像の説明を取得し、画像のテキスト形式の説明を取得します。(MIME をチェックして、PDF、MP3、テキストではなく画像であることを確認することをおすすめします)
  3. ... と、この説明で DB を更新します。(この場合、DB にパッチを適用して images テーブルに description 列を追加する必要があります)。

DB にパッチを適用して description画像に追加

  1. Cloud SQL Studio を開きます。

b92b07c4cba658ef.png

  1. Images DB のユーザーとパスワードを入力します。
  2. 画像の説明の列を追加する次の SQL を挿入します。

ALTER TABLE images ADD COLUMN description TEXT;

3691aced78a6389.png

これで、設定が反映されたかどうかを確認します。

SELECT * FROM images;

新しい説明列が表示されます。

bed69d6ad0263114.png

Gemini として f(x) を記述する

注: この関数は、Gemini Code Assist の支援を受けて作成されました。

注: この関数を作成すると、IAM 権限エラーが発生する可能性があります。一部は、下記の「考えられるエラー」の段落に記載されています。

  1. API を有効にする
  2. https://console.cloud.google.com/functions/list に移動します。
  3. [関数を作成] をクリックします。
  4. API ウィザードから API を有効にする:

d22b82658cfd4c48.png

GCF は UI またはコマンドラインから作成できます。ここではコマンドラインを使用します。

考えられるコードは .solutions/ で確認できます。

  1. コードをホストするフォルダを作成します(例: gcf/)。フォルダに移動します。
  2. requirements.txt ファイルを作成します。
google-cloud-storage
google-cloud-aiplatform
pymysql
  1. Python 関数を作成します。サンプルコード: gcf/main.py
#!/usr/bin/env python

"""Complete this"""

from google.cloud import storage
from google.cloud import aiplatform
import vertexai
from vertexai.generative_models import GenerativeModel, Part
import os
import pymysql
import pymysql.cursors

# Replace with your project ID
PROJECT_ID = "your-project-id"
GEMINI_MODEL = "gemini-1.5-pro-002"
DEFAULT_PROMPT = "Generate a caption for this image: "

def gemini_describe_image_from_gcs(gcs_url, image_prompt=DEFAULT_PROMPT):
    pass

def update_db_with_description(image_filename, caption, db_user, db_pass, db_host, db_name):
    pass

def generate_caption(event, context):
    """
    Cloud Function triggered by a GCS event.
    Args:
        event (dict): The dictionary with data specific to this type of event.
        context (google.cloud.functions.Context): The context parameter contains
                                                event metadata such as event ID
                                                and timestamp.
    """
    pass
  1. 関数を push します。gcf/push-to-gcf.sh のようなスクリプトを使用できます。

注 1. ENV に正しい値を指定するか、値を上に追加します(GS_BUCKET=blah、..)。

注 2. これにより、すべてのローカルコード(.)が push されるため、コードを特定のフォルダに配置し、プロのように .gcloudignore を使用して、巨大なライブラリを push しないようにしてください。()。

#!/bin/bash

set -euo pipefail

# add your logic here, for instance:
source .env || exit 2 

echo "Pushing ☁️ f(x)☁ to 🪣 $GS_BUCKET, along with DB config.. (DB_PASS=$DB_PASS)"

gcloud --project "$PROJECT_ID" functions deploy php_amarcord_generate_caption \
    --runtime python310 \
    --region "$GCP_REGION" \
    --trigger-event google.cloud.storage.object.v1.finalized \
    --trigger-resource "$BUCKET" \
    --set-env-vars "DB_HOST=$DB_HOST,DB_NAME=$DB_NAME,DB_PASS=$DB_PASS,DB_USER=$DB_USER" \
    --source . \
    --entry-point generate_caption \
    --gen2

: この例では、generate_caption が呼び出されるメソッドであり、Cloud Functions は関連するすべての情報(バケット名、オブジェクト名など)とともに GCS イベントを渡します。イベントの Python 辞書をデバッグしてください。

関数をテストする

単体テスト

この関数には多くの要素が含まれています。これらをすべてテストすることもできます。

たとえば、gcf/test.py を参照してください。

Cloud Functions UI

また、UI で関数を詳しく確認してください。どのタブも見てみる価値があります。特に、Source(私のお気に入り)、VariablesTriggerLogs です。Logs では、エラーのトラブルシューティングに多くの時間を費やします(このページの下部でエラーの可能性も確認します)。Permissions も必ず確認してください。

cf3ded30d532a2c7.png

E2E テスト

関数を手動でテストしましょう。

  1. アプリに移動してログインします。
  2. 写真をアップロードします(大きすぎないようにしてください。大きな画像では問題が発生することがあります)。
  3. UI で確認します
  4. Cloud SQL Studio で、説明が更新されていることを確認します。ログインして、クエリ SELECT * FROM images を実行します。

43a680b12dbbdda0.png

効果は実証済みまた、その説明を表示するようにフロントエンドを更新することもできます。

PHP を更新して表示する [省略可]

アプリが機能することを確認しました。ただ、その説明もユーザーに表示できれば便利です。

index.php に説明を追加するために PHP の専門家である必要はありません。このコードで問題ないはずです(もちろん、Gemini が作成してくれました)。

<?php if (!empty($image['description'])): ?>
    <p class="font-bold">Gemini Caption:</p>
    <p class="italic"><?php echo $image['description']; ?></p>
<?php endif; ?>

このコードは、好みに合わせて foreach 内に配置します。

次のステップでは、Gemini Code Assist のおかげで、よりきれいな UI バージョンも確認します。見栄えの良いバージョンは次のようになります。

fdc12de0c88c4464.png

まとめ

GCS に新しいオブジェクトが配置されたときにトリガーされる Cloud Functions の関数を作成しました。この関数は、人間が行うように画像のコンテンツにアノテーションを付け、DB を自動的に更新できます。すごい!

次のステップ同じ考え方で、2 つの優れた機能を実現できます。

[省略可] 追加の Cloud Functions を追加する [自由形式]

他にも思い浮かぶ機能がいくつかあります。

📩 メール トリガー

誰かが写真を送信するたびにメールを送信するメール トリガー

  • 頻繁に発生している場合は、追加の制約を追加します。大きな画像、または Gemini コンテンツに「ヌード / ヌード / 暴力」という単語が含まれる画像。
  • EventArc を確認することを検討してください。

🚫? 不適切な写真を自動的に管理する

現在、人間の管理者が画像に「不適切」という報告を行っています。手間のかかる作業やスペースのモデレーションを Gemini に任せてみませんか?前の関数で学んだように、不適切なトリガー コンテンツにフラグを立てて DB を更新するテストを追加します。つまり、基本的には、前の関数を取得し、プロンプトを変更し、回答に基づいて DB を更新します。

注意点。生成 AI の出力は予測できません。Gemini からの「クリエイティブ出力」が「オンレール」になっていることを確認します。0 ~ 1 の信頼スコア、JSON など、決定論的な回答を求めることができます。これは次のような方法で実現できます。* Python ライブラリ pydanticlangchain などを使用する * Gemini 構造化出力を使用する。

ヒント: 次のように、複数の関数を使用することも、JSON の回答を強制する単一のプロンプトを使用することもできます(上でハイライト表示した「Gemini 構造化出力」で機能します)。

これを生成するプロンプトは、次のうちどれですか。

{
    "description": "This is the picture of an arrosticino",
    "suitable": TRUE
}

プロンプトに追加のフィールドを追加して、「何か良い点はありますか?」などの分析情報を取得できます。悪い点はこの場所をご存じですか?テキストがある(OCR がこれまでになく簡単になりました):

  • goods: 「おいしそうな料理ですね」
  • bads: 「健康に悪い食べ物のように見える」
  • OCR: 「Da consumarepreferredibilmente prima del 10 Novembre 2024」
  • location: "Pescara, Lungomare"

通常は、N 個の結果に対して N 関数を使用する方がよいのですが、10 個の処理を実行する関数ではとてもやりがいがあります。詳しくは、Riccardo の記事をご覧ください。

発生する可能性のあるエラー(主に IAM / 権限)

このソリューションを初めて開発したときに、IAM 権限の問題が発生しました。共感を示し、解決方法のアイデアを提供するために、ここに追加します。

エラー: サービス アカウントに必要な権限がありません

  1. GCS バケットをリッスンする GCF 関数をデプロイするには、図のように、ジョブに使用しているサービス アカウントに適切な権限を設定する必要があります。

22f51012fa6b4a24.png

EventArc API を有効にする必要が生じることもあります。この場合、完全に利用可能になるまでに数分かかることがあります。

エラー: Cloud Run 起動元がありません

  1. GCF の権限設定の UI からの別のコメントは次のとおりです(Cloud Run 起動元ロール):

be72e17294f2d3f3.png

このエラーは、fix-permissions.sh に似たイメージ内コマンドを実行することで修正できます。

この問題の詳細については、https://cloud.google.com/functions/docs/securing/authenticating をご覧ください。

エラー: メモリ上限を超えています

初めて実行したとき、ログには次のように書かれていました。「『メモリ上限 244 MiB を超過し、270 MiB が使用されました。メモリ上限の増加を検討してください。https://cloud.google.com/functions/docs/configuring/memory をご覧ください。」再度、GCF に RAM を追加します。これは UI で簡単に行えます。次のような問題が発生する可能性があります。

bed69d6ad0263114.png

また、Cloud Run デプロイ スクリプトを修正して MEM/CPU を増やすこともできます。この処理には少し時間がかかります。

エラー: Pub/Sub が公開されました

GCF v1 でトリガーを作成すると、1 回だけ次のエラーが発生しました。

e5c338ee35ad4c24.png

繰り返しになりますが、この問題は、IAM に移動してサービス アカウントに「Pub/Sub パブリッシャー」ロールを付与することで簡単に修正できます。

エラー: Vertex AI が使用されていません

このエラーが表示された場合:

権限が拒否されました: 403 Vertex AI API は、プロジェクト YOUR_PROJECT でこれまで使用されたことがない、または無効になっています。https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT にアクセスして有効にしてください。

Vertex AI API を有効にする必要があります。必要なすべての API を有効にする最も簡単な方法は次のとおりです。

  1. https://console.cloud.google.com/vertex-ai
  2. [すべての推奨 API を有効化] をクリックします。

492f05ac377f3630.png

エラー: EventArc トリガーが見つかりません。

このエラーが発生した場合は、関数を再デプロイしてください。

8ec4fc11833d7420.png

エラー: 400 サービス エージェントがプロビジョニング中です

400 個のサービス エージェントがプロビジョニングされます(https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents)。サービス エージェントは、指定された Cloud Storage ファイルを読み取るために必要です。数分後にもう一度お試しください。

その場合は、しばらく待つか、Google 社員に問い合わせてください。

10. モジュール 8: 可用性 SLO を作成する

この章では、次の目標を達成します。

  1. SLI の作成
  2. SLI に基づく SLO の作成
  3. SLO に基づくアラートの作成

f63426182c052123.png

Riccardo は Google Cloud の SRE / DevOps 分野で働いているため、これは著者にとって非常に重要なトピックです。

(自由形式)このアプリの SLI と SLO を作成する

ダウンしているかどうかがわからなければ、アプリはどの程度優れているのでしょうか。

SLO とは

偶然ですね。Google が SLO を発明しました。詳しくは、以下の記事をご覧ください。

ステップ 1: 可用性 SLI/SLO を作成する

最初に、可用性 SLO について説明します。これは最も簡単に測定できる項目であり、最も重要な項目である可能性があります。

幸い、Cloud Run には Istio による事前構築済みの SLO サポートが付属しています。

アプリを Cloud Run に移行したら、この処理は非常に簡単で、30 秒ほどで完了します。

  • Cloud Run ページに移動します。
  • アプリをクリック/選択します。
  • [SLOs] タブを選択します。
  • [+ SLO を作成] をクリックします。
  • 可用性、リクエスト ベース
  • 続行
  • 暦月 / 99%
  • [Create SLO] をクリックします。

e471c7ebdc56cdf6.png

ステップ 2: この SLO のアラートを設定する

2 つのアラートを作成することをおすすめします。

  1. バーンレートが低い(「Slowburn」)もので、メールでアラートを送信します(優先度の低いチケットをシミュレートします)。
  2. バーンレートが高い(「Fastburn」)もので、SMS でアラートを送信する(優先度の高いチケット / ポケットベルをシミュレート)

以前の SLO tab に移動します。

これを 2 回行います。

314bfd6b9ef0a260.png

  • 「SLO アラートを作成」(右側にプラスが付いた 🔔? ボタン)をクリックします。
  • ルックバック期間、バーンレートのしきい値:
  • [迅速]1 回目: 60 分 / 10 x
  • [SLOW]。2 番目: 720 分 / 2 x
  • 通知チャンネル: [通知チャンネルを管理] をクリックします。
  • まず、[メール] -> [新しく追加] -> [..
  • 2 つ目は、[SMS] -> [新規を追加] -> [スマートフォンで確認] です。
  • ヒント: 私は名前に絵文字を使うのが好きです。デモに最適です。
  • 完了したら、右上の大きな X をクリックします。
  • 最初に電話(高速)を選択し、次にメール(低速)を選択します。
  • 次のようなサンプル ドキュメントを追加します。
  • [PHP Amarcord] Riccardo told me to type sudo reboot or to check documentation in http://example.com/playbooks/1.php but I guess he was joking

当たり!

最終結果

1 つの機能する SLO と 2 つのアラート(メールとスマートフォンに送信)が設定され、アラートがメールとスマートフォンに送信されたら、この演習は完了です。

必要に応じて、レイテンシを追加できます(強くおすすめします)。さらに複雑なレイテンシを追加することもできます。レイテンシには、妥当と思われるレイテンシを選択します。判断に迷う場合は、200ms を選択します。

11. 次のステップ

すべて完了しました。何が足りないのですか?

考慮すべき点:

Gemini で遊ぶ

Gemini は次の 2 種類で使用できます。

  1. Vertex AI。「エンタープライズの方法」は、第 7 章(GCF + Gemini)で説明した GCP と密接に結びついています。すべての認証が魔法のように機能し、サービスが美しく相互接続されます。
  2. Google AI 「消費者のやり方」。こちらで Gemini API キーを取得し、既存のワークロード(独自開発の作業、他のクラウド、localhost など)に結びつけることができる簡単なスクリプトの作成を開始します。API キーを置き換えるだけで、コードが魔法のように機能します。

ご自身のプロジェクトで(2)を試してみることをおすすめします。

UI の引き上げ

UI は苦手なの。Gemini は対応しています。PHP ページを 1 つだけ取得して、次のように言うだけです。

I have a VERY old PHP application. I want to touch it as little as possible. Can you help me:

1. add some nice CSS to it, a single static include for tailwind or similar, whatever you prefer
2. Transform the image print with description into cards, which fit 4 per line in the canvas?

Here's the code:

-----------------------------------
[Paste your PHP page, for instance index.php - mind the token limit!]

これは、1 つの Cloud Build で 5 分以内に簡単に実現できます。:)

Gemini からの回答は完璧でした(変更する必要はありませんでした)。

8a3d5fe37ec40bf8.png

以下は、作成者の個人アプリの新しいレイアウトです。

81620eb90ae3229a.png

注: コードは画像として貼り付けられています。これは、コードをコピーして使用することを推奨しているのではなく、クリエイティブの UI/フロントエンドの制約に基づいて Gemini にコードを自動生成してもらうためです。コードを変更する必要があるのは、ごくわずかです。

セキュリティ

このアプリを適切に保護することは、この 4 時間のワークショップの目標ではありません。

アイデアについては、SECURITY doc をご覧ください。

12. 完了

🎉?🎉?🎉? これで、Google Cloud を使用してレガシー PHP アプリケーションを正常にモダナイズできました。

24cb9a39b1841fbd.png

この Codelab では、次のことを学習しました。

  • Google Cloud SQL に MySQL データベースをデプロイする方法と、既存のデータベースを移行する方法。
  • Docker と Buildpack を使用して PHP アプリケーションをコンテナ化し、そのイメージを Google Cloud Artifact Registry に保存する方法
  • コンテナ化されたアプリを Cloud Run にデプロイし、Cloud SQL で実行する方法
  • Google Secret Manager を使用して機密性の高い構成パラメータ(DB パスワードなど)を秘密裏に保存/使用する方法
  • GitHub リポジトリにコードが push されたときに PHP アプリを自動的にビルドしてデプロイするように、Google Cloud Build で CI / CD パイプラインを設定する方法。
  • Cloud Storage を使用してアプリリソースを「クラウド化」する方法
  • サーバーレス テクノロジーを利用して、アプリコードに変更を加えることなく Google Cloud 上に優れたワークフローを構築する方法。
  • ユースケースに適した Gemini のマルチモーダル機能を使用します。

これは、Google Cloud によるアプリケーションのモダナイゼーションに取り組むための絶好の出発点です。

🔁? フィードバック

このワークショップの体験についてお知らせいただける場合は、こちらのフィードバック フォームをご利用ください。

フィードバックをお寄せいただくとともに、特に優れたコードについてはPR をお送りください。

🙏 よろしくお願いいたします

執筆とソリューションのテストにご協力いただいた Datatonic の Mirko Gilioli 氏と Maurizio Ipsale 氏に感謝します。