すいませんでした...
24日に登録したつもりでいました。この記事は mod_mruby・ngx_mruby Advent Calendar 2014 23日 の記事となります...
気を取り直して。
Dockerでビルド君を作ろう
クリスマスなのでmod_mrubyをDockerでビルドします。ただビルドするだけでなく、バイナリを吐き出してみましょう。
公式をもとにこういうDockerfileを作る。
FROM ubuntu:trusty
MAINTAINER Uchio KONDO <udzura@udzura.jp>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -y update
RUN apt-get -y install \
sudo git curl bison \
apache2 apache2-dev apache2-utils \
ruby2.0 ruby2.0-dev rake \
libcurl4-openssl-dev libhiredis-dev libmarkdown2-dev libcap-dev libcgroup-dev
WORKDIR /usr/local/src/
RUN git clone https://github.com/matsumoto-r/mod_mruby.git
WORKDIR /usr/local/src/mod_mruby
RUN git submodule init
RUN git submodule update
ADD run-all.sh /usr/local/bin/run-all.sh
RUN chmod a+x /usr/local/bin/run-all.sh
ENTRYPOINT ["/usr/local/bin/run-all.sh"]
CMD ["build"]
run-all.sh
はこんな感じで。
#!/bin/bash
set -x
set -e
if [ "$1" = "check" ]; then
check=true
fi
sh build.sh 1>&2
make install 1>&2
if [ -z "$check" ]; then
cat /usr/local/src/mod_mruby/src/.libs/mod_mruby.so
else
file /usr/local/src/mod_mruby/src/.libs/mod_mruby.so
ls -l /usr/local/src/mod_mruby/src/.libs/mod_mruby.so
fi
あとは
$ docker build -t udzura/mod_mruby-builder base/
$ docker run --rm udzura/mod_mruby-builder > out/mod_mruby.so
$ file out/mod_mruby.so
out/mod_mruby.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
これを64bit Ubuntuに突っ込めば動きます。便利!!!!(apt-get -y install libhiredis0.10
はあらかじめ必要です)。
ONBUILD
で build_config.rb
をカスタマイズする
ここまでなら、同じようなことを @hfm さんがやっていらっしゃる。
もうすこしDockerらしくするために ONBUILD
で build_config.rb
をカスタマイズするの術を使ってみます。
diff --git a/base/Dockerfile b/base/Dockerfile
index 36624ec..0145f7f 100644
--- a/base/Dockerfile
+++ b/base/Dockerfile
@@ -19,5 +19,7 @@ RUN git submodule update
ADD run-all.sh /usr/local/bin/run-all.sh
RUN chmod a+x /usr/local/bin/run-all.sh
+ONBUILD ADD build_config.rb /usr/local/src/mod_mruby/build_config.rb
+
ENTRYPOINT ["/usr/local/bin/run-all.sh"]
CMD ["build"]
onbuildを利用するためのDockerfileを別途用意...シンプル...
FROM udzura/mod_mruby-builder
MAINTAINER Uchio KONDO <udzura@udzura.jp>
以下の build_config.rb
を同じディレクトリに用意する。
MRuby::Build.new do |conf|
toolchain :gcc
conf.gembox 'full-core'
conf.gem :github => 'iij/mruby-io'
conf.gem :github => 'iij/mruby-env'
conf.gem :github => 'iij/mruby-dir'
conf.gem :github => 'iij/mruby-digest'
conf.gem :github => 'iij/mruby-process'
conf.gem :github => 'iij/mruby-pack'
conf.gem :github => 'mattn/mruby-json'
conf.gem :github => 'mattn/mruby-onig-regexp'
conf.gem :github => 'matsumoto-r/mruby-redis'
conf.gem :github => 'matsumoto-r/mruby-vedis'
conf.gem :github => 'matsumoto-r/mruby-sleep'
conf.gem :github => 'matsumoto-r/mruby-userdata'
conf.gem :github => 'matsumoto-r/mruby-uname'
conf.gem '../mrbgems/mod_mruby_mrblib'
# これを追加
conf.gem :github => 'matsumoto-r/mruby-discount'
conf.cc do |cc|
if ENV['BUILD_TYPE'] == "debug"
cc.flags << '-fPIC -g3 -Wall -Werror-implicit-function-declaration'
else
cc.flags << '-fPIC'
end
if ENV['BUILD_BIT'] == "64"
cc.flags << ' -DMRB_INT64'
end
end
conf.linker do |linker|
if ENV['BUILD_BIT'] == "64"
linker.flags = '-DMRB_INT64'
end
end
end
カスタムビルドしてみます。
$ docker build -t udzura/mod_mruby-builder base/
$ docker build -t udzura/mod_mruby-done onbuild/
$ docker run --rm udzura/mod_mruby-done > out/mod_mruby.so
この mod_mruby.so
を同様にコピーし、 libmarkdown2 をインストールしてから
にあるようなmrubyスクリプトを動かすと:
動いた〜
まとめ
と言うことで、こんな感じで僕だけの最強の mod_mruby.so
バイナリを作ることができるDocker imageが出来上がりました。
mrubyは基本的にすべてのmrbgemsをスタティックリンクするので、新たなgemを利用するにあたってコンパイルのし直しが必要になります。ですが、こう言う簡単一発ビルド君を作っておくと何かと便利ではないかと思います(こう言うバイナリを作成できることは、逆にmrbgemsがスタティックリンクされることのメリットの一つと言えるでしょう)。
なお、同じようなことを ngx_mruby でもできると思います。
最後に、今回の手順がすぐに試せるプロジェクトを GitHub に置きました。
本当の24日は @cubicdaiya さんでした。
明日(25日)は @matsumotory さんによる最後の記事となります!