自作スクリプトによるWordPressサイトのバックアップ

6

先日、ふとこの WordPress サイトのバックアップを確認しようとしたら様子がおかしい。 調べてみると WordPressのバックアッププラグイン「backWPup」がバージョンアップされ、いままでのものとは全く別物のように改悪されていました。このプラグイン、以前からバックアップ先が wp-content/upload 配下以外にできなくなっていたりと動作がおかしかったのですが、どうもそのころに開発元が買収されて、それからあれよあれよと壊れてきた模様。

考えてみるとこの程度のバックアップなんか自作スクリプトで全く問題ないわけです。早速方針を決めて作成・運用してみました。
 

バックアップ全体の方針

私はVPSを2台借りており、3つのWordpressサイト、1つのマストドンサイト、1つのPukiwikiサイトを運用しています。また重要なファイルのバックアップは AWS S3 に行っています。せっかくVPSが2台あるので以下のような構成を考えました。2つのサーバとAWSのうち、2箇所で障害がおきてもなんとかなる方式です。
 


 

また、バックアップの頻度・回数ですが、月3回(1日、10日、20日)、保存期間は2ヶ月としました。
 

バックアップ取得

 

ファイルバックアップとデータベースバックアップで別のスクリプトを作り、rootの cron に登録します。ともに毎月1,10,20日にバックアップを行います。時間はUTCなので、登録は17時ですが、実際に走るのは夜の0時台(当方ベトナム在住のためUTC+7)です。なぜ曜日指定で走らせないかというと、曜日指定だと「1ヶ月前のファイルを削除する」処理が面倒になるからです(ファイルのタイムスタンプではなくファイル名に埋め込んだ日付で処理したいという事情があった)。


05 17 1,10,20 * * /bin/sh /storage/file_backup_wordpress.zenmai.org.sh
15 17 1,10,20 * * /bin/sh /storage/db_backup_wordpress.zenmai.org.sh

 

データベースバックアップのスクリプトは以下のようになります。アーカイブ名に20250223のようにyyyymmddで日付が入り、yyyymm(-2ヶ月)ddのファイルがあれば削除、という世代管理です。



#/bin/sh

#作業ディレクトリ・日付等を取得
DIR='/storage/backup.wordpress.zenmai.org'
DATE=`/bin/date '+%Y%m%d'`
TODAY=`/bin/date '+%d'`
DELETE_MONTH=`/bin/date -d '2 month ago' +%Y%m`

#バックアップ収集
mysqldump --add-drop-table -h localhost -u USERNAME -pPASSWORD DBNAME > "${DIR}/wordpress.zenmai.org_DB_${DATE}.dump.sql"

if [ $? -eq 0 ]; then
  echo "Database dump complete"
else
  echo "Database dump incomplete"
fi


#圧縮
tar zcfv "${DIR}/wordpress.zenmai.org_DB_${DATE}.dump.sql.tgz" -C "${DIR}" "wordpress.zenmai.org_DB_${DATE}.dump.sql"

if [ $? -eq 0 ]; then
  echo "compress complete"
else
  echo "compress incomplete"
fi

chown -c rrr:www-data "${DIR}/wordpress.zenmai.org_DB_${DATE}.dump.sql.tgz"
rm "${DIR}/wordpress.zenmai.org_DB_${DATE}.dump.sql"

# 過去のバックアップを削除
    if [ -f "${DIR}/wordpress.zenmai.org_DB_${DELETE_MONTH}${TODAY}.dump.sql.tgz" ]; then
        rm "${DIR}/wordpress.zenmai.org_DB_${DELETE_MONTH}${TODAY}.dump.sql.tgz"
        echo "Delete wordpress.zenmai.org_DB_${DELETE_MONTH}${TODAY}.dump.sql.tgz"
    fi

 
ファイルバックアップのスクリプトは以下のようになります。アーカイブ名に20250223のようにyyyymmddで日付が入り、yyyymm(-2ヶ月)ddのファイルがあれば削除、という世代管理です。また、upload 配下のメディアファイルは3GBを超える量になるうえに、毎回バックアップをとる必要はないため、除外しています。


#/bin/sh

#作業ディレクトリ・日付等取得
DIR='/storage/backup.wordpress.zenmai.org'
DATE=`/bin/date '+%Y%m%d'`
TODAY=`/bin/date '+%d'`
DELETE_MONTH=`/bin/date -d '2 month ago' +%Y%m`

