GAE（FE）にDocker環境上のRuby on Railsをデプロイする

#はじめに： Dockerで開発したら手軽にデプロイまでしたい。
Ruby on Railsの開発で今や主流のDocker環境。
ネット上に環境構築の情報は豊富に転がっているし、local開発は出来たし、Herokuにもデプロイできた。

でもやっぱりHerokuだとイマイチ速度が出ないし、
何より**AWSとかGCP使ってるほうがカッコイイ気がする！**（小並感）

圧倒的に情報不足な**Dockerに乗っけたまま**AWSやGCPにデプロイをする方法。
今回は既にHerokuで運用中のwebサービスをGAE環境に移し替えたのでその際に行った手順と、躓いた点を書いていこうと思います。

自分自身も右往左往しながら、なんとかデプロイできたー！！動いたー！！
という感じなので、間違っている点や、改善点などが有りましたら是非色々とご教示いただけると助かります。

##前提 
- 既にDocker+ docker-composeで環境構築済み、動作確認済みのRuby on Railsアプリケーションがある
- GCPアカウント及びプロジェクトが作成済
- Cloud SDKが導入済み

**【参考】**
*Dockerを使ってRuby on Rails環境の構築をしてみる*
https://qiita.com/me-654393/items/d11b871ce8d76e153b21

*Cloud SDK のインストール*
https://cloud.google.com/sdk/downloads?hl=ja

# App Engineにアプリを作成する
まず最初に、ターミナルからGAEアプリを作成します。

```
$ gcloud app create
You are creating an app for project [project-name].
WARNING: Creating an App Engine application for a project is irreversible and the region
cannot be changed. More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.

Please choose the region where you want your App Engine application
located:

 [1] asia-east2    (supports standard and flexible)
 [2] asia-northeast1 (supports standard and flexible)
 [3] asia-northeast2 (supports standard and flexible)
 [4] asia-south1   (supports standard and flexible)
 [5] australia-southeast1 (supports standard and flexible)
 [6] europe-west   (supports standard and flexible)
 [7] europe-west2  (supports standard and flexible)
 [8] europe-west3  (supports standard and flexible)
 [9] europe-west6  (supports standard and flexible)
 [10] northamerica-northeast1 (supports standard and flexible)
 [11] southamerica-east1 (supports standard and flexible)
 [12] us-central    (supports standard and flexible)
 [13] us-east1      (supports standard and flexible)
 [14] us-east4      (supports standard and flexible)
 [15] us-west2      (supports standard and flexible)
 [16] cancel
Please enter your numeric choice:  2

Creating App Engine application in project [project-name] and region [asia-northeast1]....done.
Success! The app is now created. Please use `gcloud app deploy` to deploy your first app.
```

asia-northeast1が東京リージョンですので、選択します。
※[project-name]となっている部分は各々作成したGCPプロジェクト名が入ります。

##app.yamlを作成する
続いて、Dockerfileと同階層にapp.yamlを作成します。
app.yamlの説明に関してはここでは省略します。
【参考】https://cloud.google.com/appengine/docs/standard/go/config/appref?hl=ja

```yaml:app.yaml
entrypoint: bundle exec rackup --port $PORT
env: flex
runtime: custom

env_variables:
  SECRET_KEY_BASE: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX（各々のsecret key baseを入れる）
```

SECRET_KEY_BASEの取得方法は、
コンソール上で、

```
$ docker-compose exec web bundle exec rails secret
```
表示される文字列をコピペすればOKです。

##Railsサーバの起動ポートを8080に合わせる
GAEでは、8080番に対してアクセスするので、3000番などに設定している方は**8080番**に変更しましょう。

```Dockerfile:Dockerfile（例）
FROM ruby:2.6.3

RUN apt-get update -qq && \
  apt-get install -y build-essential \
  libpq-dev \
  nodejs

RUN mkdir /app_name
ENV APP_ROOT /app_name
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install
ADD . $APP_ROOT

# 8080番でポートを起動する
CMD /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 8080 -b '0.0.0.0'"

```

