Posted at

Alpine Linux ベースで ngx_mruby の Docker イメージを構築

More than 3 years have passed since last update.

Alpine Linux で Docker イメージを劇的に小さくする」で、Alpine Linux ペースでの Docker イメージについて紹介しました。今回は、ngx_mruby を Alpine Linux ベースで、Docker イメージを構築する例を紹介します。

作成にあたっては、matsumoto-r/ngx_mrubyDockerfile と、Docker オフィシャルの Nginx の Dockerfile を参考にしました。


Dockerfile

ズバリ! Dockerfile は、このように書きました。以下で公開しています。

FROM alpine:3.3

ENV NGINX_CONFIG_OPT_ENV --with-http_stub_status_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--prefix=/usr/share/nginx \
--sbin-path=/usr/local/sbin/nginx \
--conf-path=/etc/nginx/conf/nginx.conf \
--pid-path=/var/run/nginx.pid \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log

RUN apk add --update openssl-dev pcre-dev git \
&& apk add --virtual build-dependencies build-base ruby-dev ruby-rake tar wget bison perl \
&& git clone https://github.com/matsumoto-r/ngx_mruby.git \
&& cd ngx_mruby \
&& sh build.sh \
&& make install \
&& cd / \
&& apk del build-dependencies \
&& rm -rf \
ngx_mruby \
/var/cache/apk/*

RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log

EXPOSE 80 443

ONBUILD ADD ngx-mruby/hook /usr/share/nginx/hook
ONBUILD ADD ngx-mruby/conf /etc/nginx/conf

CMD ["nginx", "-g", "daemon off;"]

この Dockerfile を使って作成した Docker イメージのサイズは、docker images コマンド調べで、49.27MB となりました!

$ docker images asakaguchi/ngx-mruby

REPOSITORY TAG IMAGE ID CREATED SIZE
asakaguchi/ngx-mruby latest 06187dc37c4b 5 hours ago 49.27 MB

参考までに、サイズを公式の Docker イメージと比較すると . . .、ナント! 1/10 以下になりました!Alpine Linux と ngx_mruby の組み合わせは、最強かもしれませんね!

$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
asakaguchi/ngx-mruby latest 06187dc37c4b 5 hours ago 49.27 MB
matsumotory/ngx-mruby latest 31526196d1b1 17 hours ago 582.2 MB


Dockerfile の簡単な解説

以下、簡単ですが、Dockerfile の中身を解説しておきます。


Nginx の configure オプション

Nginx の configure オプションは、次のように定義してみました。主な変更点は、prefix と path 周りです。

ENV NGINX_CONFIG_OPT_ENV --with-http_stub_status_module \

--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--prefix=/usr/share/nginx \
--sbin-path=/usr/local/sbin/nginx \
--conf-path=/etc/nginx/conf/nginx.conf \
--pid-path=/var/run/nginx.pid \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log


ログ

ログ出力の部分は、Docker オフィシャルの Nginx の Dockerfile の記述を参考に追加しました。

アクセスログ(access.log)とエラーログ(error.log)は、それぞれ標準出力(stdout)と標準エラー出力(stderr)から取れるようにしています。

RUN ln -sf /dev/stdout /var/log/nginx/access.log

RUN ln -sf /dev/stderr /var/log/nginx/error.log

と、これを書いていて気づきましたが、元ネタは && を使って 1 行で処理していたのですが、なぜか 2 行に変えてしまっていました。これには、他意はないです。無意識に変えてしまっていました . . . 。思い切って、ngx_mruby を構築している RUN 中にまとめてしまっても良いと思います。


ONBUILD

ONBUILD 部分も configure オプションで変更したパスに合わせて変えています。docker/hookdocker/confngx-mruby/hookngx-mruby/conf に変えたのは、完全に好みの問題です。

ONBUILD ADD ngx-mruby/hook /usr/share/nginx/hook

ONBUILD ADD ngx-mruby/conf /etc/nginx/conf


CMD

CMD の記述は、Docker オフィシャルの Nginx の DockerfileCMD を採用しました。これも好みの問題です。

CMD ["nginx", "-g", "daemon off;"]

これは、Nginx を -g daemon off; オプションを使って、foreground で動かしています。よって、この方法を採用する場合は、nginx.conf で、daemon off; と記述しないように注意してください。nginx.conf で、daemon off; と記述したい場合は、CMD ["nginx"] としてください。


使用例

この Dockerfile は、以下のように使います。

まずは、Docker イメージを作成します。

mkdir learning-ngx-mruby && cd learning-ngx-mruby

vim Dockerfile # テキストエディタで、冒頭で紹介した Dockerfile の内容をコピー&ペースト
docker build -t ngx-mruby .

続いて、作成した Docker イメージを使って、コンテナを起動します。

echo 'hello, world' > index.html

docker run -d -p 8080:80 -v $(pwd):/usr/share/nginx/html ngx-mruby
curl http://$(docker-machine ip default):8080

hello, world のメッセージが表示されたら OK です。最後の curl コマンドの実行は、OS X(Docker Toolbox 環境1)での例です。Linux の場合は、curl http://localhost:8080 で良いかと思います。





  1. Docker Toolbox を標準的にインストールした場合を想定しています。docker-machine ip defaultdefault の部分は、環境によっては異なる可能性があります。docker-machine ls で対象となる仮想マシンの NAME を確認してください。