Ruby Postgres gem の AWS Lambda レイヤーが機能しない
概要
この投稿をガイドとして使用して、Ruby 上で実行される AWS Lambda 用の Postgres レイヤーを構築しようとしていますが、機能しません。
これが Dockerfile です。これを機能させるために、RUN バンドル設定cache_all true と RUN バンドルパッケージを追加しました。 RUN env ARCHFLAGS=“-arch aarch64” gem install pg も試しましたが、まだ機能しませんでした。
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)
# See https://northsail.io/articles/aws-lambda-ruby-2-7-pg-gem-libldap-error
# for what to libpq binaries to copy for Amazon Linux 2
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
これは、レイヤー内の gem が機能しているかどうかをテストするラムダ関数です。
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 のネイティブ拡張機能がインストールされていないか、別のアーキテクチャ用にインストールされているようですが、現時点ではそれを修正する方法がわからず、かなり混乱しています。
これを機能させる方法についてのアドバイスをいただければ幸いです。 ありがとう。
解決策
別の Docker イメージを使用すると機能しました。
FROM public.ecr.aws/sam/build-ruby3.2:latest-x86_64
どうやら、以前のものはアーキテクチャが異なっており、間違った依存関係がインストールされていたようです。