LoginSignup
0
1

More than 3 years have passed since last update.

Alpineベースのimageにruby2.2.3を入れる

Last updated at Posted at 2020-01-23

本当はalpine-rubyをベースにするべきなんだろうけど諸事情でJava系のベースにする必要があったので、rbenvを自力で入れて構築することにしました。

出来上がったDockerfileはこちら。

FROM openjdk:8-jdk-alpine

RUN apk update && \
    apk upgrade && \
    apk add --update --no-cache \
    bash \
    vim \
    curl \
    tzdata \
    openssl-dev=1.0.2u-r0

RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.8/main" >> /etc/apk/repositories
RUN apk update && \
    apk upgrade && \
    apk add --update --no-cache --virtual=.build-dependencies \
    build-base \
    git \
    gcc \
    readline-dev \
    zlib-dev \
    libffi-dev

ENV PATH /usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH
ENV RBENV_ROOT /usr/local/rbenv
ENV CONFIGURE_OPTS "--disable-install-doc"

RUN git clone https://github.com/sstephenson/rbenv.git ${RBENV_ROOT} && \
    git clone https://github.com/sstephenson/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \
    ${RBENV_ROOT}/plugins/ruby-build/install.sh
RUN echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> /etc/profile.d/rbenv.sh && \
    echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh

RUN rbenv install 2.2.3 && \
    rbenv global 2.2.3

COPY Gemfile .
COPY Gemfile.lock .

RUN gem install -N bundler -v 1.16.2
RUN bundle install -j4 && \
    rm -rf /usr/local/bundle/cache/*.gem

RUN apk del .build-dependencies

大きな障害はは以下のようにopensslの1.0を取得することでした。

v3.8から1.0系のopensslを取得する

素直にapk add opensslでライブラリを入れるとrbenv install時に以下のようなエラーが発生する。

BUILD FAILED (Alpine Linux 3.9.4 using ruby-build 20200115-8-g73b926b)

Inspect or clean up the working tree at /tmp/ruby-build.20200123165940.26.gjbJCo
Results logged to /tmp/ruby-build.20200123165940.26.log

Last 10 log lines:
                              power_assert-0.2.2.gem
                              minitest-5.4.3.gem
installing rdoc:              /usr/local/rbenv/versions/2.2.3/share/ri/2.2.0/system
installing capi-docs:         /usr/local/rbenv/versions/2.2.3/share/doc/ruby
The Ruby openssl extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Configure options used:
  --prefix=/usr/local/rbenv/versions/2.2.3
  LDFLAGS=-L/usr/local/rbenv/versions/2.2.3/lib 
  CPPFLAGS=-I/usr/local/rbenv/versions/2.2.3/include 

エラーの原因としては、ruby2.4以下の場合はopenssl1.1系に対応していないため、openssl1.0を入れる必要があるからでした。
rbenv/ruby-build

The openssl extension of Ruby version before 2.4 is not compatible with OpenSSL 1.1.x.

ubuntuベースのimageで構築するならこちらの記事で言及されているように有志が開発したパッチを当てれば動きますが、alpineの場合は自力で1.0系を入れる必要があります。

現在openjdk:8-jdk-alpineではデフォルトでv3.9のリポジトリを参照しているが、v3.9ではopensslは1.1系の提供になっています。
こちらで調べると1.0系の取得には1つ前のv3.8のリポジトリから取得が必要のようです。
https://pkgs.alpinelinux.org/packages?name=openssl&branch=v3.8&repo=main

そこでapkから取得する前に参照先にv3.8のリポジトリを追加して上げる必要があります。

RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.8/main" >> /etc/apk/repositories

追加後にopenssl-dev=1.0.2u-r0とバージョンを指定することで1.0系のopensslを取得することができます。

また当初はgem install時にThe Ruby openssl extension was not compiled. Missing the OpenSSL lib?エラーが発生していたが、修正前のDockerfikeでlibssl1.0を入れていたことが原因でした。
おそらくssl系のライブラリ同士でバッティングしていたっぽい?

rbenvの前はruby-installを使用して軽量化を図っていましたが、上と同じOpenSSLのエラーがどうしても解消できなかったので諦めることに…
ruby-installで上手く行けば多分もう少し軽くできそう。

RUN wget -O - https://github.com/postmodern/ruby-install/archive/v0.7.0.tar.gz | tar xzvf - && \
    ( cd ruby-install-0.7.0 && \
      make install ) && \
    rm -rf ruby-install-*
RUN ruby-install --system --cleanup ruby 2.2.3

その他細かいポイントなど

docker軽量化系の記事では散々言及されているようなことですが、軽くまとめると
- ビルドに必要のないパッケージは残したくないので.build-dependenciesでまとめて最後の行で一括で削除しています。
- ENV CONFIGURE_OPTS "--disable-install-doc"を指定することで不要なドキュメントをインストールしないようにしています
- bundle install時にrm -rf /usr/local/bundle/cache/*.gemでgemのキャッシュを消すようにしています

今どき2.2.3を使うことはあまりないと思いますが、備忘録として残しておこうと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1