GAEがRuby対応したのでRubyチュートリアルをやってみた〜BOOKSHELF APP〜

# 最初に
本記事はGoogle App EngineのRubyチュートリアルに関する投稿、[GAEがRuby対応したのでRubyチュートリアルをやってみた〜Hello World app〜](http://qiita.com/ebihara99999/items/51a593e5a47fd17f24eb)の続きになります。「Before you begin」が終了していない方はそちらからご覧下さい。
終了している方も、プロジェクトのロケーションが「europe-west」以外になっていることをもう一度確認下さい。

# BOOKSHELF APP
本記事では「Using Structured Data」を実施します。ここまで実施できれば、DBを使用するwebアプリを作成できるようになります。
実施したMacのOS、バージョンは以下の通りです。

```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.10.5
BuildVersion:	14F1605
```

## Using Structured Data with Ruby
* 以下の画面からDBを選ぶ  
  MySQLとCloud Datastoreはマネージドですが、PostgreSQLは違うので注意です。ここでは一番上のGoogle Cloud SQL(MySQL)を選択します。
![スクリーンショット 2016-03-24 19.11.04.png](https://qiita-image-store.s3.amazonaws.com/0/95156/66048491-9184-066f-4b5d-25b51c8b6df7.png "スクリーンショット 2016-03-24 19.11.04.png")

## Using Cloud SQL with Ruby
### Before you begin
* 先ほどのHello World appで上3つは終了しているので、「Enable APIs for your project」と「Create a service account for your project」を実施しましょう。

![スクリーンショット 2016-03-25 15.00.42.png](https://qiita-image-store.s3.amazonaws.com/0/95156/800e67de-2ec8-47f5-f61c-565dabc6e953.png "スクリーンショット 2016-03-25 15.00.42.png")

#### Enable APIs for your project
* 「Enable APIs」をクリックする
* ドロップダウンからプロジェクトを選択し続行ボタンを押す

![スクリーンショット 2016-03-25 15.02.04.png](https://qiita-image-store.s3.amazonaws.com/0/95156/51086949-a6a3-cc92-6860-f5a363706020.png "スクリーンショット 2016-03-25 15.02.04.png")

* 以下に遷移したことを確認し続行ボタンを押す

![スクリーンショット 2016-03-25 15.03.01.png](https://qiita-image-store.s3.amazonaws.com/0/95156/bcedcab6-c65c-0946-5e55-40132a83c579.png "スクリーンショット 2016-03-25 15.03.01.png")

* 「Enable APIs for your project.」にチェックをつける

![スクリーンショット 2016-03-25 15.04.58.png](https://qiita-image-store.s3.amazonaws.com/0/95156/66a2b15e-1e7b-6057-57ea-b85759be6b10.png "スクリーンショット 2016-03-25 15.04.58.png")

### Create a service account for your project.
* 「Create service account key page in the Google Cloud Platform Console」をクリック
* プロジェクトを選択し続行を押す

![スクリーンショット 2016-03-25 15.06.26.png](https://qiita-image-store.s3.amazonaws.com/0/95156/4f97ced4-117a-fd30-d51a-7bfade395fe3.png "スクリーンショット 2016-03-25 15.06.26.png")

* サービスアカウントを作成を押す

![スクリーンショット 2016-03-24 20.21.34.png](https://qiita-image-store.s3.amazonaws.com/0/95156/54a32246-4f6f-0e99-a02c-7b411da190c7.png "スクリーンショット 2016-03-24 20.21.34.png")


* 任意の名前を記入し「新しい秘密鍵の提供」をチェックし「JSON」を選択し作成ボタンを押下する  
秘密鍵は注意して保管しましょう。

![スクリーンショット 2016-03-25 15.08.38.png](https://qiita-image-store.s3.amazonaws.com/0/95156/3fb7e6c7-df52-da86-1624-067d0b496965.png "スクリーンショット 2016-03-25 15.08.38.png")


* 元の画面に戻り「Create a service account for your project.」をチェックする

![スクリーンショット 2016-03-25 15.10.50.png](https://qiita-image-store.s3.amazonaws.com/0/95156/671ce2ea-317b-c145-a0d4-adb4f907dc7b.png "スクリーンショット 2016-03-25 15.10.50.png")

## Create and configure a Cloud SQL instance

* 「Create a Cloud SQL instance. 」をクリックする
![スクリーンショット 2016-03-25 15.12.22.png](https://qiita-image-store.s3.amazonaws.com/0/95156/0b4cf4de-c93d-d0f5-99cc-99360c59ff29.png "スクリーンショット 2016-03-25 15.12.22.png")

### プロジェクトの選択

* 毎回おなじみプロジェクトの選択をする

![スクリーンショット 2016-03-25 15.15.26.png](https://qiita-image-store.s3.amazonaws.com/0/95156/52a81115-be76-48fb-54df-542441989949.png "スクリーンショット 2016-03-25 15.15.26.png")


### インスタンスの作成
* 以下のように設定する
  * 名前は任意。
  * 地域はCompute Engineインスタンスのロケーションと揃える

![スクリーンショット 2016-03-24 20.39.01.png](https://qiita-image-store.s3.amazonaws.com/0/95156/5cc0e839-b498-0521-2ba1-da334907fd5d.png "スクリーンショット 2016-03-24 20.39.01.png")


* オプションを設定する
今回はデフォルト値で進めます。
オプションで指定できる要素は以下の通りです。
  * データベースのバージョン  
  MySQL5.5と5.6が選択できます。
  * 料金プラン  
  時間単位課金の従量制とパッケージ（インスタンスが存在する日数に応じた月単位の課金）を選べます。
  * 希望する場所  
  ロケーションを選択できます。指定場所に応じて以下のようにオプションが変化します。
    * App Engineアプリに準拠（デフォルト）  
    値: App Engine アプリケーションID
    * Compute Engine ゾーン  
    値（us-centralの場合）:
      * us-central-a
      * us-central-b
      * us-central-c
      * us-central-f
    * 指定しない  
    値:なし
  * バックアップとバイナリログ  
  日時バックアップを有効にするとバイナリログオプションを選択できる
    * 日時バックアップ  
    指定した時間（1時間ごと）から4時間以内にバックアップジョブが起動します。
  * アクティベーションポリシー  
  インスタンスの起動状態に関する設定をします
    * オンデマンド（デフォルト）  
    アクティブでない状態が続くとシャットダウンする
    * 常にオン  
    シャットダウンされることはない
    * 常にオフ  
    インスタンス作成後に選べるオプション
  * ファイルシステムレプリケーション  
      * 同期
      * 非同期
  * IPv4アドレス  
  チェックするとIPv4アドレスをインスタンスに割り当てる
  * 承認済みネットワーク  
  承認するIPアドレスを設定する
  * 承認済みの App Engine アプリケーション  
  承認するアプリを設定する。デフォルトで現在環境設定中のアプリが設定されているので、連携するアプリがなければ追記不要。
  * MySQLフラグ  
  slow_query_logなど様々な設定ができる。詳細は右を参照して下さい[Configuring MySQL Flags](https://cloud.google.com/sql/docs/mysql-flags)  

### アクセス制限
* 作成し数十秒でインスタンスが立ち上がるので確認し、インスタンスをクリックする

![スクリーンショット 2016-03-24 20.52.38.png](https://qiita-image-store.s3.amazonaws.com/0/95156/b4c82662-4b81-aa09-3275-2b2cbff4a3e2.png "スクリーンショット 2016-03-24 20.52.38.png")

* アクセス制御をクリックする  
めっちゃ画面が崩れてますね・・・

![スクリーンショット 2016-03-24 20.55.29.png](https://qiita-image-store.s3.amazonaws.com/0/95156/b5d074cb-8963-bc8f-e7f1-c5f82a7fb7f9.png "スクリーンショット 2016-03-24 20.55.29.png")
#### IPv4アドレスの付与
* IPアドレスをクリックしIPv4アドレスをリクエストをクリックする

![スクリーンショット 2016-03-24 20.58.48.png](https://qiita-image-store.s3.amazonaws.com/0/95156/0f60802d-bc24-88fb-a2c6-719148ca94bc.png "スクリーンショット 2016-03-24 20.58.48.png")

#### アクセス可能なネットワークの設定
* 承認ボタンをクリックし以下のように記入し設定を保存する  
注意! デモの用途なので0.0.0.0/0を指定していますが、実際に運用する場合はこの設定は避けること（ドキュメントより引用）。アクセスを許可するインスタンスのIPアドレスは、「Compute Engine」 → 「VMインスタンス」のページで「外部IP」の箇所に書いてある。
  
![スクリーンショット 2016-03-24 21.03.02.png](https://qiita-image-store.s3.amazonaws.com/0/95156/14a58afb-2dde-8372-9e29-1f8a16db5eb5.png "スクリーンショット 2016-03-24 21.03.02.png")

#### ユーザーの作成
* ユーザーをクリックし「ユーザーアカウントを作成」ボタンを押下する  

![スクリーンショット 2016-03-25 18.19.51.png](https://qiita-image-store.s3.amazonaws.com/0/95156/7cc159fb-3075-7495-05f1-6dc3c812fa96.png "スクリーンショット 2016-03-25 18.19.51.png")

## Download and run the app
基本的にチュートリアル通りに進めれば良いので、注意点のみ記載します。

### Configure settings
* database.yml  
database.ymlにはDBインスタンス作成時に付与したIPv4アドレス、ユーザー名、パスワードを指定すること
* bundle install    
```$ bundle install```時に以下のメッセージが出たら、パスワードを入力してsudo権限で処理を続けること。  
中断し```$ bundle install --path vendor/bundle```を実行すると、ローカルでの確認は問題ないがデプロイ時に

```
ERROR: (gcloud.preview.app.deploy) Error Response: [13] Timed out when starting VMs.  It's possible that the application code is unhealthy.  (0/1 ready, 1 still deploying). 
```

となりデプロイに失敗する（エラーの詳細についてはハマりどころ・注意点で記載する）。

```
$ bundle install
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Using rake 10.4.2
Using i18n 0.7.0
Using json 1.8.3


Your user account isn't allowed to install to the system Rubygems.
  You can cancel this installation and run:

      bundle install --path vendor/bundle

  to install the gems into ./vendor/bundle/, or you can enter your password
  and install the bundled gems to Rubygems using sudo.

  Password: 
```

## ハマりどころ・注意点
* bundle install  
```bundle install --path vendor/bundle```としてしまったのが一番大きなハマりどころでした。。ローカルでは問題なく動いていたのデバッグもできませんでした。「メニューバー」 → 「ログ」でログを確認してもエラーメッセージが出ておらず（自分が見つけられなかっただけかもしれいです・・・）、色々調べていたら「VMインスタンス」→ 「インスタンス詳細画面」→ 「シリアル コンソール出力」でシリアルコンソール出力を確認することができることを発見し、そこにエラー出力が出ていて原因が判明しました。ちなみに、その際のエラー出力は以下です。

```
/app/vendor/bundle/ruby/2.2.0/gems/nokogiri-1.6.6.2/lib/nokogiri.rb:29:in `require': cannot load such file -- nokogiri/nokogiri (LoadError)
```  

* rake db:migrate  
develop環境でもリモートのMySQLサーバを見ていて、かつDBインスタンスは```0.0.0.0/0```を許可しているのでローカルでrake db:migrateを実行すればDBインスタンスのデータベース/ユーザーが作成される。

## 最後に
ログにエラーが出ない場合、「VMインスタンス」→ 「インスタンス詳細画面」→ 「シリアル コンソール出力」でシリアルコンソール出力を確認しましょう！

# 参考
* https://cloud.google.com/ruby/
* http://www.publickey1.jp/blog/16/google_app_enginerubynodejsgcp_next_2016.html
* http://stackoverflow.com/questions/33444347/unable-to-update-vm-with-nodejs-app-on-google-app-engine