Zag*_*ags 4 ruby rubygems amazon-web-services aws-lambda
我有一个尝试在 AWS Lambda 上运行的 ruby 脚本。我如何让它使用带有本机扩展的 Ruby gem?
我已经安装了我的 Ruby gembundle install --deployment并将它们包含在我的部署中。当我在 lambda 上运行该函数时,出现错误:
忽略 oj-2.18.5,因为没有构建它的扩展。尝试: gem pristine oj --version 2.18.5
加载处理程序时初始化错误
{
"errorMessage": "libruby.so.2.5: 无法打开共享对象文件:没有那个文件或目录 - /opt/ruby/gems/2.5.0/gems/oj-2.18.5/lib/oj/oj.so" ,
...
我尝试在 lambda 代码本身和 lambda 层中包含依赖项。唯一改变的是错误消息中的路径。
Lambda 能够找到我的红宝石宝石。当它们位于错误的位置时,我会收到不同的错误。
/opt/ruby/gems/2.5.0/gems/oj-2.18.5/lib/oj/oj.so 确实存在。
我已经用bundle installUbuntu 和 AWS-linux生成的文件尝试过这个。在这两个系统上,bundle 通知我它是“使用本机扩展安装 oj 2.18.5”。
如果我将 的副本上传libruby.so到我的 lambda,并将环境变量LD_LIBRARY_PATH设置为其位置并使用安装在 AWS-linux 上的一组依赖项修复上面列出的错误,但只会给我一个更不透明的错误:
/lib64/libc.so.6:未找到版本“GLIBC_2.25”(/opt/ruby/lib/libruby.so.2.5 需要)
运行ldd在宝石/ OJ-2.18.5 / lib目录/ OJ / oj.so澄清的第一个错误。问题不是oj.so不存在,而是libruby.so.2.5不存在。第二个问题是当前的 Ruby lambda 有 glibc 版本 2.17,其中 AWS-linux 带有 glibc 版本 2.25。
这里的基本问题是,如果您有本机依赖项,您需要将 gem 安装在与它们将运行的系统相同的系统上。我发现做到这一点的最好方法是使用 docker。 https://github.com/lambci/docker-lambda有 lambda 安装的 docker 镜像。
对于 ruby,请执行以下操作:
docker run -v "$PWD":/var/task --entrypoint bundle lambci/lambda-base:ruby2.5 install --path=/var/task这将为您提供一个名为ruby与 lambda 兼容的版本依赖项的文件夹。
如果您打算将此输出与 lambda 层一起使用,请记住 bunlde 生成的文件结构是ruby/2.5.0/...并且需要ruby/gems/2.5.0/...在上传之前。
问题正是如您所说,总结一下:本机扩展 gem 需要在与运行它们相同的环境中构建。因此,在将vendor上传到aws之前,我们必须在类似于lambda的环境中安装gems。
要以符合 lambda 的方式构建供应商/捆绑包,请使用以下 docker 容器:
docker run --rm -v "$PWD":/var/task lambci/lambda:build-ruby2.7 bundle install --deployment
Run Code Online (Sandbox Code Playgroud)
这将为您提供有效的供应商/捆绑包依赖性。
您可以运行另一个容器来检查该功能是否有效:
docker run --rm -v $PWD:/var/task:ro,delegated lambci/lambda:ruby2.7 lambda_handler.lambda_handler
Run Code Online (Sandbox Code Playgroud)
完整的图像列表在这里: https://github.com/lambci/docker-lambda
这个问题已经有 1 年历史了,但我不得不搜索大约 2 个小时才能解决与 gem nokogiri 完全相同的问题,所以我认为这可能对某人有用。
希望这能让您省去谷歌搜索的时间!
| 归档时间: |
|
| 查看次数: |
1093 次 |
| 最近记录: |