AWS Lambda(Ruby 3.2.0)中pg gem自定义层无法加载问题排查
问题:Ruby 3.2 AWS Lambda 使用pg gem自定义层加载失败
我在运行Runtime为Ruby 3.2的AWS Lambda时,使用pg gem自定义层遇到问题。已按照AWS官方文档要求构建自定义层压缩包pg.zip,文件结构如下:
pg.zip └ ruby/gems/3.2.0/ | build_info | cache | doc | extensions | gems | └ pg-1.5.3 └ specifications └ pg-1.5.3.gemspec
该自定义层已添加至Lambda,但测试时出现错误:
{ "errorMessage": "cannot load such file -- pg", "errorType": "Init<LoadError>", "stackTrace": [ "/var/lang/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:59:in `require'", "/var/lang/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:59:in `require'", "/var/task/lambda_function.rb:2:in `<top (required)>'", "/var/lang/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:59:in `require'", "/var/lang/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:59:in `require'" ] }
我在x86_64架构的Mac环境下使用ruby@3.2构建了该包,本地运行Ruby脚本正常。现咨询:
pg.zip的文件结构是否正确?- 是否是环境打包时的兼容性问题导致?
解答
1. 文件结构问题
你的pg.zip结构不正确。
AWS Lambda加载Ruby层时,会将层内容挂载到/opt目录,RubyGems需要能识别/opt/ruby/gems/3.2.0这个路径。当前你的压缩包根目录下直接是ruby/gems/3.2.0/,解压后会变成/opt/ruby/gems/3.2.0/...,但正确的层级应该是压缩包根目录为ruby文件夹,解压后形成/opt/ruby/gems/3.2.0。
修正后的压缩包结构应该是:
pg.zip └── ruby/ └── gems/3.2.0/ | build_info | cache | doc | extensions | gems | └ pg-1.5.3 └ specifications └ pg-1.5.3.gemspec
2. 环境兼容性问题
是的,这大概率是架构与系统兼容性问题导致的。
AWS Lambda的x86_64运行环境基于Amazon Linux 2,你在Mac x86_64环境下构建的pg gem包含针对macOS编译的原生扩展(pg依赖libpq原生库),这些原生库无法在Amazon Linux 2环境下运行,进而触发加载错误。
解决办法:
- 用Docker模拟Amazon Linux 2环境构建:运行
amazonlinux:2容器,在容器内安装Ruby 3.2、libpq-devel等依赖,执行gem install pg -v 1.5.3后,将生成的ruby/gems/3.2.0目录按正确结构打包成层。 - 改用Lambda容器镜像:基于AWS官方Ruby 3.2基础镜像构建自定义镜像,在镜像内直接安装pg gem,绕开层的路径与兼容性问题。
内容的提问来源于stack exchange,提问作者Joseph D.
相关产品推荐
相关产品推荐

