複数のクライアントサイトを管理するWordPress制作会社にとって、強固なバックアップ戦略は欠かせません。予期せぬ障害、プラグインの不具合、人為的なミスが生じた場合でも、バックアップでデータを迅速に復元できれば、サイトのダウンを最小限に抑え、リスクを軽減することができます。

Kinstaでは、バックアップが果たす重要な役割を理解し、毎日の自動バックアップ、手動バックアップ、システム生成バックアップ、ダウンロード可能バックアップ、さらに時間単位(1時間または6時間ごと)のバックアップと外部バックアップ(Amazon S3またはGoogle Cloud Storage)アドオンの全6種類のバックアップを提供しています。

バックアップの管理は、コントロールパネルのMyKinstaから簡単に行えますが、KinstaのAPIを利用して、反復的なタスクを自動化することも可能です。

Slackでコマンドを入力したり、MyKinstaの企業アカウントのすべてのWordPressサイトのバックアップをトリガーするcronジョブを設定するだけで、何十、何百ものサイト管理画面を手動で移動して操作する必要がなくなります。

このように顧客の要件を優先するホスティングサービスを選ぶことで、生産性向上を目指した独自のソリューションを構築できるのは、大きなメリットです。

今回は、Kinsta APIを活用して複数のサイトのバックアップを自動化する方法をご紹介します。お好きなスタックとの統合、Slackのようなツールの使用、またはスケジュールの設定など、バックアッププロセスを合理化し、ワークフローを強化するのに役立つはずです。

全サイトまたは特定のサイトのバックアップを実装する方法

作業に入る前に、まずはMyKinstaアカウント内のすべてのサイトのバックアップをトリガーする方法と、Kinsta APIを使用して特定のサイトや環境のバックアップをトリガーする方法を理解しておきましょう。

バックアップ作成の基本を押さえておけば、プロセスの自動化を簡単に統合することができます。

MyKinstaアカウント内の全サイトのバックアップをトリガーする

すべてのAPIに言えることですが、1つのエンドポイントで必要な操作をすべて行えるとは限りません。期待する結果を得るには、複数のエンドポイントを組み合わせる必要があります。

Kinsta APIも同様で、バックアップ管理用のエンドポイントはありますが、各エンドポイントは環境IDのような特定のパラメータを必要とし、他のエンドポイントに追加のリクエストを行うことで取得します。

例えば、サイトの手動バックアップをトリガーするには、その環境のIDが必要です。そして環境IDを取得するには、サイトIDが必要になります。つまり、サイトIDの取得、環境IDの取得、そしてバックアップのトリガーと、複数のAPI呼び出しを行わなければなりません。

ステップ 1. Kinsta APIですべてのWordPressサイトを取得する

最初のステップは、MyKinstaアカウントに紐づけられているすべてのサイトを取得します。Kinsta APIは、サイトIDやサイト名など、関連情報を含むデータを取得するエンドポイントを提供しています。GET /sitesエンドポイントを使用すると、企業アカウントにあるすべてのサイト一覧を引き出すことができます。

以下は、Node.jsとFetch APIを使用した例です。

require('dotenv').config();

const KINSTA_API_URL = 'https://api.kinsta.com/v2';
const API_KEY = process.env.KINSTA_API_KEY;

async function getAllSites() {
    const response = await fetch(`${KINSTA_API_URL}/sites`, {
        headers: {
            Authorization: `Bearer ${API_KEY}`
        }
    });
    const data = await response.json();
    return data.company.sites; // すべてのサイトの配列を返す
}

この関数は、アカウント内のすべてのサイトの配列を返します。各サイトには、サイトID、サイト名、環境などの情報が含まれています。

ステップ2. 各WordPressサイトの環境IDを取得する

各サイトは複数の環境(本番環境やステージング環境など)を持つことができ、バックアップは環境ごとにトリガーされます。各サイトの環境IDを取得するには、GET /sites/{site_id}/environmentsエンドポイントにAPI呼び出しを行います。

特定のサイトの環境を取得する関数の例は以下のとおりです。

async function getSiteEnvironments(siteId) {
    const response = await fetch(`${KINSTA_API_URL}/sites/${siteId}/environments`, {
        headers: {
            Authorization: `Bearer ${API_KEY}`
        }
    });
    const data = await response.json();
    return data.site.environments;
}

ステップ3. 各環境のバックアップをトリガーする