#バックアップ収集 /wp-content/uploads/ の過去のものはバックアップしない
tar zfcv "${DIR}/wordpress.zenmai.org_FILE_expect.upload.before2024_${DATE}.tgz" --exclude='wp/wp-content/uploads/1970' --exclude='wp/wp-content/uploads/201*' --exclude='wp/wp-content/uploads/2020' --exclude='wp/wp-content/uploads/2021' --exclude='wp/wp-content/uploads/2022' --exclude='wp/wp-content/uploads/2023'  --exclude='wp/wp-content/uploads/2024' -C /http wp > /dev/null

if [ $? -eq 0 ]; then
  echo "File backup complete. Make archive file wordpress.zenmai.org_FILE_expect.upload.before2024_${DATE}.tgz"
else
  echo "File backup incomplete"
fi

#固めてパーミッション変更
chown -c rrr:www-data "${DIR}/wordpress.zenmai.org_FILE_expect.upload.before2024_${DATE}.tgz"

# 過去のバックアップを削除
    if [ -f "${DIR}/wordpress.zenmai.org_FILE_expect.upload.before2024_${DELETE_MONTH}${TODAY}.tgz" ]; then
        rm "${DIR}/wordpress.zenmai.org_FILE_expect.upload.before2024_${DELETE_MONTH}${TODAY}.tgz"
        echo "delete wordpress.zenmai.org_FILE_expect.upload.before2024_${DELETE_MONTH}${TODAY}.tgz"
    fi

 

バックアップのVPS間転送

以下のスクリプトを cronで走らせて(こちらは一般ユーザのcronに登録)、別のVPSに同期バックアップさせます。事故防止のために、以下の場合はエラー終了するようにしています。

1.ゼロバイトのアーカイブがあった場合(=アーカイブ作成に問題があった場合)
2.DoSync(事前に手動設置)というファイルが存在しなかった場合(=ディレクトリ・ディスクに問題があった場合)


#/bin/sh

#ゼロバイトのファイルがあればそこでエラー終了
cd /storage/backup.wordpress.zenmai.org/
for file in $(ls /storage/backup.wordpress.zenmai.org/); do
                if [ ! -s ${file} ]; then
                echo "Find zero byte file. exit."
                exit
                fi
done

#DoSyncというファイルが存在しなければエラー終了
if [ -e "${DIR_FROM}/DoSync" ]; then
        echo "WORDPRESS: Sync to VPS2 starting....."
        echo "...."
        rsync -avz --delete -e "ssh -p ポート番号 -i ~/.ssh/鍵ファイル" ${DIR_FROM} user@VPS2.zenmai.org:/backups_VPS1/
        else
        echo "WORDPRESS: Something wrong? transfer to aws not start"
exit
fi

 

AWSへの転送

以下のスクリプトを cronで走らせて(こちらも一般ユーザのcronに登録)、AWSに同期バックアップさせます。事故防止のために、以下の場合はエラー終了するようにしています。

1.ゼロバイトのアーカイブがあった場合(=アーカイブ作成に問題があった場合)
2.DoBackup(事前に手動設置)というファイルが存在しなかった場合(=ディレクトリ・ディスクに問題があった場合)


#!/bin/sh

#ゼロバイトのファイルがあればそこでエラー終了
cd /backups_hongxiem/backup.wordpress.zenmai.org/
for file in $(ls /backups_hongxiem/backup.wordpress.zenmai.org/); do
                if [ ! -s ${file} ]; then
                echo "Find zero byte file. exit."
                exit
                fi
done

#DoBackupというファイルが存在しなければエラーメッセージを出して終了、あれば同期バックアップを行う

if [ -e "/backups_hongxiem/backup.wordpress.zenmai.org/DoBackup" ]; then
        echo "WORDPRESS: Sync to aws starting....."
#同期実行
        aws s3 sync  --exclude 'DoBackup' --exclude 'DoSync' /backups_hongxiem/backup.wordpress.zenmai.org/ s3://zenmaivpsbackup/wordpress.zenmai.org_backup/daily_backup/ --delete --storage-class STANDARD_IA > /dev/null
#現存アーカイブリストを取得
        aws s3 ls s3://zenmaivpsbackup/wordpress.zenmai.org_backup/daily_backup/ | grep tgz
        else
        echo "WORDPRESS: Something wrong? transfer to aws not start"
exit
fi

これで2ヶ月くらい回しています。まだ復旧作業の検証はしてないですが、まー経験上このファイルがあれば大丈夫でしょう。