GoogleAppEngine(GAE)にRailsアプリをデプロイする


# はじめに
GoogleAppEngine(GAE)にRailsアプリをデプロイする手順をメモしておきます。

# 注意点
本手順ではDBにPostgreSQLを利用する前提で`Gemfile`,`database.yml`,`app.yaml`の例を記載してます。

# 参考
[Running Rails 5 on the Google App Engine flexible environment  \|  Ruby  \|  Google Cloud Platform](https://cloud.google.com/ruby/rails/appengine?hl=ja)

# 事前準備

## Google Cloud SDK
Cloud Toolsをインストールして初期化まで済ませておく
参考：[Google Cloud SDK](https://cloud.google.com/sdk/docs/?hl=ja#install_the_latest_cloud_tools_version_cloudsdk_current_version)

## Gemfile

GAE上のRailsアプリはproductionモードで起動するため、
GAEで利用するgemがproductionでinstallされるようにする。

以下はdevelopment, testでSQLiteを利用して、
productionでPostgreSQLを利用する場合の例。

```ruby:Gemfile
# Use sqlite3 as the database for Active Record
gem 'sqlite3', group: [:development, :test]
gem 'pg', group: :production
```

## database.yml

AppEngine上のRailsアプリはproductionモードで起動するため、
database.ymlのproductionにGAE上のアプリから接続させる
DB情報を記述しておく。

以下は環境変数`DATABASE_URL`からDBのURLを取得する場合の例。

```yaml:config/database.yml
production:
  url: <%= ENV['DATABASE_URL'] %>
```

# app.yaml作成

アプリのディレクトリ配下に`app.yaml`を作成する。
`SECRET_KEY_BASE`、`DATABASE_URL`などの環境変数も記述しておく。

```yaml:app.yaml
runtime: ruby
env: flex
entrypoint: bundle exec rackup -p $PORT

env_variables:
  SECRET_KEY_BASE: 'xxxxx...'
  DATABASE_URL: 'postgres://<username>:<password>@<host>:<port>/<database>'
```

# プリコンパイル

```shell-session
$ bundle exec rails assets:precompile RAILS_ENV=production
```

# マイグレーション

```shell-session
$ bundle exec rake db:migrate RAILS_ENV=production
```

# デプロイ

```shell-session
$ gcloud app deploy

WARNING: Automatic app detection is currently in Beta
Deployment to Google App Engine requires an app.yaml file. This
command will run `gcloud beta app gen-config` to generate an app.yaml
file for you in the current directory (if the current directory does
not contain an App Engine service, please answer "no").

Do you want to continue (Y/n)?

# app.yamlが存在しない状態でデプロイしようとすると表示される
# 「Y」を入力すると、app.yamlが生成される


This looks like a Ruby application. Please confirm the command to run
as the entrypoint: [bundle exec rackup -p $PORT]:

# app.yamlにentrypointが記述されてないと表示される
# 何も入力せずにEnterキーを押下すると、app.yamlに
# 「entrypoint: bundle exec rackup -p $PORT」
# が追記される


Writing [app.yaml] to [/.../rails/myapp].
You are about to deploy the following services:
 - xxxxx-xxxxx-xxxxx/default/20170826t180159 (from [/.../myapp/app.yaml])
     Deploying to URL: [https://xxxxx-xxxxx-xxxxx.appspot.com]

Do you want to continue (Y/n)?

# デプロイ先の確認を求められる
# 「Y」を入力すると、表示されてるURLにデプロイが開始される

...

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse


Updates are available for some Cloud SDK components.  To install them,
please run:
  $ gcloud components update
```

# アクセス確認

以下のコマンドを実行するとブラウザが開いてGAEのURLにアクセスする

```shell-session
$ gcloud app browse
```

# 補足：Server Errorが表示されたりする場合
![GAE_Error.png](https://qiita-image-store.s3.amazonaws.com/0/141934/d83bd6ed-8d84-eb4a-54e5-1da5b324ac18.png)

Production環境で動かすための準備が不足しているとアクセスした際にServer Errorが表示されたりするので、準備漏れがないか見直しを行います。

## SECRET_KEY_BASEの設定

SecretKeyの生成

```shell-session
$ bundle exec rake secret
xxxxx...
```

SECRET_KEY_BASEを`app.yaml`に追記する

```yaml:app.yaml
env_variables:
  SECRET_KEY_BASE: 'xxxxx...'
```

## Rootへのルーティング設定

```ruby:config/routes.rb
root "sample#index"
```

## プリコンパイル

```shell-session
$ bundle exec rails assets:precompile RAILS_ENV=production
```

## マイグレーション

```shell-session
$ bundle exec rake db:migrate RAILS_ENV=production
```