```yaml:docker-compose.yml（例）
version: "3"
services:
  web:
    environment:
      TZ: Asia/Tokyo
    build: .
    volumes:
      - .:/app
    ports:
      - 8080:8080
    tty: true
    stdin_open: true

volumes:
  db-volume:
```
基本的な準備はここまで。

## いざデプロイ！
さて、待ちに待ったデプロイ。この瞬間が一番ドキドキします。
ターミナルを開いて、

```
$ gcloud app deploy

descriptor:      [/project-name/app.yaml]
source:          [/projects/project-name]
target project:  [project-name]
target service:  [default]
target version:  [20190000t123456]
target url:      [https://project-name.appspot.com]
Do you want to continue (Y/n)?  Y（←上記の内容で問題なければ、Yを入力します。）
```

ビルドが始まり、しばらく待ち、

```
Updating service [default] (this may take several minutes)...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://project-name.appspot.com]

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
```

と、表示されれば成功。

```
$ gcloud app browse
```
で確認しましょう。


## トラブルシューティング
###「Switch to inspect mode.」と怒られる件について

```
Updating service [default] (this may take several minutes)...failed.
ERROR: (gcloud.app.deploy) Error Response: [9]
Application startup error:
Switch to inspect mode.
```

色々ググったけど今ひとつ情報源に当たれずにめちゃくちゃ困ってた。
8080番でRailsが起動しておらず、GAEがアクセスできていないってことだと思う。

原因はdocker-compose側でサーバーを起動していたこと。

```yaml:docker-compose.yml（例）
version: "3"
services:
  web:
    build: .

    # ここがアウト
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 8080 -b '0.0.0.0'"

    volumes:
      - .:/app_name
    ports:
      - "8080:8080"
    links:
      - db

```

これだとこのエラーが出るみたい。
原因はいまいちよくわかっていないが、もしかしたらdocker-compose読んでいないのかも？

8080番ポートの下りで記載したDockerfileのように、

```Dockerfile:Dockerfile
CMD /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 8080 -b '0.0.0.0'"
```
で、8080を開いてあげるのがいいのかも。

【参考】
*A weekend, a Rails app, a Kubernetes and an Azure.*
https://medium.com/@michiels/a-weekend-a-rails-app-a-kubernetes-and-an-azure-d330b003d7c2

# 最後に：Herokuの方がわかりやすいけど、やっぱりGAE早い
今回は実行速度が気になったので、HerokuからGAEに乗り換えることを決意したわけですが、
予想通りGAEの方が速度が出ました。

**左: Heroku**
**右: GAE**
![sp-heroku.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377721/354827ea-0892-ae3f-34fe-78078ce2bdb2.jpeg) ![sp-gae.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377721/faf154b8-5b3b-8052-7918-b19e7c43c8b6.jpeg)

特にRailsの中身をいじること無く、20程度速度が速度が上昇しました。
改善案の部分でサーバー応答時間の短縮（TTFB）が表示されなくなったのがでかい気がします。


###おまけ：宣伝
今回HerokuからGAEに移行したのは[**スポチューバーTV**という、野球の技術指導メディア](https://spotuber-tv.com/)です。
スポーツ教育×Techの、主に野球の分野を伸ばしていけたらなと思っているので、興味のある方は是非御覧ください。
https://spotuber-tv.com/

# 参考

- https://medium.com/@michiels/a-weekend-a-rails-app-a-kubernetes-and-an-azure-d330b003d7c2
- https://qiita.com/ClapAndWhistle/items/23e3b4323fd06342b7c4
- https://cloud.google.com/ruby/rails/appengine?hl=ja
- https://qiita.com/takamario/items/33adc033090c31aeb702
- https://qiita.com/kshibata101/items/441de47fcb2d94875e85
- https://qiita.com/shwld/items/e86ee3f642c7857dd56e