nginx で gzip_static と gunzip を使ってストレージを節約する

一月ほど前に 社内Gyazoの画像をAmazon S3に逃がしてスケーラブルに運用する - 酒日記 はてな支店 というエントリを書いて一段落と思いきや、そのサーバには社内向けの nopaste アプリも同居しており、気がつけばテキストファイルが10GB以上積もっていたのでした…

社内 nopaste アプリの実装はDBなどを使用せず単にテキストファイルを保存しているだけだったので、ファイルを gzip して nginx の http_gzip_static_module を使って配信したらディスクを節約できていいんじゃないか、と思いついたのですが、Accept-Encoding: gzip でないクライアントからアクセスすると 404 になってしまうので圧縮前のファイルが消せない。

今時ブラウザで対応していないものは少ないとはいえ、curlとか各種言語のHTTPクライアントでアクセスする場合もあるので、gzip 非対応クライアントには展開した内容を返したいところです。

それ ngx_http_gunzip_module でできるよ、ということでこうなりました。

gzip_static always を指定するため、nginx version 1.3.6 以降が必要です。
また、gzip_static と gunzip モジュールはデフォルトでは組み込まれないため、build時に --with-http_gunzip_module --with-http_gzip_static_module を指定して有効にする必要があります。

    location ~ ^/nopaste/([0-9a-f]+)\.txt {
         gunzip       on;
         gzip_static  always;
    }

これで動作としては

  • gzip_static always によりクライアントの gzip 対応非対応お構いなしに .gz ファイルの内容を配信
  • gunzip on により、クライアントが gzip 非対応であればその場で展開

となり、どちらのクライアントに対しても .gz で保存された内容を送信することが可能になりました。