Nginxでレスポンスをロギングするまでが大変だった


色々あってレスポンスをログに残すという作業が発生したのだが、なかなか大変でした。

  • レスポンスを使えるようにするにはLuaというモジュールが必要
  • Luaを使うには自分でnginxをビルドしなければならない
  • が、いざビルドしてみたら、AmazonLinux2ではmakeの段階でエラーが出る。。。(未解明
  • 仕方ないのでdockerを入れてdockerのcentOS上でビルドすることに
  • なんやかんやあって他のモジュールも入れることになった
  • めんどくさいのでDockerfile書くかーと思って書いたらDocker buildでmakeコマンド流すとなぜかエラーになる
  • 原因調査するのも疲れたので、docker起動したら最初に流すシェルを作った <-いまここ

centOSの起動コマンド

サービスを使うのでprivilegedというオプションをつけます。あと、ここではホストOSの5000をcentOSの80にバインドしています。

$ sudo docker run --privileged -p 5000:80 -d centos /sbin/init

起動したら流すシェル

長大になってしまった。。。。
大変参考になった記事 > http://tatsuyafw.hatenablog.jp/entry/2015/10/18/222156

コンテナに入って、適当な名前でファイルを作って下記をコピペ、bashから実行すればokです。
実行後は /opt/nginx/conf/nginx.conf ができているハズなので、その辺を読んで頑張りましょう。


echo ===1==========================================================
cd tmp
curl -O http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar zxvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4

echo ===2==========================================================
yum -y install ntp

echo ===3==========================================================
yum -y install make

echo ===4==========================================================
yum -y install gcc

echo ===5==========================================================
make PREFIX=/usr/local/luajit

echo ===6==========================================================
make install PREFIX=/usr/local/luajit

echo ===7==========================================================
curl -L https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz -o ngx_devel_kit-v0.2.19.tar.gz
tar xzvf ngx_devel_kit-v0.2.19.tar.gz

echo ===8==========================================================
curl -L https://github.com/openresty/lua-nginx-module/archive/v0.9.16.tar.gz -o ngx_lua-v0.9.16.tar.gz
tar zxvf ngx_lua-v0.9.16.tar.gz

echo ===9==========================================================
yum -y install pcre-devel

echo ===10==========================================================
yum -y install zlib-devel

echo ===11==========================================================
curl -L -O http://nginx.org/download/nginx-1.9.5.tar.gz
tar zxvf nginx-1.9.5.tar.gz
cd nginx-1.9.5

echo ===12==========================================================
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0

echo ===13==========================================================
./configure --prefix=/opt/nginx \
--with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" \
--add-module=../ngx_devel_kit-0.2.19/ \
--add-module=../lua-nginx-module-0.9.16/
--with-http_auth_request_module \

echo ===14==========================================================
make -j2

echo ===15==========================================================
make install

echo ===16==========================================================
# rm -f /opt/nginx/conf/nginx.conf
mv /opt/nginx/conf/nginx.conf /opt/nginx/conf/nginx.conf.back
touch /opt/nginx/conf/nginx.conf

cat - << EOS > /opt/nginx/conf/nginx.conf
worker_processes  1;

#error_log  logs/error.log  info;
#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                      '\$status \$body_bytes_sent "\$http_referer" '
                      '"\$http_user_agent" "\$http_x_forwarded_for" - \$request_body';

    log_format bodylog '\$remote_addr - \$remote_user [\$time_local] '
                       '"\$request" \$status \$body_bytes_sent '
                       '"\$http_referer" "\$http_user_agent" \$request_time '
                       '<"\$request_body" >"\$resp_body"';

    lua_need_request_body on;

    sendfile        on;
    keepalive_timeout  65;
    # auth_request /auth

    server {
        listen       80;
        server_name  localhost;

        charset utf-8;

        access_log  /logs/host.access.log  main;

        location / {
            proxy_pass http://xxx.yyy.bbb.zzz:3000;
            root   html;
            index  index.html index.htm;
        }

        location /api/user/current {
            proxy_pass http://xxx.yyy.bbb.zzz:3000;
            access_log  /logs/user.access.log  bodylog;

            set \$resp_body "";
            body_filter_by_lua '
              local resp_body = string.sub(ngx.arg[1], 1, 10000)
              ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
              if ngx.arg[2] then
                ngx.var.resp_body = ngx.ctx.buffered
              end
            ';
        }

        location /health {
            content_by_lua "ngx.say('ok')";
        }

        #error_page  404              /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }
}
EOS

echo ===17==========================================================
touch /lib/systemd/system/nginx.service

echo ===18==========================================================
cat - << EOS > /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOS

echo ===19==========================================================
systemctl enable nginx
systemctl start nginx
systemctl status nginx

結構疲れたけど、初めてNginxを触って色々勉強になったし、docker触ってshellを色々書くのも久々だったのでなかなか楽しかった。
作ってデバッグして速攻捨てれて、docker便利だよなーと改めて思ったり。