/ ,' 3

https://twitter.com/gorlemkun

Docker HubのRuby公式イメージを深掘る

 

gorlem.hatenablog.com

 

環境構築シリーズ続き。

前回色々調べた&調べ方が分かったことによりDocker Hubに置かれている色々なイメージがどんなもんかざっくりとわかるようになっているはず。

https://hub.docker.com/

自分でDocker上に構築していく道も考えたが、まずは先人のやり方をみていくことにした。

Rubyの公式イメージ

https://hub.docker.com/_/ruby/

ruby:<version>

This is the defacto image. If you are unsure about what your needs are, you probably want to use this one. It is designed to be used both as a throw away container (mount your source code and start the container to start your app), as well as the base to build other images off of. This tag is based off of buildpack-depsbuildpack-deps is designed for the average user of docker who has many images on their system. It, by design, has a large number of extremely common Debian packages. This reduces the number of packages that images that derive from it need to install, thus reducing the overall size of all images on your system. 

ruby:2.4 などのバージョン番号以外何も付かない単純なバージョン指定で落とせるイメージがDocker Hub上のデファクトで、まあ大体どんな用途でも最適化しようと思わなければこれで行けるよ、という意味なのだと理解した。またDebianが使われているっぽい。

 

公式イメージページにあるタグのリストから単純なバージョン指定で引いてこれるイメージを探すと・・・

このjessie?という名前のついたものが基本的なイメージらしい。

github.com

jessieの内容について深掘りするには、上記イメージ内の一番上の行に

FROM buildpack-deps:jessie

 とあるので、buildpack-depsのリポジトリを深掘りすると良さそうで、

https://hub.docker.com/_/buildpack-deps/

ここを見ると

とあり、一番下のがjessieで、ruby:2.4のイメージの元はjessie↓、

https://github.com/docker-library/buildpack-deps/blob/d7da72aaf3bb93fecf5fcb7c6ff154cb0c55d1d1/jessie/Dockerfile

 

そしてjessieのイメージの元はjessie-scm↓、

https://github.com/docker-library/buildpack-deps/blob/1845b3f918f69b4c97912b0d4d68a5658458e84f/jessie/scm/Dockerfile

 

さらにjessie-scmのイメージの元はjessie-cur↓lで、

https://github.com/docker-library/buildpack-deps/blob/d662dc69f910feb241f6d0c9d2cd6cc2fb6c5e6c/jessie/curl/Dockerfile

 

jessie-curlのイメージの元はdebian:jessie↓(ここでリポジトリが変わる)

https://hub.docker.com/_/debian/

https://github.com/debuerreotype/docker-debian-artifacts/blob/6af0f6159c515601731d92972a245199337e3ca6/jessie/Dockerfile

 

