Google AppEngine PHPからCloud SQLへ接続する


PHPのGoogle AppEngine アプリケーションからGoogle Cloud SQLを利用する手順について調べてみたのでまとめてみました。

公式ドキュメントのチュートリアルUsing Google Cloud SQLに沿って試してみた内容になります。
このページの解説では、かなり他のページも参照しながらでないと進められませんでしたので、ここでは以下の流れを1記事で解説しています。

  1. Cloud SQLのインスタンスを作成
  2. ローカルPC(Max OS X)のMySQL Clientから接続してアプリ用のテーブルを作成
  3. AppEngineからCloud SQLデータベースへ接続

Cloud SQLは、パフォーマンスや機能が改善された第2世代が利用可能になっていますが、2016.03.30現在ベータでAppEngineからの利用はできませんので今回は第1世代を利用しました。

AppEngineのプロジェクト作成とPHPのHello Worldについては前回の記事「Google App Engine PHP開発の進め方」を参照ください。
以下は、この後からの手順になります。

インスタンスの作成

Google Cloud SQLは、プロジェクトのメニュー[ストレージ]の[SQL]から利用できます。

Google Cloud SQL メニュー

初めて、利用する場合は、以下のように[インスタンスを作成]のボタンのみ表示されています。

Google Cloud SQLインスタンスの作成

※ 請求先アカウントを設定していないプロジェクトでは、左上に[課金を有効にする]ボタンが表示され、[インスタンスの作成]ボタンは表示されません。
お支払い情報を入力して請求先アカウントを設定する必要があります(無料試使用あり)。

[インスタンスを作成]ボタンをクリックしてインスタンスの作成を開始します。

Google Cloud SQL インスタンスタイプの選択
[第1世代を選択]をクリック

Google Cloud SQLインスタンスの作成・設定画面
適当な[インスタンスID]を入力し、[地域]はus-centralを選択、[階層]はお試しなので最小のD0 -128 MB RAMを選択し、[作成]をクリック

インスタンスリストに作成したインスタンスが表示されます。

Google Cloud SQLインスタンス一覧

AppEngineからCloud SQLインスタンスへの許可

次に、AppEngineから作成したCloud SQLインスタンスへのアクセスを許可します。

リストでインスタンス名をクリックし、インスタンスの詳細を表示します。
[アクセス制御]タブをクリックすると、すでにプロジェクトのAppEngineインスタンスへのアクセスが許可されていることを確認できます。

Google Cloud SQL AppEngineからのアクセスを許可

データベースとテーブルを作成

インスタンスが作成できたので、MySQL Clientで接続して、アプリケーション用のデータベースとテーブルを作成していきます。

接続方法についての公式ドキュメントは、Connecting to Google Cloud SQL Using MySQL Clientを参考に設定していきます。

接続用ユーザーを追加

外部のホストからアクセス可能なユーザーを追加します。

インスタンスリストから作成したインスタンスを選択して詳細を開き、[アクセス制御]タブの[ユーザー]タブを選択します。

Google Cloud SQL ユーザー管理画面
[ユーザーアカウントの作成]をクリックします。

Google Cloud SQL 接続用ユーザーの作成
[ユーザー名]、[パスワード]を適用に入力して、[ホスト]はすべてのホストを許可する (%)を選択し[作成]をクリックします。

IP v4アドレスの割り当て

ローカルPCからの接続では、通常IPv4ネットワークからの接続になりますが、IPv4アドレスでアクセス制御を設定する場合、インスタンスにIPv4アドレスを割り当てる必要があります。

インスタンスの詳細を開き、[アクセス制御] > [IP アドレス]タブを開きます。

Google Cloud SQL IPv4アドレスのリクエスト
[IPv4アドレスをリクエスト]をクリックします。
IPv4アドレスが割り当てられます。

IPアドレスによるアクセスを許可

[アクセス制御] > [承認]タブを開き、[承認済みネットワーク]の[+項目を追加]をクリックします。