環境IDを取得したら、POST /sites/environments/{env_id}/manual-backupsエンドポイントを使用して各環境のバックアップをトリガーします。このAPIでは、環境IDとバックアップを識別するための任意のタグにより、手動でバックアップを作成できます。

指定した環境のバックアップをトリガーする方法は、以下のようになります。

async function createBackup(environmentId, tag) {
    const response = await fetch(`${KINSTA_API_URL}/sites/environments/${environmentId}/manual-backups`, {
        method: 'POST',
        headers: {
            Authorization: `Bearer ${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ tag })
    });

    if (response.ok) {
        console.log(`タグ ${tag} で環境 ${environmentId} のバックアップを作成`);
    } else {
        console.error(`環境 ${environmentId} のバックアップ作成に失敗`);
    }
}

この関数は、指定された環境IDの手動バックアップをトリガーします。バックアップを識別しやすくするためにタグを付けることも可能です。

ステップ4. 全サイトのバックアップを自動化する

すべてのサイトを取得して、環境IDを取得し、バックアップをトリガーする関数ができたら、これらを組み合わせて、MyKinstaアカウントの全サイトのバックアップを自動化するスクリプトを作成します。

これは以下のようになります。

async function backupAllSites() {
    const sites = await getAllSites();

    for (const site of sites) {
        const environments = await getSiteEnvironments(site.id);

        for (const environment of environments) {
            await createBackup(environment.id, `Backup-${new Date().toISOString()}`);
        }
    }

    console.log('全サイトのバックアップを開始');
}

この関数はすべてのサイトをループし、環境を取得して、タイムスタンプ付きタグで各環境のバックアップをトリガーします。

backupAllSites()を実行すると、MyKinstaアカウントのすべての環境のバックアップがトリガーされます。

Slackコマンドの例

このバックアッププロセスをSlackコマンドに統合すると、さらに管理が簡素化されます。Slackアプリをセットアップすることで、/backup_all_sitesのような単一のコマンドで、すべてのサイトのバックアップをトリガーすることができます。

以下は簡単な例になります。

app.command('/backup_all_sites', async ({ ack, say }) => {
    await ack();
    await backupAllSites();
    say('全サイトのバックアップを開始');
});

環境IDを使用して特定のサイトのバックアップをトリガーする

状況によっては、MyKinstaアカウントの全サイトではなく、特定のサイトまたは環境のバックアップのみをトリガーしたいこともあります。例えば、本番環境や特定の優先度の高いサイトのみをバックアップしたい場合に便利です。

Kinsta APIを使って環境IDの配列を渡すことで、選択した環境のバックアップを自動化することが可能です。以下、その手順をご紹介します。

ステップ 1. 環境IDを渡す

特定のサイトのバックアップをトリガーする場合、例によってサイトの環境IDが必要になります。IDはハードコーディングするか、Kinsta APIから取得するか、動的に(コマンドライン引数やSlackコマンドなどを通して)渡すことができます。

環境IDの配列を受け取り、それぞれのバックアップをトリガーする関数は、以下ようになります。

async function backupSelectedEnvironments(environmentIds, tag) {
    for (const envId of environmentIds) {
        await createBackup(envId, tag);
    }
}

上の関数は、バックアップしたい環境IDの配列を受け取ります(environmentIds)。createBackup(envId, tag)関数は、createBackup()(次のステップで詳しく解説)を使用して、配列内の各環境のバックアップをトリガーします。

ステップ2. バックアップをトリガーする

各環境の実際のバックアップをトリガーするには、全サイトに対して行ったのと同様に、Kinsta APIのPOST /sites/environments/{env_id}/manual-backupsエンドポイントを使用します。

async function createBackup(environmentId, tag) {
    const response = await fetch(`${KINSTA_API_URL}/sites/environments/${environmentId}/manual-backups`, {
        method: 'POST',
        headers: {
            Authorization: `Bearer ${API_KEY}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ tag })
    });

    if (response.ok) {
        console.log(`タグ ${tag} で環境 ${environmentId} のバックアップを作成`);
    } else {
        console.error(`環境 ${environmentId} のバックアップ作成に失敗: ${response.statusText}`);
    }
}

ステップ3. 環境のバックアップを実行する

バックアップをトリガーして複数の環境を処理する関数ができたら、これらを組み合わせて特定の環境をバックアップします。この例では、バックアップしたい環境IDをすでに取得していると仮定します。

