lambdaでRubyを使ってPostgresにアクセスする際に以下のようなエラーが出る場合があります。
Ignoring pg-1.1.4 because its extensions are not built. Try: gem pristine pg --version 1.1.4
それをどのように解決したかを記載します。
###結論
pgやnokogiriなど、c言語のライブラリを使用しているものをrequireする際は
linux環境(redhat系)でbundle installを行ったvendorフォルダをlambda上にアップロードする。
###原因
lambdaがc言語のライブラリを参照する際にライブラリのパスが分からない。
###解決方法
dockerでAmazonLinuxの仮想環境を作成し、そこでbundle installを実行します。
####前提
- GemfileでRubyの開発環境が作れる
- Dockerがインストールしてある
####通常のlambdaでRuby動かすための環境構築
- Gemfileを作成
source "https://rubygems.org"
gem "aws-sdk"
gem "pg"
- lambda上で動作するRubyファイルを作成
require 'aws-sdk'
require 'pg'
def lambda_handler(event:, context:)
host = String("hogehoge")
db = String("postgres")
user = String("hoge")
pass = String("geho")
port = String("5432")
PG::Connection.new(:host => host, :user => user, :dbname => database, :port => port, :password => password)
{ statusCode: 200, body: JSON.generate('Hello from Lambda. powerd by Ruby!!')
end
- Gemifileが配置されているディレクトリで
bundle install --path vendor/bundle
実行 - Zipしてアップロード
####ハマったこと
以下のようなエラーが出る
Ignoring pg-1.1.4 because its extensions are not built. Try: gem pristine pg --version 1.1.4
####解決方法
参考にしたgitリポジトリ
https://github.com/stevenringo/lambda-ruby-pg-nokogiri
- dockerでvendorを作る仮想環境を呼び出す
ホストマシン上でGemfileを作った上で、そのフォルダ上で以下を実行し仮想環境に入る
docker run -v `pwd`:/var/task -it stevenringo/lambda-ruby2.5-postgresql10 /bin/sh
- 実行環境作成に必要な環境を整備する
bundle config --local build.pg --with-pg-config=/usr/pgsql-10/bin/pg_config
bundle config --local silence_root_warning true
bundle install --path vendor/bundle --clean
mkdir -p /var/task/lib
cp -a /usr/pgsql-10/lib/*.so.* /var/task/lib/
※途中のmkdir -p /var/task/lib
とcp -a /usr/pgsql-10/lib/*.so.* /var/task/lib/
も省略せずに行ってください。
これを怠るとZIPアップロード後に
"errorMessage": "libpq.so.5: cannot open shared object file: No such file or directory - /var/task/vendor/bundle/ruby/2.5.0/gems/pg-1.1.4/lib/pg_ext.so"
と表示されます。
- zipで固める。
exit
で仮想環境から抜けて、zipで固めます。この時、libフォルダも合わせて固めます。
zip -r hello_world.zip hello_world.rb vendor lib
- ファイルをアップロードする
これで当初のエラーは出なくなるはず。
検索用キーワード
gem
Ruby
postgres
pg
lambda
libpq
pristine
エラー
ラムダ