CloudflareのAPIをNode.js+GitLab CIから実行してキャッシュクリアしてみよう
こんにちは、n0bisukeです。
過去にも書いているように、dotstudioではCloudflareを使っています。
無料で使えて便利なのですが、キャッシュが強くて中々更新されないといった現象があります。
調べてみるとCloudflareのAPIでキャッシュクリアが出来るみたいだったのでNode.jsで叩きつつデプロイ時のCIタスクに乗せてみました。
今回の環境
参考までに今回の筆者の環境です。
- macOS 10.14 Mojave
- Node.js v11.9.0
- npm 6.7.0
Cloudflareでのキャッシュクリア方法
APIを使わない場合は、ページから直接削除できます。
Custom Purgeのボタンを押すと、モーダルウィンドウが出てくるのでキャッシュクリアしたいドメインやページを指定しましょう。
こんな感じの指定が出来ます。
https://dotstud.io
のようにメインドメイン指定が出来ます。https://hogehoge.dotstud.io
のようにサブドメインでも大丈夫です。https://hogehoge.dotstud.io/hoge.html
のようにファイル指定も可能です。
記述したらPurge
ボタンを押してキャッシュクリアです。
確認する際ですが、ブラウザ側のキャッシュが残ってしまってる可能性もあるので、ブラウザのシークレットモードなどでページを開いてあげると確実だと思います。
API経由でCloudflareのキャッシュをクリア
デプロイ時にキャッシュクリアをしたいので、API経由でキャッシュクリアをしてみましょう。
CloudflareのAPI キーの取得
まずはAPIキーを取得します。右上のユーザーアイコンからMy Profile
を選択し、ページ下部のAPI Keysの箇所を確認します。
Global API KeyのViewボタンを押すとパスワード入力を求められるので、パスワードを入力するとAPIキーが表示されます。
APIキーを使ってcurlでキャッシュクリアをしてみる
参考記事を元に試してみます。最初からNode.jsでやりたい人はスキップでOKです。
CloudflareのAPIの呼び出しはヘッダーにはX-Auth-Email
とX-Auth-Key
の指定、Content-Type: application/json
の指定をする必要があります。
手順としては大きく分けて2つSTEPです。
- STEP1. ZONE IDと呼ばれるIDを取得
- STEP2. ZONE IDを使ってキャッシュクリア
以下のコマンドをターミナルなどで実行してみましょう。
STEP1. ZONE IDと呼ばれるIDを取得
まずはZONE IDの取得です。以下のコマンドで取得できます。
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=<MY DOMAIN>" -H "X-Auth-Email: <MY EMAIL>" -H "X-Auth-Key: <MY API KEY>" -H "Content-Type: application/json"
<MY DOMAIN>
、<MY EMAIL>
、<MY API KEY>
の箇所を適宜変更して実行して下さい。
それぞれ、自分が管理しているドメイン、登録しているメールアドレス、先ほど取得したAPIキーです。
実行例
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=dotstud.io" \ -H "X-Auth-Email: [email protected]" \ -H "X-Auth-Key: xxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json"
ZONE ID
コマンドを実行してエラーがなければ、JSONがかえってきます。ここのidの値がZONE IDになります。
{"result":[{"id":"yyyyyyyyyyyyyyyyyyyy","name":"dotstud.io","status":"active","paused":false,"type":"full", (......以下省略)
STEP2. ZONE IDを使ってキャッシュクリア
次にZONE IDを使ってキャッシュクリアです。
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/<ZONE ID>/purge_cache" -H "Content-Type:application/json" -H "X-Auth-Key: <MY EMAIL>" -H "X-Auth-Email: <MY API KEY>" --data '{"files":["<TARGET>"]}'
先ほどと同様に適宜変更します。
<ZONE ID>
、<MY EMAIL>
、<MY API KEY>
、<TARGET>
の箇所を適宜変更して実行して下さい。
<ZONE ID>
はSTEP1で取得したZONE IDで、<TARGET>
はキャッシュクリアさせたいドメインやファイル名の指定です。最初にAPI利用なしでCloudflareのサイト上でキャッシュクリアをした時に指定したときと同様の指定ができます。
実行例
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/yyyyyyyyyyyyyyyyyyyy/purge_cache" \ -H "Content-Type:application/json" \ -H "X-Auth-Key: xxxxxxxxxxxxxxxx" \ -H "X-Auth-Email: [email protected]" \ --data '{"files":["https://hogehoge.dotstud.io/"]}'
成功すると以下のようなレスポンスがあり、キャッシュがクリアされます。
{"result":{"id":"yyyyyyyyyyyyyyyyyyyy"},"success":true,"errors":[],"messages":[]}%
Node.jsでAPIを叩いてみる
まずはフォルダやファイルの準備をしましょう。
mycfフォルダ内にpurge_cache.js
というファイルを作成します。
mkdir mycf
cd mycf
touch purge_cache.js
HTTPリクエストを利用する為にaxiosをインストールします。
npm init -y
npm i axios
purge_cache.js
に以下の内容をコピペして、YOUREMAIL
、APIKEY
、PURGE_TARGETS
を適宜書き換えましょう。
'use strict';
const YOUREMAIL = `[email protected]`; //Cloudflareに登録してるメールアドレス
const APIKEY = `xxxxxxxxxxxxxxxxx`; //CloudflareのAPI KEY
const PURGE_TARGETS = [`https://hogehoge.dotstud.io`]; //消す対象ページ
const axiosBase = require('axios');
const axios = axiosBase.create({
baseURL: `https://api.cloudflare.com/client/v4/zones`,
headers: {
'Content-Type': 'application/json',
'X-Auth-Key': APIKEY,
'X-Auth-Email': YOUREMAIL
}
})
const main = async() => {
try {
//STEP1. ZoneIDの取得
let res = await axios.get('/');
const zoneid = res.data.result[0].id;
//STEP2. キャッシュ削除
res = await axios.delete(`/${zoneid}/purge_cache`,{
data: {
files: PURGE_TARGETS
}
});
console.log(res.data);
} catch (error) {
console.log(error.response.data)
}
}
main();
実行します。エラーが出なければこれでキャッシュクリアされます。
node purge_cache.js
これでNode.jsからCloudflareのキャッシュクリアをすることが出来ました。
GitLab CIのタスクで実行する
実際にデプロイした際にキャッシュクリアされるようにしたいのでGitLab CIのタスクに入れ込みました。
ソースコードの変更
先ほどソースコード上に書いていたYOUREMAIL
などの値は環境変数から取得するようにpurge_cache.js
を変更しました。また、最後(STEP3)にDiscordにデプロイ成功を通知する処理も追加しています。
'use strict';
if(!process.env.YOUREMAIL || !process.env.APIKEY || !process.env.PURGE_TARGET){
console.log('環境変数が足りません');
return;
}
const YOUREMAIL = process.env.YOUREMAIL; //Cloudflareに登録してるメールアドレス
const APIKEY = process.env.APIKEY; //CloudflareのAPI KEY
const PURGE_TARGETS = [process.env.PURGE_TARGET]; //消す対象ページ
const axiosBase = require('axios');
const axios = axiosBase.create({
baseURL: `https://api.cloudflare.com/client/v4/zones`,
headers: {
'Content-Type': 'application/json',
'X-Auth-Key': APIKEY,
'X-Auth-Email': YOUREMAIL
}
})
const main = async() => {
try {
//STEP1. ZoneIDの取得
let res = await axios.get('/');
const zoneid = res.data.result[0].id;
//STEP2. キャッシュ削除
res = await axios.delete(`/${zoneid}/purge_cache`,{
data: {
files: PURGE_TARGETS
}
});
console.log(res.data);
//STEP3. Discordへ通知
res = await axiosBase.post(process.env.DISCORD_WEBHOOK_URL,{
content: 'デプロイ成功 & キャッシュクリア'
});
console.log(res.data);
} catch (error) {
console.log(error.response.data)
}
}
main();
package.jsonの変更
また、先日書いた記事にもあるような、VuePressのデプロイフローに今回のタスクを乗せていきます。
package.json
にci:purge_cache
を追加してpurge_cache.js
を実行するスクリプトを追加します。
(省略)
"scripts": {
"dev": "vuepress dev docs",
"build": "vuepress build docs",
"ci:purge_cache": "node purge_cache.js",
},
(省略)
.gitlab-ci.ymlの変更
GitLab CIの挙動として.gitlab-ci.yml
の記述は以下のようにしています。
after_script
の箇所でnpm run ci:purge_cache
をすることで、デプロイが終わった後にpurge_cache.js
が実行されてキャッシュクリアがされます。
image: node:current-alpine
pages:
cache:
paths:
- node_modules/
before_script:
- node -v
- npm i
script:
- npm run build
- cp docs/robots.txt docs/.vuepress/dist #限定公開の場合
- cp -pr docs/.vuepress/dist public
after_script:
- npm run ci:purge_cache #Cloudflareのキャッシュクリア & Discordへ通知
artifacts:
paths:
- public
only:
- master
環境変数の登録
GitLabのリポジトリから環境変数を追加することができます。
リポジトリのSettings>CI/CD
からEnvironment variables
の箇所を開きます。
各値を名前をソースコードに記述した変数名と一致させつつ設定しましょう。
まとめ
ここまでの手順が出来るとデプロイするたびに、Cloudflareのキャッシュがクリアされて、なかなか更新されない問題が解消できると思います。
これでもページが更新されない場合はブラウザ側でキャッシュされている可能性が高いのでシークレットモードなどで確認したり、ブラウザを変えてみるのがベターだと思います。
キャッシュコントロールをしてCloudflareをもっと便利に使っていきましょう。
それでは!