AWS Lambda Ruby环境Postgres Layer构建失败求助
为Ruby AWS Lambda构建Postgres Layer失败的问题排查
尝试为运行Ruby的AWS Lambda构建Postgres Layer,参考相关帖子操作未成功。已添加RUN bundle config cache_all true和RUN bundle package尝试解决,也试过RUN env ARCHFLAGS="-arch aarch64" gem install pg,均无效。
使用的Dockerfile
FROM public.ecr.aws/lambda/ruby:3.2 RUN yum install -y amazon-linux-extras \ && amazon-linux-extras enable postgresql14 \ && yum group install "Development Tools" -y RUN yum install -y postgresql postgresql-devel ADD Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT} ENV GEM_HOME=${LAMBDA_TASK_ROOT} RUN bundle config cache_all true RUN bundle config set path 'vendor/bundle' RUN bundle install RUN bundle package
构建脚本
#!/bin/sh -e DIST_DIR="pg" rm -rf $DIST_DIR mkdir -p "$DIST_DIR/lib" mkdir -p "$DIST_DIR/ruby/gems" cd "$SOURCE_DIR" >/dev/null || exit docker build -t ruby-builder -f Dockerfile . CONTAINER=$(docker run -d ruby-builder) # 复制Amazon Linux 2所需的libpq相关二进制文件 docker cp \ $CONTAINER:/usr/lib64/libpq.so.5.14 \ $DIST_DIR/lib/libpq.so.5 docker cp \ $CONTAINER:/usr/lib64/libldap_r-2.4.so.2.10.7 \ $DIST_DIR/lib/libldap_r-2.4.so.2 docker cp \ $CONTAINER:/usr/lib64/liblber-2.4.so.2.10.7 \ $DIST_DIR/lib/liblber-2.4.so.2 docker cp \ $CONTAINER:/usr/lib64/libsasl2.so.3.0.0 \ $DIST_DIR/lib/libsasl2.so.3 docker cp \ $CONTAINER:/usr/lib64/libssl3.so \ $DIST_DIR/lib/ docker cp \ $CONTAINER:/usr/lib64/libsmime3.so \ $DIST_DIR/lib/ docker cp \ $CONTAINER:/usr/lib64/libnss3.so \ $DIST_DIR/lib/ docker cp \ $CONTAINER:/usr/lib64/libnssutil3.so \ $DIST_DIR/lib/ docker cp \ $CONTAINER:/var/task/vendor/bundle/ruby/3.2.0 \ $DIST_DIR/ruby/gems/3.2.0 docker stop $CONTAINER docker rm $CONTAINER
生成的目录结构
. ├── lib └── ruby └── gems └── 3.2.0 ├── bin ├── build_info ├── cache ├── doc ├── extensions │ └── aarch64-linux │ └── 3.2.0 ├── gems │ ├── bundler-2.4.17 │ │ ├── exe │ │ └── lib │ └── pg-1.5.4 │ ├── certs │ ├── ext │ ├── lib │ ├── misc │ ├── rakelib │ ├── sample │ └── translation ├── plugins └── specifications
测试Lambda函数
require 'json' require 'pg' def lambda_handler(event:, context:) { statusCode: 200, body: {postgres_client_version: PG.library_version}.to_json } end
报错信息
Test Event Name test Response { "errorMessage": "cannot load such file -- pg", "errorType": "Init<LoadError>", "stackTrace": [ "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "/var/task/lambda_function.rb:2:in `<top (required)>'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'" ] } Function Logs Ignoring pg-1.5.4 because its extensions are not built. Try: gem pristine pg --version 1.5.4 Init error when loading handler lambda_function.lambda_handler { "errorMessage": "cannot load such file -- pg", "errorType": "Init<LoadError>", "stackTrace": [ "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "/var/task/lambda_function.rb:2:in `<top (required)>'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'" ] } INIT_REPORT Init Duration: 324.56 ms Phase: init Status: error Error Type: Runtime.ExitError Ignoring pg-1.5.4 because its extensions are not built. Try: gem pristine pg --version 1.5.4 Init error when loading handler lambda_function.lambda_handler { "errorMessage": "cannot load such file -- pg", "errorType": "Init<LoadError>", "stackTrace": [ "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "/var/task/lambda_function.rb:2:in `<top (required)>'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'", "<internal:/var/lang/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:86:in `require'" ] } INIT_REPORT Init Duration: 2500.61 ms Phase: invoke Status: error Error Type: Runtime.ExitError START RequestId: 2ab0555b-bde9-4cb1-a0d4-ee0d2fe2d0b1 Version: $LATEST Unknown application error occurred Runtime.Unknown END RequestId: 2ab0555b-bde9-4cb1-a0d4-ee0d2fe2d0b1 REPORT RequestId: 2ab0555b-bde9-4cb1-a0d4-ee0d2fe2d0b1 Duration: 2520.07 ms Billed Duration: 2521 ms Memory Size: 128 MB Max Memory Used: 16 MB
解决思路建议
- 验证扩展编译状态:从报错信息看,pg的原生扩展未正确构建。在Dockerfile的
bundle install步骤后添加命令,检查扩展目录是否生成.so文件:
如果没有RUN ls -la ${LAMBDA_TASK_ROOT}/vendor/bundle/ruby/3.2.0/extensions/aarch64-linux/3.2.0/pg-1.5.4/.so文件,说明编译过程存在问题。 - 直接用gem安装pg:跳过bundle,直接指定架构参数安装pg,确保原生扩展适配Lambda的aarch64环境:
RUN env ARCHFLAGS="-arch aarch64" gem install pg -v 1.5.4 --install-dir ${LAMBDA_TASK_ROOT}/vendor/bundle/ruby/3.2.0 - 修正Layer的gem路径识别:AWS Lambda Ruby层需要确保
GEM_PATH包含Layer的gem目录。可以在Layer中添加ruby/lib/ruby/site_ruby/3.2.0/rubygems/defaults/operating_system.rb文件,内容如下:
或者在Lambda函数开头显式设置环境变量:Gem.default_path << '/opt/ruby/gems/3.2.0'ENV['GEM_PATH'] = '/opt/ruby/gems/3.2.0' - 检查系统依赖库的完整性:复制libpq相关文件时,保留原始软链接而非仅复制具体版本文件,避免链接错误。可以修改构建脚本中的复制命令:
docker cp $CONTAINER:/usr/lib64/libpq.so* $DIST_DIR/lib/ - 容器内预测试pg加载:构建完Docker镜像后,进入容器运行
irb并执行require 'pg',确认pg能正常加载,排除构建过程中的问题。
内容的提问来源于stack exchange,提问作者Alvaro
相关产品推荐
相关产品推荐