const selectedEnvironments = ['12345', '67890']; // 実際の環境IDに置き換える
backupSelectedEnvironments(selectedEnvironments, '手動バックアップ');
  • selectedEnvironments配列にはバックアップしたい環境IDが含まれる
  • backupSelectedEnvironments()は各IDをループし、タグ「手動バックアップ」でバックアップをトリガーする

Slackコマンドの例

Slackアプリやコマンドラインインターフェースを使用している場合、バックアップする環境をユーザーが指定できるようにすることもできます。

以下はSlackアプリでの実装方法です。

app.command('/backup_selected_envs', async ({ command, ack, say }) => {
    await ack();
    const [tag, ...envIds] = command.text.split(' ');  // 最初の部分はタグで残りは環境ID
    await backupSelectedEnvironments(envIds, tag);
    say(`Backups triggered for selected environments with tag ${tag}.`);
});

ユーザーは、/backup_selected_envs Backup-Tag 12345 67890のようなコマンドを入力します。Backup-Tagはタグ、12345, 67890は環境IDです。

コマンドのテキストは分割され、環境IDはbackupSelectedEnvironments()に渡されます。

バックアップのトリガー後、アプリがバックアップ完了の旨を返します。

WordPressサイトのバックアップをスケジュールする方法

自動化の大きなメリットは、手を動かすことなく特定の時間にタスクを自動で実行できることです。

全サイト、また特定のサイトのバックアップをトリガーする方法を理解したら、次のステップはこれらのプロセスをスケジュールします。

これはローカル、Kinstaのようなホスティングプラットフォーム、Slack経由など、さまざまな方法で実装可能です。

cron式を理解する

バックアップをスケジュールするための方法を検討する前に、cron式について知っておきましょう。

cron式は、タスクがいつ実行されるべきかを定義するものです。node-cronnode-schedule、そしてKinstaのアプリケーションホスティングで利用できるようなサーバーサイドのcronジョブなど、多くのスケジュールライブラリやサービスで使用されています。

cron式は5つのフィールドで構成され、各フィールドはタスクが実行されるタイミングを制御します。一般的には以下のようになります。

* * * * *
| | | | |
| | | | └─── 曜日 (0 - 7) (日曜から土曜日、0と7は日曜日を示す)
| | | └────── 月 (1 - 12)
| | └──────── 日 (1 - 31)
| └────────── 時 (0 - 23)
└──────────── 分 (0 - 59)

各フィールドは以下のようになっています。

  • :タスクが実行される時間の分(0~59)
  • :タスクが実行される日の時間(0~23)
  • :タスクを実行する日(1~31)
  • :タスクを実行する月(1 – 12)
  • 曜日:タスクを実行する曜日(0~7、0と7は日曜日を示す)

スケジュールの定義には、各フィールドで特定の値、ワイルドカード(*)、または範囲を使用することができます。

cron式の例を見てみましょう。

  • 0 0 * * *:毎日午前0時(00:00)
  • 0 3 * * 1:毎週月曜日午前3時
  • */10 * * * *:10分毎
  • 0 9-18 * * *:午前9時から午後6時までの1時間ごと

cron式を十分に理解した上で、Kinsta APIを使用してWordPressサイトのバックアップをスケジュールする方法をご紹介していきます。

方法1. ローカルでnode-cronを使用する

Node.jsパッケージのnode-cronは、cronのような構文に基づいてスケジュールされたタスクを実行します。ローカルまたはスタンドアロン型のNode.jsアプリケーションで自動化したタスクを実行するのに適しており、バックアップのスケジュールやメールの送信など、定期的なタスクの実行によく使用されます。

node-cronでは、タスク(バックアップなど)を定義し、cron式を使用してタスクが実行されるタイミングを指定します。cron式は、先に触れたとおり、タスクが実行される分、時、日、月、曜日を定義する5つのフィールドで構成されています。

まずは、プロジェクトにnode-cronをインストールします。

npm install node-cron

例えば、node-cronを使用して全サイトのバックアップを毎日午前0時にスケジュールしたいとします。この場合は、以下のようになります。

const cron = require('node-cron');
const { backupAllSites } = require('./app');  // バックアップ機能のインポート

// 毎日午前0時に全サイトのバックアップを実行するスケジュール
cron.schedule('0 0 * * *', () => {
  console.log('午前0時に全サイトのスケジュールバックアップを実行...');
  backupAllSites();
});

特定の環境を毎日午前2時にバックアップするには、次のようにスケジュールします。

