AWSが提供しているlambda/rubyのbaseイメージでffi gemをインストールしようとしたら、native buildで失敗しました。
再現
Gemfile
# frozen_string_literal: true source 'https://rubygems.org' gem 'ffi'
Dockerfile
FROM public.ecr.aws/lambda/ruby:3.2 # 通常はGemfile.lockもコピーするだろうけど再現には必要ないため省略 COPY Gemfile ${LAMBDA_TASK_ROOT}/ RUN gem install bundler && bundle install
こんな環境でdocker buildしてbundle installしようとすると、
$ docker build --platform linux/arm64 -t lambda-ruby-test:test . [+] Building 2.5s (7/7) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 263B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for public.ecr.aws/lambda/ruby:3.2 0.0s => CACHED [1/3] FROM public.ecr.aws/lambda/ruby:3.2 0.0s => [internal] load build context 0.0s => => transferring context: 106B 0.0s => [2/3] COPY Gemfile /var/task/ 0.0s => ERROR [3/3] RUN gem install bundler && bundle install 2.4s 2.4s ------ > [3/3] RUN gem install bundler && bundle install: (略) #0 1.937 Fetching gem metadata from https://rubygems.org/.. #0 1.976 Resolving dependencies... #0 1.979 Fetching ffi 1.16.3 #0 2.144 Installing ffi 1.16.3 with native extensions #0 2.327 Gem::Ext::BuildError: ERROR: Failed to build gem native extension. #0 2.327 #0 2.327 current directory: /var/lang/lib/ruby/gems/3.2.0/gems/ffi-1.16.3/ext/ffi_c #0 2.327 /var/lang/bin/ruby extconf.rb #0 2.327 checking for ffi.h... *** extconf.rb failed *** #0 2.327 Could not create Makefile due to some reason, probably lack of necessary #0 2.327 libraries and/or headers. Check the mkmf.log file for more details. You may #0 2.327 need configuration options. (略) #0 2.327 /var/lang/lib/ruby/3.2.0/mkmf.rb:490:in `try_do': The compiler failed to #0 2.327 generate an executable file. (RuntimeError) #0 2.327 You have to install development tools first. #0 2.327 #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:616:in `block in try_compile' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:565:in `with_werror' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:616:in `try_compile' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:1157:in `block in have_header' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:989:in `block in checking_for' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:354:in `block (2 levels) in postpone' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:324:in `open' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:354:in `block in postpone' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:324:in `open' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:350:in `postpone' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:988:in `checking_for' #0 2.327 from /var/lang/lib/ruby/3.2.0/mkmf.rb:1156:in `have_header' #0 2.327 from extconf.rb:10:in `system_libffi_usable?' #0 2.327 from extconf.rb:46:in `<main>' #0 2.327 #0 2.327 To see why this extension failed to compile, please check the mkmf.log which can #0 2.327 be found here: #0 2.327 #0 2.327 /var/lang/lib/ruby/gems/3.2.0/extensions/aarch64-linux/3.2.0/ffi-1.16.3/mkmf.log #0 2.327 #0 2.327 extconf failed, exit code 1 (略) #0 2.327 An error occurred while installing ffi (1.16.3), and Bundler cannot continue. #0 2.327 #0 2.327 In Gemfile: #0 2.327 ffi ------ Dockerfile:8 -------------------- 6 | COPY Gemfile ${LAMBDA_TASK_ROOT}/ 7 | 8 | >>> RUN gem install bundler && bundle install 9 | -------------------- ERROR: failed to solve: process "/bin/sh -c gem install bundler && bundle install" did not complete successfully: exit code: 5
native buildのコンパイルで失敗しておりgemをインストールできません。
必要な依存パッケージ
リポジトリのRequirementsを見るとCコンパイラと libffi
ライブラリが必要だと書いています。
加えて、そもそもmakeができていなかったので make
も必要そうでした。
lambda/rubyのbase OSはAmazon Linux 2 なのでパッケージ管理システムはyumです。 したがって、yumで下記のパッケージをインストールすればエラーを解消できそうです。
- gcc
- make
- libffi-devel
Dockerfile(改修後)
FROM public.ecr.aws/lambda/ruby:3.2 # 依存パッケージを追加する RUN yum update -y && yum install -y gcc make libffi-devel COPY Gemfile ${LAMBDA_TASK_ROOT}/ RUN gem install bundler && bundle install
無事にbundle installが成功しました。
$ docker build --platform linux/arm64 -t lambda-ruby-test:test . [+] Building 19.7s (9/9) FINISHED => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 261B 0.0s => [internal] load metadata for public.ecr.aws/lambda/ruby:3.2 0.0s => CACHED [1/4] FROM public.ecr.aws/lambda/ruby:3.2 0.0s => [internal] load build context 0.0s => => transferring context: 28B 0.0s => [2/4] RUN yum update -y && yum install -y gcc make libffi-devel 12.3s => [3/4] COPY Gemfile /var/task/ 0.0s => [4/4] RUN gem install bundler && bundle install 6.7s => exporting to image 0.7s => => exporting layers 0.6s => => writing image sha256:1234567890 0.0s => => naming to docker.io/library/lambda-ruby-test:test 0.0s