そしてdebian:jessieはというと、scratchからなので、やっとここでスタートとなる空ファイルに到達できる。(Docker Hubがscratchリポジトリという空のレポジトリを定義している。https://hub.docker.com/_/scratch/

そしてDocker Hubのdebianリポジトリの説明を見ると、

Stable releases are also tagged with their version (iedebian:8 is an alias for debian:jessie

とあるので、どうやらdebianの正式バージョンの8個目のものを指しているらしい。そしてdebian:jessieのDockerfileの中にある

ADD rootfs.tar.xz /

というのはdebian8のイメージを解凍して空のコンテナ上に置くことをしているはず。

・・・とrubyのDockerfileを調べる前に、そもそものFROMで指定しているベースイメージに何が入っているのか一通りざっくり調べてみると、

 

jessie-curl

ここまではapt-getに頼らずアプリインストールするための最低限の構成。

  • ca-certificate(証明書そのものを扱う)
  • curl(色んなプロトコルでデータ送受信)
  • wget(ファイルのダウンロード)
  • gnupg(ファイル暗号化)
  • dirmngr(証明書もろもろ管理サービス)
 
jessie-scm

ここまではおそらく外部リポジトリを扱えるようにするための構成。

  • bzr(バージョン管理)
  • git(バージョン管理)
  • mercurial(バージョン管理)
  • openssh-client(SSHリモートホストに接続)
  • procps(プロセス管理。psでプロセス監視したりプロセスkillしたりするやつ)
 
jessie

うーなんかいっぱいある。

まとめるとおそらく、外部からソースを落としてきてコンパイルして使えるようにするための構成だと思われる。

lib***系はLinuxでよく使われる共有ライブラリ群。たぶん。

autoconf, automake, makeあたりはCのコードをバイナリにコンパイルするのに使う。

  • autoconf \ automake \ bzip2 \ dpkg-dev \ file \ g++ \ gcc \ imagemagick \ libbz2-dev \ libc6-dev \ libcurl4-openssl-dev \ libdb-dev \ libevent-dev \ libffi-dev \ libgdbm-dev \ libgeoip-dev \ libglib2.0-dev \ libjpeg-dev \ libkrb5-dev \ liblzma-dev \ libmagickcore-dev \ libmagickwand-dev \ libncurses5-dev \ libncursesw5-dev \ libpng-dev \ libpq-dev \ libreadline-dev \ libsqlite3-dev \ libssl-dev \ libtool \ libwebp-dev \ libxml2-dev \ libxslt-dev \ libyaml-dev \ make \ patch \ xz-utils \ zlib1g-dev \
 
ruby

やっとたどり着いたrubyのイメージなんだが、見てみるとrubyのインストールしかしていない。

ただ、そのインストール方法がなかなか複雑・・・にみえる。ざっくり見た感じ、は

  • Rubyのバイナリが入った圧縮ファイルを落としてくる
wget -O ruby.tar.xz "https://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOR%-rc}/ruby-$RUBY_VERSION.tar.xz"
  • 解凍する
tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1
  • コンパイルする
  • autoconf(コンパイル設定生成) -> ./configure(実際に設定) -> make(ビルド) -> make install(ビルドしたやつのインストール) の流れはよくあるやつ。
autoconf
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"
./configure --build="$gnuArch" --disable-install-doc --enable-shared
make -j "$(nproc)"
make install

rubyの公式にもこの方法は一応ちょっと触れられている。

Building from Source

Of course, you can install Ruby from source. Download and unpack a tarball, then just do this:

$ ./configure
$ make
$ sudo make install

By default, this will install Ruby into /usr/local. To change, pass the --prefix=DIR option to the ./configure script.

Installing Ruby

  • bundlerをインストールする
gem install bundler --version "$BUNDLER_VERSION" --force
  • 色々環境変数設定する
  • GEM_HOME: Gemのホームディレクト
  • BUNDLE_PATH: BundlerがGemを入れるディレクト
  • それ以外は正直よくわかりませんでした・・・まあよしなに設定してくれているということで。
ENV GEM_HOME /usr/local/bundle
ENV BUNDLE_PATH="$GEM_HOME" BUNDLE_BIN="$GEM_HOME/bin" BUNDLE_SILENCE_ROOT_WARNING=1 BUNDLE_APP_CONFIG="$GEM_HOME"
ENV PATH $BUNDLE_BIN:$PATH

環境変数まわりはこの辺にもっとほかのやつが書いてある。

docs.ruby-lang.org

Bundler: bundle config

 

と、こういう手順。

 

・・・rubyのインストールよりもそれ以外が膨れ上がってしまった感があるが、

  • 根本のベースイメージにDebianが使われていたり
  • 基本的なソフトがrubyインストール前段階でいくつか入れられていたり
  • rubyがソースコードからインストールされていたり
  • gemまわりの環境変数が事前に設定されていたり

することを把握しておくと、今後のデバッグであまり困らない気がする。

 

はー。やっと終わった。やはり疲れる。1週間くらい記事を書くのにかかった。ただ、環境構築つらい問題は少しずつ解消されてきている気がする。しかしまだまだこれではアプリが書けないので、もう少しやっていこう。