Laravel6.0 をGCP App Engineで公開し、Google Cloud SQL でMySQLを設定したメモ

## 概要

[前回](https://qiita.com/hibohiboo/items/11768cb10bf1e7025090)のソースをGCPに上げた。
主に以下のサイトを参考にしたけれど、大分ハマってしまった。

* [Run Laravel on Google App Engine standard environment](https://cloud.google.com/community/tutorials/run-laravel-on-appengine-standard)
* [Google App Engine で Laravel を動かして Cloud SQL へ接続してみた](https://memento-mori.jp/blog/back-end/google-app-engine_on_laravel)

## ログの設定

手順だと最後だけれど、エラーの調査のためにも最初にやっておいたほうがいい気がする。
ログみればテーブルが足りてないことにすぐに気づけたりするので。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/fb0bf821-9229-5dd2-92a3-31f3be6a2e24.png)

### Loggerの追加

[app/Logging/CreateStackdriverLogger.php](https://github.com/GoogleCloudPlatform/php-docs-samples/blob/master/appengine/php72/laravel-framework/app/Logging/CreateStackdriverLogger.php)を追加。
configファイルを以下のように修正。

```diff:config/logging.php
+        // Add the following lines to integrate with Stackdriver:
+        'stackdriver' => [
+            'driver' => 'custom',
+            'via' => App\Logging\CreateStackdriverLogger::class,
+            'level' => 'debug',
+        ],
    ],
];
```

GCP公開時の環境変数を以下のように追加。

```diff:app.yaml
runtime: php72

env_variables:
+  LOG_CHANNEL: stackdriver
```

[app/Exceptions/Handler.php](https://github.com/GoogleCloudPlatform/php-docs-samples/blob/master/appengine/php72/laravel-framework/app/Exceptions/Handler.php)を以下のように修正。

```diff:app/Exceptions/Handler.php
+ use Google\Cloud\ErrorReporting\Bootstrap;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
// 省略

    public function report(Exception $exception)
    {
-        parent::report($exception);
+        if (isset($_SERVER['GAE_SERVICE'])) {
+            // Ensure Stackdriver is initialized and handle the exception
+            Bootstrap::init();
+            Bootstrap::exceptionHandler($exception);
+        } else {
+            parent::report($exception);
+        }
    }
    # [END
```

composerでライブラリの導入。

```
composer require google/cloud-logging google/cloud-error-reporting
```
## MySQLの準備

- インスタンスを作成
 ![2019-10-13-16-11-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/8ab11166-08c2-c06f-3890-2bf15051e293.png)



- MySQL を選択
  ![2019-10-13-16-12-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/b6e13691-032c-f8a7-a040-661c9e2f4c30.png)


* インスタンスIDを入力。
  - インスタンス名には機密情報や個人を特定できる情報を含めない。
    - インスタンス名は外部から閲覧可能。
  - インスタンス名にプロジェクト ID を含める必要はない。
    - この処理は必要に応じて自動的に行う（ログファイルの場合など）
* リージョンを入力
  - インスタンスと同じリージョンにすること
    - asia-northeast1 (東京))
  - ゾーンは任意のままでよい

MySQLの詳細設定は、次の記事が分かりやすく書かれています。

* [GoogleAppEngineでFuelPHP（と、ついでにGoogleCloudSQL）をカジュアルに使ってみよう](https://qiita.com/HikaruYokogoshi/items/29d583f242c6f0407ab3)
  * ストレージはHDDのほうが安い [料金表](https://cloud.google.com/sql/pricing?hl=ja) 
    * ※ストレージは後で変更できないので注意。
  * CPUはmicroが安い
  * ※cpuは後から変更できる

ここで、フラグを設定して日本時間にしておくと、後々再起動しなくてよい。

* [Cloud SQL のタイムゾーンを変える](https://maretol.hatenablog.jp/entry/2017/04/03/141318)
* 詳細設定のフラグを開く
  * `default_timezone` を `+09:00`にする

![2019-10-13-16-19-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/1812ee45-4025-1005-913e-c22d5192fc5b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/57f4adcb-e6e2-dfc0-c6cf-569a6cbbdd9f.png)


### gcloud に接続

[Laravel5.5をGoogle App Engineで動かす](https://qiita.com/fullkawa/items/4d6b080385de5523835c)を参考に、laradockのworkspaceコンテナにgcpを入れることにした。
プロキシをたてて、`php artisan migrate`を行う必要があるため。
今までのgcpコンテナにはphpには入れていなかったので。
このコンテナに入る処理を`gcp/bin/sql_bash`ファイルに記述した。
どんなファイルかは[参考のソース](https://github.com/hibohiboo/whitemap/tree/60b615495d5b79c9344637e27ed660933d6cd7d2/gcp/bin)を参照。
で、コンテナに入ったら`gcloud auth login`で認証して、インスタンスの情報を確認する。

```
./bin/sql_bash.sh
gcloud auth login
gcloud sql instances describe インスタンス名 | grep connectionName
```

`connectionName: プロジェクトID:asia-northeast1:インスタンス名`が返される。`プロジェクトID:asia-northeast1:インスタンス名`が接続文字列となる。

#### バックグラウンドでプロキシを動かす

末尾に&をつけて、プロキシをバックグラウンドで動かす。
実行した後、Enter を押さないと止まったように見える。

```
cloud_sql_proxy -instances=whitemap-255523:asia-northeast1:db01=tcp:3306 &
```

#### MySQL に接続してインスタンスを作る

```
gcloud sql databases create laravel --instance=インスタンス名
```

プラットフォームから確認する。
![2019-10-13-16-49-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/005e3bf6-5008-e557-708c-fadaeb4dbf33.png)

![2019-10-13-16-52-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/27153c30-a9ff-686e-bbf3-60d1550e4b21.png)

![2019-10-13-16-53-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/cc866bf2-3142-773d-e496-8f7422a513de.png)

##### タイムゾーンについて
フラグを設定していれば日本時間になっているはず。

```
show variables like '%time_zone%';
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/ae522aa7-d2fb-981f-461b-4b35228a269c.png)


##### 文字コードについて

ちなみに、デフォルトは utf8。
utf8mb4 にするなら、手動でSQL流せばいける。

```
CREATE DATABASE example CHARACTER SET utf8mb4;
```

```
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.04 sec)
```

#### テーブルの作成

今回は手順に従ってsession,cacheをDBに保存する設定も行うため、
それ用のテーブル定義を`session:table`,`cache:table`で行う。
passport も入れてあるので、その分の artisan も追加。

```
php artisan session:table
php artisan cache:table
export DB_DATABASE=laravel DB_USERNAME=root DB_PASSWORD=YOUR_DB_PASSWORD DB_HOST=127.0.0.1
php artisan migrate --force
php artisan passport:install
```

#### 接続ユーザの作成

接続するためのユーザをつくる。
作ったら、一度コンソールでログインして、テーブルやユーザができているか確認するとよい。

```
gcloud sql users create [USER_NAME] --host=[HOST] --instance=[INSTANCE_NAME] --password=[PASSWORD]
```

![2019-10-13-22-07-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/ce03399e-f228-a419-11d0-4a06ee07bf05.png)


#### 設定ファイルの修正

DB設定を追加する。

```diff:app.yaml
runtime: php72

env_variables:
  APP_KEY: YOUR_APP_KEY
  APP_STORAGE: /tmp
  VIEW_COMPILED_PATH: /tmp
+  CACHE_DRIVER: database
+  SESSION_DRIVER: database
+  ## Set these environment variables according to your CloudSQL configuration.
+  DB_DATABASE: YOUR_DB_DATABASE
+  DB_USERNAME: YOUR_DB_USERNAME
+  DB_PASSWORD: YOUR_DB_PASSWORD
+  DB_SOCKET: "/cloudsql/YOUR_CONNECTION_NAME"
```

#### passport の設定を環境変数にいれるようにする

* [passport](https://readouble.com/laravel/6.0/ja/passport.html)の「Passportのデプロイ」を参照

##### 設定ファイルの作成

```
php artisan vendor:publish --tag=passport-config
```

##### 環境変数にファイルの内容を埋め込む

* `php artisan passport:install`で以下のファイルができている
  * storage/oauth-private.key
  * storage/oauth-private.key

この鍵ファイルの内容を以下のように設定ファイルに入れる

```diff:app.yaml
runtime: php72

env_variables:
  APP_KEY: YOUR_APP_KEY
  APP_STORAGE: /tmp
  VIEW_COMPILED_PATH: /tmp
  CACHE_DRIVER: database
  SESSION_DRIVER: database
  ## Set these environment variables according to your CloudSQL configuration.
  DB_DATABASE: YOUR_DB_DATABASE
  DB_USERNAME: YOUR_DB_USERNAME
  DB_PASSWORD: YOUR_DB_PASSWORD
  DB_SOCKET: "/cloudsql/YOUR_CONNECTION_NAME"
+   PASSPORT_PRIVATE_KEY: |
+     -----BEGIN RSA PRIVATE KEY-----
+     <private key here>
+     -----END RSA PRIVATE KEY-----
+   PASSPORT_PUBLIC_KEY: |
+     -----BEGIN PUBLIC KEY-----
+     <public key here>
+     -----END PUBLIC KEY-----
```


## 公開準備

### Firebase のシークレットファイルの場所を追記。

[前回](https://qiita.com/hibohiboo/items/11768cb10bf1e7025090)でFirebaseを導入したため。

```diff:app.yaml
env_variables:
+  FIREBASE_CREDENTIALS: secret.json
```

これで公開してやれば、動く。
[ここまでのソース](https://github.com/hibohiboo/whitemap/tree/60b615495d5b79c9344637e27ed660933d6cd7d2/laravel_docker/whitemap)

はず。

### cloud sql のストレージに初期から１Gあってちょっとだけびっくりした

![2019-10-13-20-36-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/c2b73f7d-3d53-de8a-d7ac-48ec4e7144d9.png)

ほとんどデータいれていない状態で、1.13GiB あって少し驚いた。
メタデータとかも容量に含まれているのね。


## 参考

[Run Laravel on Google App Engine standard environment](https://cloud.google.com/community/tutorials/run-laravel-on-appengine-standard)
[Google App Engine で Laravel を動かして Cloud SQL へ接続してみた](https://memento-mori.jp/blog/back-end/google-app-engine_on_laravel)
[Cloud SQL for MySQL インスタンス](https://cloud.google.com/sql/docs/mysql/create-instance)
[【Docker】AlpineLinux を使った Laravel 環境構築](https://qiita.com/gatapon/items/cfdceedee29570185325)
[Cloud SQL for MySQL ユーザ作成](https://cloud.google.com/sql/docs/mysql/create-manage-users?hl=ja)
[passport](https://readouble.com/laravel/6.0/ja/passport.html)
[Laravel Passport の暗号キー情報を環境変数(.env ファイル)で保持する方法](https://qiita.com/hypermkt/items/6ad0c9535dd1b22ca3be)
[複数行の yaml](https://magazine.rubyist.net/articles/0009/0009-YAML.html#%E8%A4%87%E6%95%B0%E8%A1%8C%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97)
[Logging](https://cloud.google.com/community/tutorials/run-laravel-on-appengine-standard)
[PHP 用 Error Reporting の設定](https://cloud.google.com/error-reporting/docs/setup/php)
[Laravel5.5 を Google App Engine で動かす](https://qiita.com/fullkawa/items/4d6b080385de5523835c)
[passport](https://readouble.com/laravel/6.0/ja/passport.html)
[Laravel Passportの暗号キー情報を環境変数(.envファイル)で保持する方法](https://qiita.com/hypermkt/items/6ad0c9535dd1b22ca3be)