vognev/laravel-serverless-aws

Laravel/Serverless for AWS Lambda

v0.0.1 2019-09-25 15:44 UTC

This package is auto-updated.

Last update: 2024-09-26 02:39:13 UTC


README

包的目标是提供将 Laravel 应用程序作为 AWS Lambda 函数部署的可能性。

安装

可以使用 composer 在现有项目中安装包

composer require vognev/laravel-serverless-aws

但这更像是一个构建自定义 PHP 运行时的助手,以在 AWS 环境中运行;对于完全可操作的设置,您还应该全局安装 serverless framework

npm install -g serverless

它将提供名为 slsserverless)的二进制文件,该文件将用于部署。

此外,您需要 docker 并安装和配置 aws-cli 工具

aws configure

初始化

运行 php artisan serverless:install 命令。

它将发布

config/serverless.php

这是一个配置文件,您可以在这里调整包的行为。除了能够定义存储包数据的位置外,它的目的是配置应包含在运行时中的哪些 PHP 模块(因为 Lambda 运行时的大小有限)。

storage/serverless

默认情况下,所有与运行时相关的资产都将发布到这里。在您可以在该位置找到 contextruntime 文件夹中,其中包含构建运行时的 Docker 的上下文,以及相应的解包 PHP 运行时。

.php.conf.d

在这个文件夹中,您可以调整 PHP 模块选项,或添加自己的 .ini 配置。

serverless.yml

用于部署的服务器less 框架的项目描述。

docker-compose.serverless.yml

用于模拟生产环境和适合本地开发的独立和示例 docker-compose 栈。

构建运行时

AWS Lambda 函数由几个 layers 组成。我们将构建 runtime layer(提供 PHP 二进制文件)。

运行时使用 Docker 和 storage/serverless/context 目录中看到的上下文构建。构建过程将生成带有多个 .so 模块的 php 二进制文件,这些模块配置为以便携方式从 /opt/ (Lambda 层解包的位置)调用(为了不在 AWS 环境中依赖缺失的共享库)

有关更多详细信息,请参阅 Custom AWS Lambda Runtimes

在 Dockerfile 中,您可以找到几个阶段

  • sources - 获取并解包 php(和其他)源
  • builder - 将解包的源构建
  • bundler - 将便携式 PHP 分发到 /opt

一旦上下文发布,您可以将它添加到 VCS 并根据您的需求进行调整。调整的一个方面就是更新构建列表(config/serverless.php)以构建(可用模块可以在 storage/serverless/context/php-modules.sh 中找到)。此外,没有任何东西可以阻止您构建额外的 pecl 模块,更改 PHP 版本,甚至重写整个 Dockerfile。

完成操作后,运行 php artisan serverless:runtime 并在 storage/serverless/runtime 下找到它。

提示:您可以使用 Docker-in-Docker(dind)和 tmpfs 用于存储来加快构建速度,我们不需要从它那里获得任何持久性

docker run --name dind -d --tmpfs=/var/lib/docker --privileged -p 2375:2375 \
  --entrypoint dockerd docker:dind --host tcp://0.0.0.0:2375
DOCKER_HOST=127.0.0.1:2375 php artisan serverless:runtime

服务器less 配置

部署通过调整 serverless.yml 选项进行配置。

服务名称

service 名称在 AWS 中标识您的项目。

service: workbench

提供者

provider.name 总是等于 aws,因为我们正在部署到 AWS Lambda。

provider.region 包含要部署函数的区域名称。

provider.runtime 总是等于 privided,因为我们正在构建自己的 PHP 运行时(PHP 不可在 AWS 上使用)。

provider:
  name: aws
  region: eu-central-1
  runtime: provided

环境变量

AWS Lambda 文件系统为只读(除 /tmp 之外),因此,对于 Laravel,我们应该更新各种可写路径,使其指向其中的位置。在初始化时,函数的引导脚本将创建这些文件夹,因此我们只需通过环境变量来调整它们。

此外,不能保证不同的请求将由相同的函数实例处理,因此会话也应持久化在外部存储或仅在 cookie 中。

这些变量应尽早设置,因此我们无法依赖于 .env 变量并将它们注入到函数过程中。

provider:
  environment:
    LOG_CHANNEL: stderr
    SESSION_DRIVER: cookie
    APP_PACKAGES_CACHE: /tmp/packages.php
    APP_SERVICES_CACHE: /tmp/services.php
    APP_CONFIG_CACHE: /tmp/config.php
    APP_ROUTES_CACHE: /tmp/routes.php
    APP_EVENTS_CACHE: /tmp/events.php

这里我们告诉 Serverless Framework,我们将使用我们自定义构建的 runtime,并指定其位置。

layers:
  runtime:
    retain: false
    package:
      artifact: storage/serverless/runtime.zip

包含/排除

在这里,您可以指定要包含或排除在最终函数层中的路径(使用 glob 表达式)。

package:
  include:
    - tests/TestCase.php
  exclude:
    - .idea/**
    - storage/**
    - node_modules/**
    - bootstrap/cache/**
    - tests/**

网站函数

此函数提供项目的 http 入口点,因此我们必须为此定义 http 事件,然后 Serverless 将为我们创建 函数 API 网关

注意:我们还在源代码本身中组合了函数,以及我们正在构建的自定义 PHP 运行时(使用 yml 的 layers 键)

functions:
  website:
    handler: website
    memorySize: 128
    timeout: 30
    events:
      - http: 'ANY /'
      - http: 'ANY /{proxy+}'
    layers:
      - { Ref: RuntimeLambdaLayer }

Artisan 函数

此函数提供项目的 cli 入口点。在这里,我们已定义 CloudWatch Events 触发器,它将触发 Laravel 的计划命令。

  artisan:
    handler: artisan
    memorySize: 128
    timeout: 900
    events:
      - schedule:
          rate: rate(1 minute)
          input:
            - 'schedule:run'
            - '--no-ansi'
            - '-n'
          enabled: true
    layers:
      - { Ref: RuntimeLambdaLayer }

SQS 队列

为了能够通过应用程序运行和计划队列作业,可以配置 SQS 队列。Serverless Framework 不会为您创建它,因此您应该使用 AWS 管理控制台手动创建它。

接下来,您应确保 sqs 队列配置包含 token 参数,因此请相应地更新您的 config/queue.php 文件。

return [
  'sqs' => [
     'token' => env('AWS_SESSION_TOKEN')
  ]
];

然后,使用 composer require aws/aws-sdk-php 安装 php 的 aws-sdk,这样您将拥有工作的 SQS 队列驱动程序,并使用 serverless.yml 的环境变量部分进行配置

provider:
  environment:
    QUEUE_CONNECTION: sqs
    SQS_PREFIX: https://sqs.<region_id>.amazonaws.com/<account_d>/
    SQS_QUEUE: <queue_name>

并为 artisan 函数定义 SQS 触发器

functions:
  artisan:
    events:
      - sqs:
          arn: arn:aws:sqs:<region_id>:<account_id>:<queue_name>
          enabled: true
          batchSize: 1

在此阶段,函数的角色将阻止其向队列发送消息;因此,一旦您部署了函数,请转到 IAM,找到与您的函数关联的角色,并编辑其策略以包含 SQS.SendMessage 操作。

部署

完成上述步骤后,您可以使用 sls deploy 命令将项目部署到 AWS。