私はPHPerなのですが、最近、仕事関係でLambdaの話がちょくちょく出てきたので、ちょっと勉強がてら調査することに。
今更なのですが Lambda でPHPを動かせるようになっていたということに驚いた。
で、調べてみるとどうやらbrefというライブラリを使えば、簡単にLambda上でLaravelも動かせるらしい。
Bref - Serverless PHP made simple
わざわざ Lambda で PHPを使う必要があるのかと思うかもだけど、一緒にお仕事しているチームの構成を考えるとメンテナンスも含めてLaravelが使えるというのはとても助かるのです。
で、さくっと試してみようと思ったところデプロイで躓いちゃったので、メモ残しておきます。
環境
- Windows 10 Home
- Docker Toolbox
- PHP7.4
- Laravel 8
IAM ユーザーを作成する
Lambda を利用するにあたり必要な IAM ユーザーを作成。
Creating AWS access keys - Bref
とりあえず試したいだけだから、まんまガイドに従って作成。
簡単、簡単。
serverless framwork のインストール
後述しますが、本当は docker で serverless が動作する環境を作ろうと思っていたのですが、なぜかメモリ不足というエラーのため動作せず。。。
なので、Windows に直接 serverless をインストール。
Serverless Getting Started Guide
docker で環境作りに悩んでいたのが馬鹿みたいに、サクッと環境ができた。
credential の設定もガイドに従って設定。
私、この環境を作るまでChocolateyというソフトを存じ上げませんでした。
いや~、ダサいというイメージの Windows ですが、少しずつクールになってきていると思っているのは私だけ?w
Laravel 環境を docker で作る
毎回 docker 自分で作るの面倒だなぁと思っていたら、多くのLGTMがついてた下記で環境作り。
最強のLaravel開発環境をDockerを使って構築する【新編集版】 - Qiita
いや~、ありがたい。
bref をインストール
公式ドキュメント通り。
Serverless Laravel applications - Bref
ガイドに従って、.env
の設定も行いましたよ。
#LOG_CHANNEL=stack
LOG_CHANNEL=stderr
#SESSION_DRIVER=file
SESSION_DRIVER=array
VIEW_COMPILED_PATH=/tmp/storage/framework/views
楽ですね~
いざ deploy したら、動かなかった。。。
ここまで、ガイドに従うだけなので、超簡単に環境構築できていました。
serverless deploy
でデプロイもすんなり成功!
が、、、エンドポイントにアクセスしたらエラー発生。。。
Exception
The /var/task/bootstrap/cache directory must be present and writable.
----
/var/task/vendor/laravel/framework/src/Illuminate/Foundation/PackageManifest.php
----
return [];
}
return json_decode(file_get_contents(
$this->basePath.'/composer.json'
), true)['extra']['laravel']['dont-discover'] ?? [];
}
/**
* Write the given manifest array to disk.
*
* @param array $manifest
* @return void
*
* @throws \Exception
*/
protected function write(array $manifest)
{
if (! is_writable($dirname = dirname($this->manifestPath))) {
throw new Exception("The {$dirname} directory must be present and writable.");
}
$this->files->replace(
$this->manifestPath, '<?php return '.var_export($manifest, true).';'
);
}
}
----
Arguments
"The /var/task/bootstrap/cache directory must be present and writable."
で結論からいうと、エラーの通り /var/task/bootstrap/cache
に書き込もうとしてエラーが発生しているので、これを直す。
Lambda で書き込み権限あるのは、/tmp
配下だけらしいので、以下を .env
に追加。
APP_SERVICES_CACHE=/tmp/services.php
APP_PACKAGES_CACHE=/tmp/packages.php
APP_CONFIG_CACHE=/tmp/config.php
APP_ROUTES_CACHE=/tmp/routes.php
APP_EVENTS_CACHE=/tmp/events.php
で、再度デプロイして、アクセスすると200が返ってきましたよ~
上記の設定をする前にググってたら、 $app->useStoragePath()
を設定すると良いよとか書いてあったので、試したりしたのですがうまくいかず、上記の記述を追加するまでにまぁまぁな時間がかかりました。。
というわけで、どなたか同じ状況になったときの参考にしてもらえれば幸いです。
(番外)dockerにserverless環境を作ったけど、deploy できなかった。。
前述の docker 環境に以下のような serverless 用のコンポーネントを作った。
serverless:
build:
context: .
dockerfile: ./infra/docker/serverless/Dockerfile
args:
- AWS_ACCESS_KEY_ID=<key>
- AWS_SECRET_ACCESS_KEY=<secret>
tty: true
stdin_open: true
image: serverless
working_dir: /app
volumes:
- ./backend:/app
container_name: serverless
FROM python:3.7-alpine
ARG AWS_ACCESS_KEY_ID
ARG AWS_SECRET_ACCESS_KEY
ENV NODE_PATH /usr/lib/node_modules/
# install nodejs
RUN apk update \
&& apk add --no-cache nodejs npm
# install aws-cli
RUN pip install awscli
# install serverless framework
RUN npm install -g serverless serverless-plugin-existing-s3
# set aws key
RUN sls config credentials --provider aws --key $AWS_ACCESS_KEY_ID --secret $AWS_SECRET_ACCESS_KEY
# change work directory
RUN mkdir -p /app
WORKDIR /app
ほんでもって、docker内で serverless deploy
を実行したところ、なぜか以下のエラー。
Serverless: Setting up AWS...
root@02e9b3d52dbe:/work/backend# serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Error --------------------------------------------------
Error: ENOMEM: not enough memory, open '/work/backend/vendor/mockery/mockery/library/Mockery/Matcher/NoArgs.php'
For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Issues: forum.serverless.com
Your Environment Information ---------------------------
Operating System: linux
Node Version: 12.19.0
Framework Version: 2.5.0
Plugin Version: 4.0.4
SDK Version: 2.3.2
Components Version: 3.2.1
メモリは十分にあると思うのに理由がわからない。
散々悩んだあげく、諦めたのさ~