Laravel6をGoogle App Engineで動かす


TL;DR

GCPのApp EngineでLaravel6.8を動かしてみました。

下記のチュートリアルに手順が示されています。

準備

プロジェクトを作り、課金を有効にしましょう。
Cloud SDKをローカルマシンにインストールして、gcloudコマンドを使えるようにします。
gcloudで作成したプロジェクトを選択します。

Laravelのインストール

ToDoアプリを作るという前提でインストールします(実際にこの記事で作るまでには至りませんが
インストールされるのは2020-01-02現在最新のLaravel6.8.0です。

$ composer create-project --prefer-dist laravel/laravel todo
$ cd todo
$ php artisan serve

ここまででブラウザで表示出来ることを確認します。

App Engine用の変更

ここからApp Engineのための変更を加えていきます。

app.yamlの作成

App Engineは設定ファイルのapp.yamlが必要です。

app.yaml
runtime: php72

env_variables:
  ## Put production environment variables here.
  APP_KEY: YOUR_APP_KEY
  APP_STORAGE: /tmp
  VIEW_COMPILED_PATH: /tmp
  SESSION_DRIVER: cookie

アプリケーションキーの更新

Laravelのアプリケーションキーをapp.yamlに追加します。

$ sed -i '' "s#YOUR_APP_KEY#$(php artisan key:generate --show --no-ansi)#" app.yaml

bootstrap/app.phpの修正

App Engine用にストレージパスを変更します。

bootstrap/app.php
/*
|--------------------------------------------------------------------------
| Set Storage Path
|--------------------------------------------------------------------------
|
| This script allows you to override the default storage location used by
| the  application.  You may set the APP_STORAGE environment variable
| in your .env file,  if not set the default location will be used
|
*/
$app->useStoragePath(env('APP_STORAGE', base_path() . '/storage'));

チュートリアルにはbeyondcode/laravel-dump-serverの削除とありますが、
Laravel6では初めからbeyondcode/laravel-dump-serverは含まれていないので大丈夫です。

デプロイ

$ gcloud app deploy

どのリージョンにデプロイするか聞かれるので、今回はasia-northeast1(東京)を選択。
デプロイが成功すると、以下のコマンドでブラウザが開きます。

$ gcloud app browse

ここまででまずファーストステップ完了。

デプロイの際に.gcloudignoreが生成されました。
これにはデプロイから除外するファイルを記述します。
確認するとvendorなどが含まれています。
そこで.gcloudignore.envを追加します。
環境変数はapp.yamlで渡すほうがいいと思います。

Cloud SQLの使用

次にデータベースを使えるように設定します。
まずCloud SQL for MySQLの第2世代インスタンスを作成します。

Cloud SQL Proxy

次にローカルマシン上でCloud SQLへのマイグレーションを実行出来るように、Cloud SQL Proxyをインストールします。
INSTANCE_CONNECTION_NAMEは作成したMySQLインスタンスのインスタンス接続名です。

$ curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
$ chmod +x cloud_sql_proxy
$ ./cloud_sql_proxy -instances=INSTANCE_CONNECTION_NAME=tcp:3306

データベースの作成。

Cloud SQL Proxyを使えるようになったのでgcloudコマンドでデータベースを作ります。
YOUR_INSTANCE_NAMEはインスタンス名で、インスタンス接続名とは違います。
以下ではlaravel-todoというデータベースを作っています。

$ gcloud sql databases create laravel-todo --instance=YOUR_INSTANCE_NAME

マイグレーション

セッションテーブルとキャッシュテーブルをマイグレーションします。
準備として、.envにパスワードなどを追加しておきましょう。

php artisan session:table
php artisan cache:table
php artisan migrate

これでプロキシ経由でマイグレーションが実行されます。

デプロイ

再びapp.yamlを編集します。
パスワードやインスタンス接続名などを書き換えてください。

app.yaml
runtime: php72

env_variables:
  ## Put production environment variables here.
  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"
$ gcloud app deploy

ブラウザで確認すると、エラーとなってしまいました。
エラーは以下のコマンドでリアルタイムに確認出来ます。

$ gcloud app logs tail -s default

いろいろ調べたんですが、これという原因はわからず、確実にエラーが解消されるのはStorageにあるコンテナイメージのバケットを削除してからデプロイし直すことでした。対処方法がこれで本当にいいのかわかりませんが。。。
ブラウザでアクセスした後にデータベースのsessionsテーブルを確認したら、ちゃんとデータが入っていたので、Cloud SQLが使えることもわかりました。

その他のエラー

あと、

Class 'Facade\Ignition\IgnitionServiceProvider' not found

というエラーが出る場合もあります。
これは、facade/ignitionrequire-devではなくrequireのほうに移さないといけないっぽいです。

$ composer require facade/ignition

gcloud app deployでデプロイされるのはproductionのようなんですが、.envもしくはapp.yamlAPP_DEBUGtrueになっていると、facade/ignitionが必要になるかららしいです。

アプリケーションの無効化

プロジェクトは削除したくないけど、一旦アプリケーションにアクセス出来ないようにしたい場合があると思います。
そのときは、App Engineの設定から「アプリケーションを無効にする」でアクセス出来ないようにします。

まとめ

デプロイを繰り返すとエラーになったり不思議な現象に悩まされました
Storageのバケット削除で対処したけど本当にこれでいいのかわかりません。
しかし簡単にLaravelアプリをデプロイ出来るのは魅力的ですね

参考URL

https://cloud.google.com/community/tutorials/run-laravel-on-appengine-standard?hl=ja
https://cloud.google.com/sdk/docs/downloads-interactive?hl=ja
https://cloud.google.com/sql/docs/mysql/quickstart-proxy-test?hl=ja
https://stackoverflow.com/questions/58087153/laravel-with-app-engine-standard-class-facade-ignition-ignitionserviceprovider
https://qiita.com/hibohiboo/items/526566ffa007fe1ec84b