Dockerを使ってngx_cache_purgeを試す

公開日時
更新日時

nginxでproxy_cacheを使うと手軽にキャッシュが行えるが、デフォルトだと有効期限切れになるかサーバに入ってキャッシュファイルを消すかをしないとキャッシュを削除することができない。

ngx_cache_purgeモジュールを使うとlocation指定でキャッシュを削除できるようになるので、Dockerで環境を作って試してみた。

サンプルapp

キャッシュ元になるアプリケーションサーバのサンプルをnodeで作る。

nodeの公式サイトにあるサンプルを元に↓を作成。

デフォルトだとmax-ageが0になっており、nginx側でキャッシュしないため、検証用にmax-age=60を設定。

'use strict';

const express = require('express');

// Constants
const PORT = process.env.PORT || 8080;
const HOST = process.env.HOST || '0.0.0.0';

// App
const app = express();
app.get('/', (req, res) => {
  const now = new Date().toString()
  console.log(now)

  res.set('Cache-Control', 'public, max-age=60');
  res.send(`Hello World: ${now}`);
});

app.get('/test/:id', (req, res) => {
  const now = new Date().toString()
  console.log(now)

  res.set('Cache-Control', 'public, max-age=60');
  res.send(`Hello ${req.params.id}: ${now}`);
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

nginx

ngx_cache_purgeにあるサンプルを元にnginx.confを作成。

purge locationについては本来はアクセス制限をかける必要があるが、今回は検証用なのでコメントアウトしている。

docker/nginx/nginx.conf

events {
  worker_connections 1024;
}

http {
    proxy_cache_path  /tmp/cache  keys_zone=tmpcache:10m;

    server {
        location / {
            proxy_pass         http://app:3000;
            proxy_cache        tmpcache;
            proxy_cache_key    $uri$is_args$args;

            add_header X-Cache-Status $upstream_cache_status;
        }

        location ~ /purge(/.*) {
            # allow              127.0.0.1;
            # deny               all;
            proxy_cache_purge  tmpcache $1$is_args$args;
        }
    }
}

docker/nginx/Dockerfile

procraft/nginx-purge-dockerを参考にさせていただきngx_cache_purgeを組み込むDockerfileを作成。

FROM nginx

ENV NGX_CACHE_PURGE_VERSION=2.5

# Install basic packages and build tools
RUN apt-get update && \
    apt-get install --no-install-recommends --no-install-suggests -y \
      wget \
      build-essential \
      libssl-dev \
      libpcre3 \
      libpcre3-dev \
      zlib1g-dev \
      ca-certificates && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# download and extract sources
RUN NGINX_VERSION=`nginx -V 2>&1 | grep "nginx version" | awk -F/ '{ print $2}'` && \
    cd /tmp && \
    wget http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz && \
    wget https://github.com/nginx-modules/ngx_cache_purge/archive/$NGX_CACHE_PURGE_VERSION.tar.gz \
         -O ngx_cache_purge-$NGX_CACHE_PURGE_VERSION.tar.gz && \
    tar -xf nginx-$NGINX_VERSION.tar.gz && \
    mv nginx-$NGINX_VERSION nginx && \
    rm nginx-$NGINX_VERSION.tar.gz && \
    tar -xf ngx_cache_purge-$NGX_CACHE_PURGE_VERSION.tar.gz && \
    mv ngx_cache_purge-$NGX_CACHE_PURGE_VERSION ngx_cache_purge && \
    rm ngx_cache_purge-$NGX_CACHE_PURGE_VERSION.tar.gz

# configure and build
RUN cd /tmp/nginx && \
    BASE_CONFIGURE_ARGS=`nginx -V 2>&1 | grep "configure arguments" | cut -d " " -f 3-` && \
    /bin/sh -c "./configure ${BASE_CONFIGURE_ARGS} --add-module=/tmp/ngx_cache_purge" && \
    make && make install && \
    rm -rf /tmp/nginx*

ADD ./nginx.conf /etc/nginx/nginx.conf

docker-compose.yml

最後に↓のdocker-compose.ymlを作成。

version: "3.7"

services:
  datastore:
    image: busybox
    volumes:
      - yarn_modules:/app/node_modules
  web:
    build:
      context: ./docker/nginx
      dockerfile: Dockerfile
    depends_on:
      - app
    ports:
      - "8000:80"
  app:
    build: .
    volumes:
      - .:/app
      - yarn_modules:/app/node_modules
    command: ["node", "server.js"]
    environment:
      PORT: 3000
    ports:
      - "3000:3000"

volumes:
  yarn_modules:

コンテナ起動。

docker-compose build
docker-compose run --rm app yarn
docker-compose up

確認

↓にアクセスすると初回アクセスはnode appを経由してレスポンスが返り、60秒以内に再アクセスがあった場合はnginx側でキャッシュを返す。

http://localhost:8000/test/1
http://localhost:8000/test/2

キャッシュ削除

/purge以下にキャッシュの条件を指定するとキャッシュが消せる。

http://localhost:8000/purge/test/1

また、「*」を使うと一括削除もできる。

test以下のすべてのキャッシュを消す場合は以下にアクセス。

http://localhost:8000/purge/test/*

これでngx_cache_purgeの検証ができた。

参考


Related #nginx

nginxのキャッシュ保存先を複数設定する

proxy_cache_pathは複数設定できた

wsl2上のUbuntuにrubyの開発環境を構築する

久しぶりに手動構築した

nginxでgzip圧縮設定をしたのに反映されない現象が発生

ウイルス対策ソフトのWebアクセス保護設定の影響だった