Help us understand the problem. What is going on with this article?

brefphpを使って簡単にLaravelをサーバレス環境で動かす

はじめに

ここではbrefについてと、実際の使い方や使ってみた所感などをまとめてみようと思います。

brefphp とは?

PHPアプリケーションをAWS Lambdaに簡単にデプロイするための Composer パッケージです。
コマンド1つでサーバーからアプリケーションのデプロイまで行えます。

:information_source: 使い方

Step :one: serverless のインストール

bref は serverless コマンドを使用してAWS環境にデプロイを行います。
以下のコマンドでインストールしましょう。

npmの場合

npm install -g serverless

yarnの場合

yarn global add serverless

追加したら以下のコマンドでちゃんと実行できるか確認しましょう

$ serverless --version
Framework Core: 2.4.0
Plugin: 4.0.4
SDK: 2.3.2
Components: 3.2.1

Step :two: Laravelプロジェクトの作成 [公式]

今回はLaravelで使うため、プロジェクトを作成します。

Laravelインストーラーがない場合はインストールします

composer global require laravel/installer

プロジェクトを作成します。

laravel new brefphp-test

Step :three: brefphp パッケージのインストール [公式]

作成したLaravelプロジェクトのディレクトリに移動して、
brefphpをインストールします。

composer require bref/bref bref/laravel-bridge

デフォルトのサーバ構成設定ファイルを作成します。

php artisan vendor:publish --tag=serverless-config

Step :four: デプロイの準備

「アクセスキーID」と「シークレットアクセスキー」の作成

デプロイ前に、デプロイ先のサーバ(AWS)のアクセスキーとシークレットキーを使用します。
IAMのユーザー追加画面でテスト用ユーザーを作りましょう。

  1. ユーザー名を決めて、アクセスの種類の「プログラムによるアクセス」をチェックします。
    WS000000.jpg

  2. アクセス権限の設定です。「既存のポリシーを直接アタッチ」を選択して「AdministratorAccess」を選択します。
    名前の通り最強権限なので、発行されるキーは絶対に外部に漏らさないでください!
    WS000001.jpg

  3. タグはよしなに追加します。(自分は何もしません)
    WS000002.jpg

  4. ユーザーの追加完了です。
    「アクセスキーID」と「シークレットアクセスキー」をメモしておいてください。
    WS000004.jpg

プロファイルの追加

メモした「アクセスキーID」と「シークレットアクセスキー」をプロファイルに登録します。

$ aws configure --profile <プロファイル名>

AWS Access Key ID [None]: <アクセスキーID>
AWS Secret Access Key [None]: <シークレットアクセスキー>
Default region name [None]:
Default output format [None]:

すると、 ~/.aws/credentials (Windowsの場合は %USERPROFILE%/.aws/credentials) にプロファイルが登録されます。

/.aws/credentials
[<プロファイル名>]
aws_access_key_id = <アクセスキーID>
aws_secret_access_key = <シークレットアクセスキー>

Step :five: デプロイ

以下のコマンドでデプロイします。
<プロファイル名>は、先程(Step4)で登録した名前を指定してください。

$ serverless deploy -v --aws-profile=<プロファイル名>

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
~~~~~~~[色々ログ出てきて]~~~~~~~
Serverless: Stack update finished...
Service Information
service: laravel
stage: dev
region: us-east-1
stack: laravel-dev
resources: 15
api keys:
  None
endpoints:
  ANY - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev
  ANY - https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/{proxy+}
functions:
  web: laravel-dev-web
  artisan: laravel-dev-artisan
layers:
  None

Stack Outputs
WebLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:laravel-dev-web:2
ArtisanLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:lara![WS000000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157186/369830d6-c723-975d-2b78-c94add355649.jpeg)
vel-dev-artisan:2
ServiceEndpoint: https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: laravel-dev-serverlessdeploymentbucket-o2rnhi5yd9v6

生成されたエンドポイントにアクセスして、LaravelのWelcomeページが出てくれば成功です
Laravel.png

AWS Lambdaの関数にも追加されています。
WS000000.jpg

Step :six: 環境の削除

$ serverless remove コマンドで環境を削除できます。

$ serverless deploy -v --aws-profile=<プロファイル名>

Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack removal progress...
~~~~~~~[色々ログ出てきて]~~~~~~~
Serverless: Stack removal finished...
Serverless: Stack removal finished...

:desktop: ローカル環境の構築

Dockerでローカル環境を構築します。
すでにローカル用のイメージは用意されているので、すぐに立ち上げることができます。

Laravelプロジェクトと同じディレクトリに docker-compose.yml の作成

docker-compose.yml
version: "3.5"

services:
    web:
        image: bref/fpm-dev-gateway
        ports:
            - '8000:80'
        volumes:
            - .:/var/task
        links:
            - php
        environment:
            HANDLER: public/index.php
            DOCUMENT_ROOT: public
    php:
        image: bref/php-74-fpm-dev
        volumes:
            - .:/var/task:ro

docker-compose up -d でコンテナを起動します。1

http://localhost:8000 にアクセスするとLaravelのWelcomeページが表示されます。

:moneybag: 料金について

ローカル環境には料金はかかりません。
AWSにデプロイした際に以下のサービスを利用するため、料金が発生します。

  1. Lambda
  2. API Gateway
  3. S3
  4. CloudFormation

所感

個人開発で使って便利だったので、会社のプロジェクトでも導入してみました。
LambdaやAPI Gatewayによるいろいろな制限があったりして、思うように行かなかった部分もありますが、なんとかサービスもリリースしているような状態です。

EC2に比べてLambdaやAPI Gatewayの料金は基本的にトラフィック依存なので、
アクセス数のそんなにないサービスでは、かなりのコスト削減になりました。

:warning: 発生した問題とその対策

実際にプロジェクトに導入した際に発生した問題と、それについての対策を記述します。
もし似たような問題が発生した場合は参考になればと思います。

POSTで10MBを超えるファイルをアップロードできない

API GatewayのPOSTリクエストサイズの最大が10MBのため、大容量のファイルをPOSTできません。
最終的にS3にアップロードする予定だったので、S3でPresigned URL2を発行して、それに対しアップロードするようにしました。

6MBを超えるデータを返せない

またもやAPI Gatewayの制約により、レスポンスの最大は6MBです。
(まぁ、6MBなんて超えることなんて稀ですが…)
こちらも一度S3にアップロードしてPresigned URLを生成し、
フロントエンドから直接S3のURLを参照するようにしました。

APIのタイムアウトの最長が29秒

API Gatewayの制約上、29秒でタイムアウトしてしまいます。
なので、重い処理はAmazon SQSに投げて処理するようにしました。

クーロンの最大時間が15分

バックグラウンドのクーロン処理は結局Lambda上で行うため、
Lambdaの制約上15分が限界です。

今の所、15分を超えるようなクーロンはないですが、
発生する場合はAmazon SQSで分割して実行するか、
別途専用のサーバを立てる必要がありそうです。

ログの stack が使用できない

Brefのプロバイダにて、stack は強制的に stderr に置き換えられている。
config/logging.php に独自設定を追加するか、
プロバイダを読み込まないようにする対応が必要。

PR

brefのSlackコミュニティに日本語チャンネルができました。
一緒にbrefについて語りましょう😆


  1. 初回のみイメージをビルドするため時間がかかります。 

  2. 一時的に有効なURLを発行して直接S3にアップロードできるURL 

YuK1Game
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away