Dockerを使って任意のrubyバージョンのrpmを作成する
May 11, 2014 - docker
CentOSを使ってて不便なのがruby2系のインストール。
rbenvやruby-buildを使うかソースからインストールするのですが、この場合、環境を構築するたびにビルドすることになり時間もかかるし大変面倒です。
なのでDockerを使ってクリーンな環境でRubyの最新rpmをビルドしてみました。
Dockerを使えばビルド環境がすぐに立ち上げられるので、rpmビルドに必要なパッケージを確認したりするのに最適です。
今回のソースはgithubにpushしてあります。
環境
- ゲストOS:Vagrantで起動したUbuntu-14.04
- コンテナ:centos:6.4
ファイルの配置
以下ファイルを同一ディレクトリに入れておきます。
- Vagrantfile
- provision.sh
- Dockerfile
- rubybuild.sh
- ruby-2.0.0-p481.spec
手順
- ゲストOSの起動(Vagrant)
- ゲストOSにsshログイン
- Dockerコンテナのビルド
- Dockerコンテナ内でrpmビルド
1. ゲストOSの起動
Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.synced_folder ".", "/vagrant"
config.vm.provision "shell", path: 'provision.sh'
# お好みで
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "2", "--ioapic", "on"]
end
end
provision.sh
sudo apt-get update
sudo apt-get install -y language-pack-ja
# Docker
sudo apt-get install -y docker.io
sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
2. ゲストOSにsshログイン
$ vagrant up
$ vagrant ssh
$ cd /vagrant
3. Dockerコンテナのビルド
ビルド用specファイルを用意して、シェルスクリプトでビルドします。
すると、コンテナにマウントしたボリュームにビルド済みのrpmファイルがコピーされます。
ビルド用specシェルスクリプト
環境変数RUBY_VERSIONに”2.0.0-p481”や”2.0.0-p451”を設定すれば任意のバージョンをビルドします。
※デフォルトの2.0.0-p481以外はそれ用のspecファイルが必要になります。
rubybuild.sh
#!/bin/env bash
WORKDIR=/opt/rpmbuild
RUBY_VER=${RUBY_VER:-"2.0.0-p481"}
RUBY_MAJOUR_VER=$(echo $RUBY_VER|cut -d"-" -f1)
RUBY_MINOR_VER=$(echo $RUBY_VER|cut -d"-" -f2)
if [ -z "$RUBY_MINOR_VER" ]; then
RUBY_TARBALL="ruby-$RUBY_MAJOUR_VER.tar.gz"
else
RUBY_TARBALL="ruby-$RUBY_MAJOUR_VER-$RUBY_MINOR_VER.tar.gz"
fi
RUBY_REMOTE_FILE="http://cache.ruby-lang.org/pub/ruby/${RUBY_MAJOUR_VER:0:3}/$RUBY_TARBALL"
mkdir -p $WORKDIR/rpm/{BUILD,SRPMS,SPECS,SOURCES,RPMS}
echo "%_topdir $WORKDIR/rpm" > $WORKDIR/.rpmmacros
if [ ! -f $WORKDIR/rpm/SOURCES/$RUBY_TARBALL ]; then
wget $RUBY_REMOTE_FILE -O $WORKDIR/rpm/SOURCES/$RUBY_TARBALL
fi
cp $WORKDIR/ruby-${RUBY_VER}.spec $WORKDIR/rpm/SPECS/ruby.spec
rpmbuild -bb $WORKDIR/rpm/SPECS/ruby.spec
cp $WORKDIR/rpm/RPMS/x86_64/* /shared/
4. Dockerコンテナ内でrpmビルド
Dockerfile
FROM centos:6.4
# setup
RUN yum update -y
RUN yum install -y rpm-build gcc
# epel
RUN rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6
RUN rpm -ihv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# ruby-depends
RUN yum install —enablerepo=epel -y libyaml-devel
RUN yum install -y byacc readline-devel ncourses-devel tcl-devel openssl-devel gdbm-devel db4-devel
# build rpm
WORKDIR /opt/rpmbuild
ADD rubybuild.sh /opt/rpmbuild/rubybuild.sh
ADD ruby-2.0.0-p481.spec /opt/rpmbuild/ruby-2.0.0-p481.spec
コンテナ起動してrpmをビルド
コンテナを起動する際に、カレントディレクトリをマウントしておきます。
※--rm
オプションでrpm作成完了したらコンテナは破棄します
$ sudo docker build -t <USERNAME>/rpmbuild .
$ sudo docker run --rm -v $PWD:/shared:rw -it <CONTAINER_ID> /bin/sh ./rubybuild.sh
成功すれば、ゲストOSのカレントディレクトリにrpmができてます。
$ ls *.rpm
ruby-2.0.0p481-2.el6.x86_64.rpm
これで、rpmコマンド一発で最新のrubyをインストールできます。
rubyインストール済みコンテナを作るなら、Dockerfileに以下のように書けばruby実行環境のできあがりです。
FROM centos:6.4
# EPEL
RUN rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6
RUN rpm -ihv http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# Install ruby rpm
ADD ruby-2.0.0p481-2.el6.x86_64.rpm ruby-2.0.0p481-2.el6.x86_64.rpm
RUN yum install -y --enablerepo=epel libyaml-devel
RUN rpm -ihv ruby-2.0.0p481-2.el6.x86_64.rpm