概要
タイトルの通りです。Dockerのruby:2.3.8イメージでruggedをインストールしようとした際に発生したcmake時のエラーと対処について記録します。
事象と対応
私は以下のようにgitlab-ci.ymlを設定してGitLabのジョブを実行していました。単にrailsのアプリをインストールしてテストを実行しようとしているだけの設定です。
image: ruby:2.3.8
before_script:
- apt-get install -y --no-install-recommends cmake
- bundle install --path vendor/bundle
test:
script:
- bundle exec rake spec
前述の通りruggedをインストールするため、依存パッケージのcmakeも前もってインストールしています。
いざ実行してみるとジョブが成功しません。エラーログはこのような感じです。
current directory:
/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/gems/rugged-0.27.7/ext/rugged
/usr/local/bin/ruby -I /usr/local/lib/ruby/site_ruby/2.3.0 -r
./siteconf20190125-288-nqejbk.rb extconf.rb
checking for gmake... no
checking for make... yes
checking for cmake... yes
checking for pkg-config... yes
-- cmake .. -DBUILD_CLAR=OFF -DTHREADSAFE=ON -DBUILD_SHARED_LIBS=OFF
-DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/usr/local/bin/$(RUBY_BASE_NAME)
--with-sha1dc
--without-sha1dc
--use-system-libraries
extconf.rb:21:in `sys': ERROR: 'cmake .. -DBUILD_CLAR=OFF -DTHREADSAFE=ON
-DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo
' failed (RuntimeError)
from extconf.rb:83:in `block (2 levels) in <main>'
from extconf.rb:80:in `chdir'
from extconf.rb:80:in `block in <main>'
from extconf.rb:77:in `chdir'
from extconf.rb:77:in `<main>'
To see why this extension failed to compile, please check the mkmf.log which can
be found here:
/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/extensions/x86_64-linux/2.3.0/rugged-0.27.7/mkmf.log
extconf failed, exit code 1
Gem files will remain installed in
/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/gems/rugged-0.27.7
for inspection.
Results logged to
/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/extensions/x86_64-linux/2.3.0/rugged-0.27.7/gem_make.out
An error occurred while installing rugged (0.27.7), and Bundler cannot continue.
Make sure that `gem install rugged -v '0.27.7' --source 'https://rubygems.org/'`
succeeds before bundling.
In Gemfile:
rugged
言われたとおり、/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/extensions/x86_64-linux/2.3.0/rugged-0.27.7/mkmf.logを見るために、ログを入れた上で再度実行してみると以下のようなログがでました。
Running after script...
$ cat /builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/extensions/x86_64-linux/2.3.0/rugged-0.27.7/mkmf.log
find_executable: checking for gmake... -------------------- no
--------------------
find_executable: checking for make... -------------------- yes
--------------------
find_executable: checking for cmake... -------------------- yes
--------------------
find_executable: checking for pkg-config... -------------------- yes
--------------------
"cmake .. -DBUILD_CLAR=OFF -DTHREADSAFE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo "
-- The C compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
... 省略
-- Looking for qsort_s - not found
-- Looking for clock_gettime in rt
-- Looking for clock_gettime in rt - found
-- Checking for module 'libcurl'
-- Found libcurl, version 7.52.1
-- Resolved libraries: /usr/lib/x86_64-linux-gnu/libcurl.so
-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIR)
CMake Error at src/CMakeLists.txt:157 (MESSAGE):
Unable to autodetect a usable HTTPS backend.Please pass the backend name
explicitly (-DUSE_HTTPS=backend)
-- Configuring incomplete, errors occurred!
See also "/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/gems/rugged-0.27.7/vendor/libgit2/build/CMakeFiles/CMakeOutput.log".
See also "/builds/myname-anonymous/rails-4.2.11-ruby-2.3.8/vendor/bundle/ruby/2.3.0/gems/rugged-0.27.7/vendor/libgit2/build/CMakeFiles/CMakeError.log".
ERROR: Job failed: exit code 1
Could NOT find OpenSSL とあります。どうやらOpenSSLがないらしいです。いろいろ調べるとlibssl-devパッケージをインストールする必要があったらしいため、gitlab-ci.ymlのbefore_scriptにインストール処理を書いて実行したらうまくいきました。
原因分析
ruby:2.2.4のイメージを使用していたときはこのようなことが起こらなかったたため、なぜ2.3.8だと起こるのかが気になったので原因を調べました。
イメージ単位で結果が異なったので原因はDockerのrubyイメージの内容の違いだと思いました。残念ながら2.2.4のイメージはDockerfileが簡単には見つけられそうになかったため2.3.8のDockerfileから見始めました。気になる部分がありました。既にlibssl1.0-devがインストールされているようです。しかもその上には# ruby 2.3 on stretch can only support libssl1.0-dev (libssl dev from buildpack-deps is 1.1.x)という記述があります。どうやら2.3のバージョンはlibssl1.0-devしかサポートしていないので、親イメージのlibssl-devの代わりとしてインストールしているようです。じゃあ親イメージのbuildpack-deps:stretchにはlibssl-devがインストールされてるんだなと思い調べるとされてました。
そうなってくるとなんでわざわざこちら側でもlibssh-devをインストールしなきゃいけないのかと思い両方のDockerfileを眺めていたら、怪しい部分を発見しました。ruby:2.3.8のイメージはこの行でrubyのインストールに使用したlibssl1.0-devをアンインストールしているらしいです。まあでもlibssl1.0-devの方だしlibssl-devの方はアンインストールされてないんじゃないかなと思ったらそうではありませんでした。gitlab-ci.ymlにいろいろログを出力させて、libssl1.0-devのインストール時にlibssl-devが消えることがわかりました。つまりは
-
buildpack-deps:stretchイメージでlibssl-devがインストールされる -
ruby:2.3.8イメージでlibssl1.0-devがインストールされる。また、libssl-devが消える。 -
ruby:2.3.8イメージでrubyインストール後にlibssl1.0-devがアンインストールされる。 - 結果、libssl系は全部消える。
ということですね。そのためにこちら側でlibssl-devをインストールする必要があったということです。
感想
個人的にはruby:2.3.8でrubyのインストール後に再度libssl-devをインストールしてほしいなとは思いましたが、親イメージのことを考慮するのは変だとか別の事情があるかもしれないとかだと思うのでまあDockerイメージの継承は難しいなと思いました。(雑