如何在AWS Lambda或Serverless环境中打包Composer依赖? (部署策略)

12次阅读

必须在本地或CI中用与Lambda一致的php版本和架构执行composer install –no-dev –optimize-autoloader,再打包vendor部署;推荐使用AWS官方docker镜像构建以确保环境一致。

如何在AWS Lambda或Serverless环境中打包Composer依赖? (部署策略)

在 AWS Lambda 或 serverless Framework 环境中,composer install 不能直接在 Lambda 运行时执行(无写入权限、无 PHP CLI 环境、无网络),必须在构建阶段完成依赖打包。

本地构建 + vendor 打包是最可靠的方式

Serverless Framework 和 AWS SAM 都不支持运行时安装 Composer 包。你必须在本地(或 CI 环境)用与 Lambda 相同的 PHP 版本和架构(x86_64 或 arm64)执行 composer install --no-dev --optimize-autoloader,再将 vendor/ 和代码一起 zip 部署。

  • 确保本地 PHP 版本与 Lambda 运行时一致(如 php8.2);可用 php -v 核对
  • 务必加 --no-dev:Lambda 不需要 phpunitpsysh 等开发依赖,否则可能超 250MB 解压限制
  • --optimize-autoloader 生成 vendor/autoload.php 的静态映射,提升冷启动性能
  • 避免在 composer.json 中使用 platform 配置伪造环境——它可能导致 autoloader 生成错误路径

使用 Docker 构建可避免“本地环境不一致”问题

本地 PHP 版本或扩展缺失(如 zipmbstring)会导致 autoload_static.php 生成异常,Lambda 启动时报 class not found。用官方 AWS Lambda PHP 镜像构建能完全对齐。

docker run --rm -v $(pwd):/var/task public.ecr.aws/sam/build-php8.2    /bin/sh -c "cd /var/task && composer install --no-dev --optimize-autoloader"
  • 镜像地址随运行时更新:public.ecr.aws/sam/build-php8.1public.ecr.aws/sam/build-php8.3
  • 该镜像已预装 zipcurlgit 和必要扩展,无需额外配置
  • 不要在容器内执行 composer update——会污染 composer.lock,应只做 install

Serverless Framework 中的打包路径必须显式声明

serverless.yml 默认只打包当前目录下非 node_modules 的文件,vendor/ 若在项目根目录外(如被 composer install -d ../shared-vendor 指定),会被忽略。

  • package/include 显式包含:
    package:   include:     - 'vendor/**'
  • 若用 vendor/ 在子目录(如 src/vendor),需确认 composer install -d src 后路径正确,并在 include 中写 src/vendor/**
  • 禁用自动打包(package: individually: true)后,必须为每个函数单独指定 package/include,否则 vendor/ 不会进入 ZIP
  • 别依赖 functions.*.package.artifact 指向已有 ZIP——它绕过 include 规则,vendor 可能缺失

最易被忽略的是 autoloader 路径硬编码问题:某些包(如 monolog/monolog)在生成优化类映射时,会把绝对路径写进 vendor/composer/autoload_static.php。Docker 构建时若挂载路径不一致(如 /var/task vs /home/project),Lambda 解压require 会失败。解决方法只有两个:用标准挂载路径(如上面示例),或改用 composer install --classmap-authoritative(更严格,但兼容性略低)。

text=ZqhQzanResources