6
6

More than 5 years have passed since last update.

CentOSでngx_mrubyをビルドするDockerfileを書いてみた

Last updated at Posted at 2014-04-17

はじめに

matsumoto-r/ngx_mrubyをCentOSで試そうと思い、ビルドするためのDockerfileを書いてみました。
hnakamur/docker-ngx_mruby-centosに置いてあります。MITライセンスです。

ngx_mrubyのビルド設定

ngx_mrubyではデフォルトで以下のモジュールをビルドするようになっています。

https
  #
  # Recommended for ngx_mruby
  #
  # comment out because of moving error.h
  conf.gem :git => 'git://github.com/iij/mruby-io.git'
  conf.gem :git => 'git://github.com/iij/mruby-process.git'
  conf.gem :git => 'git://github.com/iij/mruby-pack.git'
  conf.gem :git => 'git://github.com/iij/mruby-digest.git'
  conf.gem :git => 'git://github.com/mattn/mruby-json.git'
  conf.gem :git => 'git://github.com/matsumoto-r/mruby-redis.git'
  conf.gem :git => 'git://github.com/matsumoto-r/mruby-vedis.git'
  conf.gem :git => 'git://github.com/matsumoto-r/mruby-memcached.git'
  conf.gem :git => 'git://github.com/matsumoto-r/mruby-sleep.git'
  conf.gem :git => 'git://github.com/matsumoto-r/mruby-userdata.git'
  conf.gem :git => 'git://github.com/mattn/mruby-onig-regexp.git'

  # ngx_mruby extended class
  conf.gem :git => 'git://github.com/matsumoto-r/mruby-ngx-mruby-ext.git'

私の書いたDockerfileではbuild_config.rbを以下のように変更しています。

https
    sed -i.orig "s|conf.gem :git => 'git://github.com/matsumoto-r/mruby-memcached.git'|#&|;/^  conf.gem :git => 'git:\/\/github.com\/mattn\/mruby-onig-regexp.git'/a\
\  conf.gem :git => 'git://github.com/iij/mruby-env.git'" \
      build_config.rb && \
  • mruby-memcachedはビルド対象から外す
    • matsumoto-r/mruby-memcachedはlibmemcachedのソースをビルドして参照するようにしてみたんですが、mruby-memcachedがコンパイルエラーになってしまいました。とりあえず私は使う予定がなかったので外すことにしました。
  • mruby-envを追加
    • mrubyのスクリプト内で環境変数を参照したかったのでiij/mruby-envを追加しました。

nginxのビルド

matsumoto-r/ngx_mrubyのBuildのドキュメントには3通りの方法が書かれています。nginxにモジュールを追加したい場合もあるので、3番めの方法にしたかったのですが、mrubyがビルドされずエラーになってしまったので、1番めの方法でmrubyをビルドしておいてから、3番めの方法でビルドするようにしてみたら、うまく行きました。

nginxのconfigureは以下のようにしています。適宜変更してご利用ください。

https
    ./configure --prefix=/usr/local/nginx \
      --user=nginx \
      --group=nginx \
      --with-file-aio \
      --with-ipv6 \
      --with-http_ssl_module \
      --with-http_realip_module \
      --with-http_addition_module \
      --with-http_xslt_module \
      --with-http_image_filter_module \
      --with-http_geoip_module \
      --with-http_sub_module \
      --with-http_dav_module \
      --with-http_flv_module \
      --with-http_mp4_module \
      --with-http_gzip_static_module \
      --with-http_random_index_module \
      --with-http_secure_link_module \
      --with-http_degradation_module \
      --with-http_stub_status_module \
      --with-md5-asm \
      --with-sha1-asm \
      --with-pcre-jit --with-pcre=/usr/local/src/pcre-8.35 \
      --with-cc-opt='-O2 -g' \
      --add-module=/usr/local/src/ngx_mruby \
      --add-module=/usr/local/src/ngx_mruby/dependence/ngx_devel_kit && \

mrubyとnginxが依存しているもののビルドまたはインストール

  • ruby
    • mrubyのビルドに必要。2.1.1をソースからビルド
  • Redis
  • redis/hiredis
  • PCRE - Perl Compatible Regular Expressions
    • JITを使いたい(nginxのconfigureの--with-pcre-jitオプション)ので最新版8.35をソースからビルド
  • GeoIP
    • これは依存しているというわけではなく、nginxにGeoIPモジュールを組み込んで(nginxのconfigureの--with-http_geoip_moduleオプション)ビルドしたかったので利用。
    • epelからインストール
    • ソースからビルドする場合はHow to install Nginx GeoIP moduleが参考になりそうです(試してないです)。

Dockerイメージのビルド

Dockerfileのあるディレクトリで以下のコマンドを実行します。

docker build -t hnakamur/ngx_mruby .

コンテナの起動

redisはdockerでlua-resty-redisのコンテナからredisのコンテナに通信するサンプル - Qiitaの記事で作ったコンテナを利用します。以下のコマンドでredisのコンテナを起動します。

docker run -d -p 6379:6379 -name redis hnakamur/redis

以下のコマンドでngx_mrubyのコンテナを起動します。

docker run -d -p 80:80 -link redis:redis hnakamur/ngx_mruby

ngx_mrubyからredisにアクセスするサンプル

まずDockerによって環境変数を参照するためにnginx.confに以下の設定を入れています。

https
env REDIS_PORT_6379_TCP_ADDR;
env REDIS_PORT_6379_TCP_PORT;

/redisのlocation設定は以下のようにしています。

https
        location /redis {
            mruby_content_handler /usr/local/nginx/conf/get_redis.rb;
        }
https
host = ENV["REDIS_PORT_6379_TCP_ADDR"]
port = ENV["REDIS_PORT_6379_TCP_PORT"].to_i
db = Redis.new host, port

# Note: a value must be String
# > db.set "key1", 100
# (mirb):1: expected String (TypeError)

db.set "key1", "100"

value = db.get "key1"

r = Nginx::Request.new
r.content_type = "text/html"
Nginx.rputs "host = #{host}, port = #{port}, value is #{value}\n"

私の環境ではdockerでlua-resty-redisのコンテナからredisのコンテナに通信するサンプル - Qiitaに書いたように8080→80のポートフォワーディングを設定していますので、OSXで

curl http://localhost:8080/redis

でアクセスすると

host = 172.17.0.2, port = 6379, value is 100

といった出力が得られます。

6
6
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
6
6