Snippets
Laravel Serverless

Laravel Serverless with bref

  • This template will create a Laravel application with Bref and deploy it to AWS Lambda using Serverless Framework.
  • It includes a Dockerfile for building the application image, a serverless.yml configuration file for deploying the application and a GitHub action for deploying the application to AWS Lambda.
  • There will be a single ECR repository for the application and different images tagged for different kernels (e.g. bref/php-82-fpm:2, bref/php-82-console:2, bref/php-82:2)

Dockerfile

  • This Dockerfile is used to build the application image. It uses the bref/php-82 base image and installs Composer dependencies.
  • For different kernels such as http, worker, console, we change the base image in serverless.yml.
ARG BASE_IMAGE
 
FROM bref/php-82:2 as app-builder
 
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
 
COPY composer.json composer.lock /var/task/
 
RUN composer install --no-autoloader --no-scripts
 
COPY . /var/task
 
RUN composer dump-autoload
 
FROM $BASE_IMAGE
 
# Add extra extensions if any here
# COPY --from=bref/extra-imap-php-82:1 /opt /opt
COPY --from=app-builder /var/task /var/task

serverless.yml

service: app-name
 
provider:
  name: aws
  profile: default
  # The AWS region in which to deploy (ap-southeast-1 (Singapore) is the default)
  region: ap-southeast-1
  runtime: provided.al2
  ecr:
    images:
      app-name-http:
        path: "."
        file: "Dockerfile"
        buildArgs:
          "BASE_IMAGE": "bref/php-82-fpm:2"
      app-name-console:
        path: "."
        file: "Dockerfile"
        buildArgs:
          "BASE_IMAGE": "bref/php-82-console:2"
      app-name-worker:
        path: "."
        file: "Dockerfile"
        buildArgs:
          "BASE_IMAGE": "bref/php-82:2"
 
package:
  # Directories to exclude from deployment
  patterns:
    - '!node_modules/**'
    - '!public/storage'
    - '!resources/assets/**'
    - '!storage/**'
    - '!tests/**'
 
functions:
  api:
    image:
      name: app-name-http
      command:
        - "public/index.php"
    timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
    events:
      - httpApi: '*'
  artisan:
    image:
      name: app-name-console
      command:
        - "artisan"
    timeout: 120 # in seconds
    events:
      - schedule:
          description: Running the Laravel Scheduler (schedule:run) each minute
          rate: rate(1 minute)
          input:
            cli: schedule:run
 
constructs:
  defaultJobs:
    type: queue
    worker:
      image:
        name: app-name-worker
        command:
          - "Bref\\LaravelBridge\\Queue\\QueueHandler"
      timeout: 60 # seconds
 
plugins:
  - ./vendor/bref/bref
  - ./vendor/bref/extra-php-extensions
  - serverless-lift

deploy.yml

name: Deploy master branch
 
on:
  push:
    branches:
      - main
  workflow_dispatch:
 
jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    steps:
      - uses: actions/checkout@v2
      - uses: "shivammathur/setup-php@v2"
        with:
          php-version: "8.2"
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          file: Dockerfile
      - name: Login to ECR
        uses: docker/login-action@v3
        with:
          registry: ${{ vars.AWS_ACCOUNT_ID }}.dkr.ecr.ap-southeast-1.amazonaws.com
          username: ${{ secrets.AWS_ACCESS_KEY_ID }}
          password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      - uses: "ramsey/composer-install@v2"
      - name: install serverless
        run: |
          npm i -g serverless@3.0
          serverless config credentials --profile default -p aws -k ${{ secrets.AWS_ACCESS_KEY_ID }} -s ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          serverless plugin install -n serverless-lift
      - name: serverless deploy
        run: |
          serverless deploy --verbose
          echo "Migrating...."
          serverless bref:cli -f artisan -a "migrate --force"