cron.schedule('0 2 * * *', () => {
  const environmentIds = ['env12345', 'env67890']; // バックアップする特定の環境
  console.log('選択した環境のスケジュールバックアップを実行中...');
  backupSelectedEnvironments(environmentIds, 'Scheduled Backup');
});

方法2. クラウドホスティング(Kinstaなど)でcronジョブを使用する

Node.jsアプリケーションをKinstaのようなプラットフォームにデプロイする場合、バックアップのようなタスクのスケジュールに組み込まれているcronジョブを活用できます。クラウド環境でcronジョブを設定するには、node-cronのようなローカルのスケジュールツールとは少し異なる構造が必要になります。

Kinstaにアプリをデプロイする際には、ウェブプロセスを実行します(ウェブトラフィックがなくても)。

プロジェクトが正しく実行され、自動的にバックアップ機能を呼び出さないようにするには、ウェブサーバーを実行するシンプルなファイルを作成します。このファイルは「偽の」ウェブプロセスとして機能し、cronジョブがバックアップロジックを処理します。

ファイルには、以下のコードを追加してください。

require('http').createServer((req, res) => {
    res.writeHead(302, { Location: 'https://www.google.com' });
    res.end();
}).listen(process.env.PORT);

これにより、スクリプトコマンドをウェブプロセス(start)とcronジョブプロセス(cron)を区別するように設定することができます。

  "scripts": {
    "start": "node index.js",  // ウェブプロセス
    "cron": "node app.js"  // cronジョブプロセス
  },

最後に、指定した時間にバックアップ機能を呼び出すようにKinstaのcronジョブを設定します。cronジョブの設定を使用して、バックアップを実行するコマンドを定義することができます。

MyKinstaにログイン後、「アプリケーション」>(アプリ名)>「プロセス」画面で、ウェブプロセスのコマンドを設定します。

npm run start

cronジョブのコマンドは以下のように設定してください。

npm run cron

特定の時間(この例では毎日午前11時30分)にcronジョブを実行するには、cron式を次のように設定します。

30 11 * * *

このコマンドはbackupAllSites()を毎日午前11時30分にトリガーします。

Kinstaのアプリケーションホスティングでcronジョブを設定
Kinstaのアプリケーションホスティングでcronジョブを設定

方法3. node-scheduleを使用する

Node.jsライブラリであるnode-scheduleでも、cron式を使用してタスクをスケジュールすることができ、より複雑なスケジュールにも対応します。

以下は、node-scheduleのcron式を使ってSlack経由でバックアップをスケジュールする例です。

const schedule = require('node-schedule');
const { backupAllSites } = require('./app');

// バックアップを動的にスケジュールするSlackコマンド
app.command('/schedule_backup', async ({ command, ack, say }) => {
    await ack();

    // コマンドから時間と分を取り出す(HH:MM形式)
    const [時間, 分] = command.text.split(':');

    // 入力を検証
    if (!時間 || !分) {
        say('時間をHH:MM形式で指定してください');
        return;
    }

    // node-scheduleのcronのような式を使ってバックアップをスケジュール
    const job = schedule.scheduleJob(`${minute} ${hour} * * *`, () => {
        console.log(`${時間}:${分}でスケジュールバックアップを実行中`);
        backupAllSites();  // これにより全サイトのバックアップが開始
    });

    say(`${時間}:${分}にバックアップが正常にスケジュールされました`);
});

例えば、以下のSlackコマンドを実行して、午後11時30分にバックアップをスケジュールすることができます。

/schedule_backup 23:30

このコマンドを実行すると、バックアップが毎日午後11時30分に実行されるようにスケジュールされ、Slackから以下のレスポンスを受け取ります。

23:30にバックアップが正常にスケジュールされました

この方法により、サーバーやアプリケーションコードとやり取りすることなく、時間を指定するだけでSlackからバックアップを動的にスケジュール可能です。バックアップのようなスケジュールしたいタスクを簡単に処理したい場合に、非常に柔軟かつ効果的なアプローチになります。

まとめ

複数のWordPressサイトでバックアップをスケジュールすることは、多数の顧客サイトを抱える制作会社や代行業者に欠かせません。バックアップを自動化することで、日々の作業を効率化できるだけでなく、一貫性を確保し、人為的ミスのリスクを減らして安心感を得ることができます。

Joel Olawanle Kinsta

Kinstaでテクニカルエディターとして働くフロントエンド開発者。オープンソースをこよなく愛する講師でもあり、JavaScriptとそのフレームワークを中心に200件以上の技術記事を執筆している。