我尝试写了一个在CentOS上构建ngx_mruby的Dockerfile

首先 (Begins with/Firstly)

我想在CentOS上尝试matsumoto-r/ngx_mruby,所以我写了一个用于构建的Dockerfile。
它可以在hnakamur/docker-ngx_mruby-centos找到,并且使用MIT许可证。

ngx_mruby的构建配置

ngx_mruby 默认会构建以下模块。

  #
  # 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进行了以下更改。

    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文档中有三种方法。因为有时候我需要在nginx中添加模块,所以本想使用第三种方法,但是mruby没有成功构建,出现了错误。所以我尝试先使用第一种方法构建mruby,然后再尝试用第三种方法构建,结果顺利完成了。

请根据需要进行修改,以下是nginx的配置。

    ./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のビルドに必要
ソースからビルド

redis/hiredis

matsumoto-r/mruby-redisが依存
ソースからビルド

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 .

启动容器

使用 Qiita 上的文章中提供的容器,通过 docker 在 lua-resty-redis 的容器与 redis 的容器之间进行通信的示例。使用以下命令启动 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文件中添加以下设置。

env REDIS_PORT_6379_TCP_ADDR;
env REDIS_PORT_6379_TCP_PORT;

/redis的位置设置如下。

        location /redis {
            mruby_content_handler /usr/local/nginx/conf/get_redis.rb;
        }
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

可以得到类似的输出。 de