概要
皆さんGoogleAppEngine(以下GAE)、使用していますか?
私は使用しています。大好きです。
しかしながらGAEを使用したことがない、という方は
- 導入までのハードルが高そう
- 開発方法を理解するまでが難しそう
- MVCなフレームワークが使えるのかわからない
- その他なんかわからん
などなどの理由でなかなか手を出せない、という人が多いのではないでしょうか。
ただ、下記のような魅力もあるのも事実です
- ある程度なら課金無しで使用でき、無料枠が多い
- 今回同時に紹介するGoogleCloudSQLは課金あります
- 素早くスケールアウトし瞬間的な大量アクセスにも耐えうる
- 最近東京リージョンも登場した(!)
などなど…他にも魅力的な部分もありますが、下記記事が非常に詳しく解説してくださっているので引用させて頂きます。
個人的に最強のPaaSプラットフォームGoogle App Engineの良い所を挙げてみる
2016年半ば現在のGoogle App Engine
こんなに魅力があるのに、導入で躓く・難しそうという理由で使われない…というのは非常にもったいないので、この記事で導入さえしてもらえれば後はPHPコードを書くだけに集中できるよ!なんだ簡単じゃん!…と、なっていただくのが目的です。
この記事ではどこまで解説するか
- GoogleCloudPlatform(以下GCP)のプロジェクト作成
- GCP、GAEの操作ツール、gcloudコマンドの導入、操作
- FuelPHPをGAEで使用するための設定 -> hello world
- GAEのローカルデバッグ・デプロイ
- ログ確認方法
- GoogleCloudSQLを用いたDB接続
また、Macを前提とした解説になりますが、Windowsの方にも同じように使用していただけるよう解説は加えます。
ただ、動作確認は全然やってないので何か間違っていたら指摘をいただけるとうれしいです…
GCPのプロジェクト作成
まず、GAEを動かすためのプロジェクトをGCPで作成しましょう
自分のGoogleアカウントでログインした後プロジェクト一覧を開き、プロジェクト作成をクリックします
このようなポップアップが出てくるので、自分の好きなプロジェクト名を入力します。
また、その際「詳細設定を表示」と表示されている箇所がありますので、それもクリックします
地域はどこにしても動きますが、サービスを主に日本で展開する場合は東京リージョンである「asia-northeast1」を選択することをおすすめします。
地域を選択したら「作成」をクリックします。
しばらくしたらプロジェクトの作成が完了します。
gcloudコマンドの導入、操作
GoogleAppEngineのデプロイ等に使用するgcloudコマンドを導入します。
上記ファイルをクリックします。
もしOSbitが32bitであれば「Mac OS X (x86)」の方のファイルを選択してください。もしOSのbit数がわからなければ「macOS ビット数」等でググってみてください(投げやり)
以下からコンソールで作業します
今回は
/Users/[ユーザー名]/GAE/lib
にインストールしようと思います。[ユーザー名]の部分は実際のユーザ名と読み替えてください
記事を書いている時点のバージョンは121.0.0ですが、ここも読み替えてください
$ mkdir -p /Users/[ユーザー名]/GAE/lib
$ mv /path/to/google-cloud-sdk-121.0.0-darwin-x86_64.tar.gz /Users/[ユーザー名]/GAE/lib
$ cd /Users/[ユーザー名]/GAE/lib # 任意のディレクトリ
$ tar xfvz google-cloud-sdk-121.0.0-darwin-x86_64.tar.gz
$ ./google-cloud-sdk/install.sh # 実行は任意ですが、PATHを通すためなるべく実行したほうがいいです
$ ./google-cloud-sdk/bin/gcloud init # しばらく時間がかかります
# 下記のような文言が表示されたらYを選択しブラウザで認証を完了してください。
# To continue, you must log in. Would you like to log in (Y/n)?
# 下記のような文言が表示されたら1を選択します
# Pick cloud project to use:
# [1] [GCPのプロジェクト名]
# Please enter your numeric choice:
$ gcloud -v
バージョン文字列が出れば完了です!
Windowsの場合は上記の部分をクリックし、exeを実行します。その際Pythonがインストールされていない場合「Bundled Python」にチェックを入れインストールします。
インストール後「Cloud SDK Shell」を立ち上げ、gcloud init実行でインストールできるかと思います
https://cloud.google.com/sdk/docs/quickstart-windows
もしくは上記を参考にするといいかもしれません
※動作確認等はしてませんので、参考程度に…
FuelPHPをGAEで使用するための設定
さて、いよいよFuelPHPをまずローカルPCにインストールするのですが、通常通りインストールするだけではGAEでは使用できない点が幾つかあります。
- アクセスログ・エラーログをsyslog経由で吐くように修正
- GAEはファイル出力・書き込みなどが原則禁止
- locale設定の変更
- app.yamlの追加
- GAEのから見たルーティングや環境変数の設定ファイル
FuelPHPのインストールを行った後
これらを一つ一つ解決していきましょう。
FuelPHPのインストール
まずFuelPHP本体のインストールです。これは本家ドキュメントでも詳しく解説してくださっています。
http://fuelphp.jp/docs/1.8/installation/instructions.html
ですので、詳しい説明は省きますが上記の「コマンドラインからインストール」から下記のようなコマンドをコンソールで叩きインストールされているものとします。
インストール方法自体は手動でもなんでもOKです!
$ curl get.fuelphp.com/oil | sh
$ cd /Users/[ユーザー名]/GAE
$ oil create googleappengine_sample
これで
/Users/[ユーザー名]/GAE/googleappengine_sample
にFuelPHPが配置されました。※以後ここのディレクトリを/path/to/fuelphpと書きます
Windowsの方や上記がよくわからない方がいらっしゃいましたら「Zip ファイルをダウンロードする」のところの手順でFuelPHPを配置していただき、コンソールやコマンドプロンプトで
$ php composer.phar self-update
$ php composer.phar update
を、実行していただくといいかもしれません。
※http://fuelphp.jp/docs/1.8/installation/instructions.html#/composer より引用
もしこの地点でPHPコマンドがない方は先にXAMPPなどでPHPをインストールしそちらを使用してください。
# このあたりは
# gcloud component install app-engine-php
# とかでインストールしてそこのPHPを使用したほうがスマートなのですが…誰かやってみてもらえると嬉しい…
アクセスログ・エラーログをsyslog経由で吐くように修正
ここからはGAE用の修正に入っていきます。
下記のようなファイルを配置することでFuelPHPのLogクラスをオーバーライドしsyslog経由で出力するよう変更しています。
<?php
class Log extends Fuel\Core\Log
{
public static function _init()
{
static::$monolog = new \Monolog\Logger('fuelphp');
$syslog = new \Monolog\Handler\SyslogHandler('fuelphp', 'local0');
$formatter = new \Monolog\Formatter\LineFormatter("%level_name% - %datetime% --> %message%".PHP_EOL, "Y-m-d H:i:s");
$syslog->setFormatter($formatter);
static::$monolog->pushHandler($syslog);
}
}
bootstrap.phpにもオーバーライドするような記述を追加します。
/* 〜省略〜 */
\Autoloader::add_classes(array(
// Add classes you want to override here
// Example: 'View' => APPPATH.'classes/view.php'
'Log' => APPPATH . 'classes/log.php', // この行を追加
));
/* 〜省略〜 */
locale設定の変更
localeがCしか使用できない?みたいなのでこれも変更します。
# 正直なぜlocaleを変更しなければならないのか理由がわかっていません。。。誰か教えてくれるとうれしい
return array(
/* 〜省略〜 */
// en_USからCに変更
'locale' => 'C', // PHP set_locale() setting, null to not set
/* 〜省略〜 */
);
app.yamlの準備
GAE側のルーティングや各種設定を記述します。
public以下の静的ファイルを拡張子で判別し、GAE側で静的に返却するようにしています。
それ以外のアクセスに関してはpublic/index.phpを通してFuelPHP側に処理させるようになっています。
runtime: php55
api_version: 1
handlers:
- url: /(.*.(htm$|html$))
static_files: public/\1
upload: public/(.*.(htm$|html$))
application_readable: true
- url: /assets/img/(.*.(png$))
mime_type: image/png
static_files: public/assets/img/\1
upload: public/assets/img/(.*.(png$))
application_readable: true
- url: /assets/img/(.*.(gif$))
mime_type: image/gif
static_files: public/assets/img/\1
upload: public/assets/img/(.*.(gif$))
application_readable: true
- url: /assets/img/(.*.(jpg$))
mime_type: image/jpeg
static_files: public/assets/img/\1
upload: public/assets/img/(.*.(jpg$))
application_readable: true
- url: /(.*.(ico$))
mime_type: image/x-icon
static_files: public/\1
upload: public/(.*.(ico$))
application_readable: true
- url: /assets/css/(.*.(css$))
mime_type: text/css
static_files: public/assets/css/\1
upload: public/assets/css/(.*.(css$))
application_readable: true
- url: /assets/js/(.*.(js$))
mime_type: text/javascript
static_files: public/assets/js/\1
upload: public/assets/js/(.*.(js$))
application_readable: true
- url: /assets
static_dir: public/assets
- url: /robots.txt
static_files: public/robots.txt
upload: public/robots.txt
- url: /.*
script: public/index.php
# 下記はデプロイ時とデバッグ時でそれぞれ切り替え
env_variables:
# FUEL_ENV: 'production'
FUEL_ENV: 'development'
例えばsitemap.xmlをアクセスさせるようにしたい!となったときは
- url: /sitemap.xml
mime_type: application/xml
static_files: public/sitemap.xml
upload: public/sitemap.xml
と、いうふうに追加すればアクセスできるようになります。
# FUEL_ENVに関してはデプロイごとに切り替えるの面倒…なんとかしたい
ローカルデバッグの実行
GAEにはローカルで実行できるwebサーバの機能を用意してくれているのでそれを使用すれば今すぐFuelPHPのウェルカムページを確認することができます!早速やってみましょう。
$ cd /path/to/fuelphp
$ dev_appserver.py .
http://localhost:8080/
にアクセスすると
上記のようなページが表示されたら成功です。
dev_appserver.pyを実行したコンソールを見るとそこにそのままアクセスログやエラーログが吐かれていることがわかると思います。
更に起動中にファイルを変更した場合リアルタイムに検知、反映してくれます。非常に便利ですね!
デプロイの実行
一度この状態でGAEにデプロイを行ってみましょう。
app.yamlのFUEL_ENVをproductionに切り替えます。
env_variables:
FUEL_ENV: 'production'
# FUEL_ENV: 'development'
その後デプロイコマンドを実行します
$ cd /path/to/fuelphp
$ gcloud app deploy
# 下記はYを選択してください。
# Do you want to continue (Y/n)?
Updating service [default]...done.
Deployed service [default] to [https://[プロジェクトID].appspot.com]
You can read logs from the command line by running:
$ gcloud app logs read -s default
To view your application in the web browser run:
$ gcloud app browse
上記のように表示されたら成功です!
またデバッグを行う際はFUEL_ENVの切り替えを行ってください。
$ gcloud app browse
これを実行すると公開されたURLでページが確認できます。
https://[プロジェクトID].appspot.com/
というURLで表示されると思います。
なお、複数個プロジェクトを作成された方は
GCPのIDをコピーし
$ gcloud config set project [プロジェクトID]
と入力すればデプロイ対象のプロジェクトを変更することができます。
ログ確認方法
ログもGCPから確認できます。
上記をクリックして
少しスクロールしたところにある「ログ」をクリックすると
このような画面で確認できます。
ログレベルや日付ソート等も簡単にできるので触ってみてください。
https://itunes.apple.com/jp/app/google-cloud-console/id1005120814?mt=8
https://play.google.com/store/apps/details?id=com.google.android.apps.cloudconsole&hl=ja
これらのログはiOS/Androidアプリからも確認することができます!
GoogleCloudSQLを用いたDB接続
さて、webアプリケーションといえばやはりDBを使いたいですよね。
GAEは外部のDBとは接続できませんがGoogleが提供しているフルマネージドMySQLであるGoogleCloudSQLを使用できます。
この記事を書いている現在「Second Generation」「First Generation」の2つのバージョンが存在します。
カジュアルに使うのなら料金・速度共にSecond Generationの方が有利なのですが
上記URLに下記のような記述があります。引用させていただくと
Cloud SQL Second Generation のインスタンスはベータのため、次の機能は利用できません。
Google App Engine の接続
Compute Engine, Managed VM, Container Engine やワークステーションからの接続はサポートされています。
と、なっており、一見GAEからはSecond Generationは使用できないようにみえるのですが
私は普通に使用できているので今回はSecond Generationを使用する前提で解説をしていきます。
# https://cloud.google.com/sql/docs/1st-2nd-gen-differences
# こっちには書いてないからこっちの方が正ってことなのかな…?
また、ここから先の作業は料金が発生します。
まだGCPのアカウント情報に支払い情報が紐付いていなければメニューから「お支払い」を選択し情報登録を行ってください。
料金は上記URLで確認できます。
インスタンスの作成
まずはインスタンスを作成しましょう。
メニューから「SQL」をクリックした後何もインスタンスを作っていない状態だとウェルカムページが表示されるので「インスタンスを作成」をクリックします。
その後インスタンスをタイプを選択する画面が表示されます。
これが先程の「Second Generation」「First Generation」の選択に当たるので「第2世代を選択」をクリックします。
設定項目が出てきますので、それぞれ設定します。
-
インスタンスID
- 任意の文字列を設定してください
-
データベースバージョン
- 5.6か5.7お好みの方を選択してください。ここでは5.6を選択することにします
-
場所
- AppEngineインスタンスと近いほうが通信速度が上がるので、AppEngineで選択した地域と同じ地域を選択します。ここではasia-northeast1を選択します。ゾーンは「すべて」のままにします
- ただしasia-northeast1の方が各種料金が若干高いです。
- AppEngineインスタンスと近いほうが通信速度が上がるので、AppEngineで選択した地域と同じ地域を選択します。ここではasia-northeast1を選択します。ゾーンは「すべて」のままにします
-
マシンタイプ
- カジュアルに一番安いやつを使いたいのでdb-f1-microを選択します。
-
ストレージの種類
- ここでも安さ重視でHDDのほうが料金安くなるのでHDDを選択しています。SSDの方が応答速度は早いです
-
ストレージ容量
- 最低容量である10GBを選択します。
-
自動バックアップ
- ここでは有効にし、アクセスに影響が少なそうな深夜〜早朝にしていますが、これもお好みです。
- バックアップも料金がかかるのでより安くしたい方はOFFにしたほうがいいかもしれません
- ここでは有効にし、アクセスに影響が少なそうな深夜〜早朝にしていますが、これもお好みです。
-
バイナリログ
- 不具合があったときに故障直前の状態まで戻す機能を使うためにログを残しておくか…の機能なんですが、どう機能するかは正直わかっていません。とりあえず有効にしておきます。
-
フェイルオーバーレプリカを使用するか
- 全く同じ状態のレプリカを1台立ち上げて、1台が故障した際にサービスが止まらないようにする機能
- 2倍の料金がかかるのでここではOFFにしておきます
-
メンテナンスの時間枠
- Google側でメンテナンスが入る際に再起動が入る時間の選択。一番影響が少なそうな時間にしておきます
- メンテナンスリリースチャンネルもこだわりがなければそのままでいいと思います。
「作成」をクリックするとインスタンスが立ち上がります。
インスタンスを選択したら下辺りにプロパティが載っているので見てみてください。
インスタンスの名前横にチェックマークが着いたら起動完了です。
コンソールから接続してみる
手動でコンソールから接続してみましょう。
接続されるまで少し時間がかかりますがmysqlのクライアントコマンドよろしく下記のコマンドでGoogleCloudSQLに接続することが可能です。
$ gcloud beta sql connect [インスタンスID] --user root
# Whitelisting your IP for incoming connection for 1 minute...done.
Enter password:
パスワードは何も設定されていないので、そのままエンターキーを押すと接続できます。
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 127336
Server version: 5.6.31-google-log (Google)
Copyright (c) 2000, 2016, 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> CREATE DATABASE `appengine_test` DEFAULT CHARACTER SET utf8;
mysql> CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ちなみにmysqlコマンドとやれることはほぼ変わらないらしく(試してないですが)、例えば下記のようにSQL文を流すことも可能です。
$ gcloud beta sql connect [インスタンスID] --user root < hoge.sql
GAE(FuelPHP)から接続してみる
上記まで出来たらFuelPHPから接続を行ってみましょう!
今回はFuelPHPのormを使用して接続してみようと思うので、そこの設定から行います
return array(
/* 〜省略〜 */
// コメントを外す
'always_load' => array(
// コメントを外す
'packages' => array(
'orm',
),
);
/* 〜省略〜 */
);
次にDBの設定を行います。
<?php
/**
* The production database settings. These get merged with the global settings.
*/
return array(
'default' => array(
'connection' => array(
'dsn' => 'mysql:dbname=appengine_test;unix_socket=/cloudsql/[インスタンス接続名]',
'username' => 'root',
'password' => '',
),
),
);
「インスタンス接続名」は先程のGoogleCloudSQL管理画面から取得します。
次にモデルを作成します。
ついでにdatetimeを自動的に更新するように調整しておきます。
<?php
class Model_User extends Orm\Model
{
protected static $_table_name = 'users';
protected static $_created_at = 'created';
protected static $_updated_at = 'modified';
protected static $_mysql_timestamp = true;
protected static $_primary_key = ['id'];
protected static $_observers = array(
'Orm\\Observer_CreatedAt' => array(
'events' => array('before_insert'),
'mysql_timestamp' => true,
'property' => 'created',
),
'Orm\\Observer_UpdatedAt' => array(
'events' => array('before_save'),
'mysql_timestamp' => true,
'property' => 'modified',
),
);
protected static $_properties = [
'id',
'name',
'created',
'modified',
];
}
次にテスト表示用のルーティングを行います。
ものすごく適当ですが
https://[プロジェクトID].appspot.com/user/add/[任意の文字列]
というURLでusersにinsertが行われていく、というアプリケーションにしましょう。
<?php
return array(
/* 〜省略〜 */
'user/add/(:any)' => array('user/add/$1'), // 追加
);
コントローラも用意します。
<?php
class Controller_User extends Controller_Template
{
public $template = 'template';
public function action_add($name)
{
$new = new Model_User();
$new->name = $name;
$new->save();
$users = Model_User::find('all');
$this->template->content = View::forge('user/add');
$this->template->content->users = $users;
}
}
テンプレートとビューも用意します
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link type="text/css" rel="stylesheet" href="/assets/css/bootstrap.css">
<title>GAE+GoogleCloudSQL+FuelPHPテスト</title>
</head>
<body>
<div class="container">
<?php echo $content; ?>
</div>
</body>
</html>
<table class="table">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>created</th>
<th>modified</th>
</tr>
</thead>
<tbody>
<?php foreach ($users as $user): ?>
<tr>
<th scope="row"><?php echo $user->id; ?></th>
<td><?php echo $user->name; ?></td>
<td><?php echo $user->created; ?></td>
<td><?php echo $user->modified; ?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
FUEL_ENVがproductionなのを改めて確認し、もう一度デプロイしましょう
env_variables:
FUEL_ENV: 'production'
# FUEL_ENV: 'development'
$ cd /path/to/fuelphp
$ gcloud app deploy
その後で下記URLにアクセスすると
https://[プロジェクトID].appspot.com/user/add/[任意の文字]
下記画像のような画面が出てきて、アクセスするたびに行が増えるような動きになると思います!
うまくDBに接続できたことがわかりますね!
実際の開発時
これでひとまずGoogleCloudSQLの解説は終了になるのですが
本当にこの環境で開発する場合、ローカルにMySQLをインストールし
<?php
/**
* The development database settings. These get merged with the global settings.
*/
return array(
'default' => array(
'connection' => array(
'dsn' => 'mysql:dbname=appengine_test;host=localhost;',
'username' => 'root',
'password' => '',
),
'profiling' => true,
),
);
上記のように開発用DBコンフィグを設定する必要があると思います。
ローカルへのMySQLインストールはいろいろな方が解説されていると思うので、ここでの解説は割愛します。
開発用DBをGoogleCloudSQLにすることも可能ですがお金かかりますし、あんまりおすすめしないです
インスタンスの削除
GoogleCloudSQLはお金がかかるので、今後使用予定がないなら
上記から削除しておきましょう。
最後に
いかがでしたでしょうか?
長くなってしまいましたが、導入さえやってしまえば後はPHPをガンガン書くだけなのですごく楽しく開発できる環境だと個人的には思っています!
こんな長文のエントリを書くのは初めてなので、間違ってる箇所やもっとこうしてほしい、などありましたらコメントいただけると非常に嬉しいです!
あと近日中にCronの設定について別で書ければなと思っています。
ここまで読んでいただきありがとうございました。
宣伝
最後にちょっとだけ宣伝させてもらうと
ミニ四駆データベース
というサイトをここで紹介しているのと同じ構成で作成しています。良ければぜひご覧ください。