検証などで Stub 的にちょっと JSON の固定レスポンスを返したりするために Nginx のコンテナを利用するシーンが多々あるのですが、ただ JSON を返すだけでは一瞬で返ってしまい、レスポンスタイムなどが現実的でなかったりします。そこで、Nginx で sleep のようなものが設定できるモジュールを公式のコンテナイメージに動的モジュールとして利用できるようにしたので tips としてメモっておきます。
sleep のようなものが設定できる Nginx モジュール
あまりじっくり探す時間もなかったので Qiita の記事 をそのまま参考にさせていただきました。以下の 2つがあるようです。
- echo-nginx-module : https://github.com/openresty/echo-nginx-module
- lua-nginx-module : https://github.com/openresty/lua-nginx-module
いろいろ検索した範囲では lua-nginx-module の方が情報が多かったですが、ぱっと見分かりやすそうだった echo-nginx-module の方を使ってみることにしました。
Nginx 公式イメージに動的モジュールとして追加する
まずはモジュールを公式イメージの環境に合わせてコンパイルする必要があるので以下のような手順でイメージをビルドしていきます。
- 公式イメージで multi-stage build
- 公式イメージの Nginx と同じバージョンのソースコードをダウンロード
- echo-nginx-module のソースもダウンロード
--add-dynamic-module
オプションで echo-nginx-module を追加して Nginx をmake modules
- 作成されたモジュールを最終的なイメージにコピー
Dockerfile
|
|
- 13行目 : モジュールの
./configure
時には公式イメージで指定されたオプションと同じものを指定する必要があります。そのオプションはnginx -V
で出力できるので、引っ張り出して変数に入れてあげます - 14行目 : Dynamic Module として扱うので
--add-dynamic-module=....
で指定します - 15行目 :
make modules
とすることでモジュールのコンパイルだけできます
./configure
時に公式イメージで指定されたオプションと同じものを指定しなくてもコンパイルはできてしまいます。が、Nginx の起動時に以下のようなエラーが出てしまいます。
2022/12/26 10:19:25 [emerg] 7#7: module "/etc/nginx/modules/ngx_http_echo_module.so" is not binary compatible in /etc/nginx/nginx.conf:1
nginx: [emerg] module "/etc/nginx/modules/ngx_http_echo_module.so" is not binary compatible in /etc/nginx/nginx.conf:1
(おまけ)echo-nginx-module の使い方
使いこなせないぐらい多機能なので…詳しくはドキュメントを参照いただくとして、簡単な使い方だけご紹介(主要部分の抜粋です)。
load_module /etc/nginx/modules/ngx_http_echo_module.so;
http {
server {
location /api/something {
echo_sleep 1.5; # Non-blocking
echo_exec /200.json;
}
location /ok {
echo_blocking_sleep 2; # Blocking
echo "ok";
}
}
}
/api/something
にアクセスがあったら 1.5秒待って/200.json
ファイルの内容を返します/ok
にアクセスがあったら 2秒待って “ok” が返ります。blocking
指定しているのでワーカープロセスがブロックされます(本番環境では使わないように、とのこと)
まとめ
Nginx の公式コンテナイメージで動的モジュールを使う方法をやってみました。以下がポイントになるでしょうか。多分他のモジュールでも同様にできるのではないかと思います。
- Docker Multi-stage Build を活用する
- 公式イメージで指定した configure オプションと同じものを指定する
最後に・・・
この投稿は個人的なものであり、所属組織を代表するものではありません。ご了承ください。