入力用のフォームが表示されるので、[ネットワーク]にCIDR形式でPCが所属するネットワークを指定します。

Google Cloud SQL 承認済みネットワーク
入力したら[保存]ボタンをクリックします。

※ 自分のネットワークのIPアドレスはhttp://whatsmyip.net/などで確認できます。

MySQL Clientからの接続

以上の設定で、ローカルのMySQL ClientからIPアドレスを指定してCloud SQLインスタンスに接続できるようになります。

$ mysql -uroot -p -h 11.22.33.44
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.6.26 (Google)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

アプリケーション用のデータベースとテーブルを作成

MySQL CLientで、「Step 3: Create your database and table」に載っているデータベースとテーブルを用意します。

データベース

CREATE DATABASE guestbook;

テーブル

CREATE TABLE guestbook.entries (
  entryID INT NOT NULL AUTO_INCREMENT,
  guestName VARCHAR(255),
  content VARCHAR(255),
  PRIMARY KEY(entryID)
);

PHPアプリの実装

チュートリアルのGuestbooksアプリ(Github: GoogleCloudPlatform/appengine-php-guestbook)をフォークして、永続化をCloud SQLに対応したものをGithub: hrendoh/appengine-php-guestbookにアップしてありますのでソースコード全体はそちらを参照ください。

// guestbook.php
...
  // Create a connection.
  $db = null;
  if (isset($_SERVER['SERVER_SOFTWARE']) &&
      strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false) {
    // Connect from App Engine.
    try {
      $db = new pdo('mysql:unix_socket=/cloudsql/<your-project-id>:<your-instance-name>;dbname=guestbook', 'root', '');
    } catch (PDOException $ex) {
      die('Unable to connect.');
    }
  } else {
    // Connect from a development environment.
    try {
      $db = new pdo('mysql:host=127.0.0.1:3306;dbname=guestbook', 'root', '<password>');
    } catch(PDOException $ex) {
      die('Unable to connect');
    }
  }
...

24行目の接続文字列を修正します。

// sign.php
...
$db = null;
if (isset($_SERVER['SERVER_SOFTWARE']) &&
    strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false) {
  // Connect from App Engine.
  try{
    $db = new pdo('mysql:unix_socket=/cloudsql/<your-project-id>:<your-instance-name>;dbname=guestbook', 'root', '');
  }catch(PDOException $ex) {
    die('Unable to connect.');
  }
} else {
  // Connect from a development environment.
  try {
    $db = new pdo('mysql:host=127.0.0.1:3306;dbname=guestbook', 'root', '<password>');
  } catch (PDOException $ex) {
    die('Unable to connect');
  }
}

sign.phpも、同じく12行目の接続文字列のみを修正します。

app.ymlのhandlersに各phpファイルを割り当てます。
/にguestbook.phpを、/signにsign.phpを指定します。

// app.yml
runtime: php55
api_version: 1

handlers:
- url: /
  script: guestbook.php
- url: /sign
  script: sign.php

アプリケーションの動作確認

アプリが用意出来たらデプロイして、動作を確認してみます。

$ /usr/local/google_appengine/appcfg.py -A <project-id> -V v1 update .

http://.appspot.comにアクセスすると以下の様なフォームが表示されます。

appengine-php-cloud-sql-review-guestbook
フォームに入力して[Sign Guestbook]をクリックすると入力した文字列が保存されて、フォームの上部に表示されます。

appengine-php-cloud-sql-review-sign

まとめ

今回は、MySQL Clientからの接続は、ローカルPCからプロキシを介して接続しましたが、実際の運用では、管理用のCompute Engineを用意するのが良さそうです。
特に、Laravelなどを利用する場合にマイグレーションをどこで実行するのかと考えると同様の構成が必要になりそう。

補足

チュートリアルに必要なコマンドはhomebrewでインストールしました。

$ brew install wget
$ brew install mysql --client-only