かばだんなさん かく語りぬ Header Image

WordPressのバックアップシェルを書いた

今までWordPressのバックアップはメールで送ってたのですが、いいかげんサイトの数が多くなったのでまじめにバックアップのシェルを書いてみました。

やりたい事は、

1.いざという時にはWordPress本体さえインストールすればすぐ戻せるようにする。
 具体的にはバックアップの対象は下記のとおりとする。
 ・ 「DBのデータ」
 ・ 「コンテンツファイル」(アップロードしたメディアとかプラグインとかレイアウトとか)

2.バックアップデータはローカルサーバに保存する。
 当該サーバの物理的破損への対処は別途考える事とします。

3.バックアップは毎日取るが、古いファイルは随時削除する。
 削除対象は下記のとおりとする。
 ・ 1ヶ月以上経ったら、毎月1の日(1日・11日・21日・31日)以外のファイルを削除する。
 ・ 3ヶ月以上経ったら、毎月1日のファイルを残して削除する。

と、まぁこんな感じです。

この要件で、昔書いたのを基にポチポチとシェルを書いてみました。

別に隠す程のノウハウでもないので公開します。(あ、ApacheなLinuxを想定しています。)

#!/bin/bash

# ----------------------------------------------------
# Local WordPress Backup. (DB data & contents files)
#
# ShallSystemService All Rights Reserved.
# ----------------------------------------------------

# ----------------------------------
#  Configure
# ----------------------------------
DB_NAME=*******
DB_USER=*******
DB_PASS=*******
DB_HOST=localhost

BLOG_DIR=/var/www/httpdocs/wordpress/wp-content
BACKUP_DIR=/opt/wp-backup/blog-backup

# ----------------------------------
#  Initialize
# ----------------------------------
BLOG_DIR=`dirname "$BLOG_DIR"`/`basename "$BLOG_DIR"`
BACKUP_DIR=`dirname "$BACKUP_DIR"`/`basename "$BACKUP_DIR"`

# ----------------------------------
#  Create Contents backup files
# ----------------------------------
echo -n "Creating tarball... "
TAR_NAME=${BLOG_DIR##*/}-$(date +%Y%m%d).tar.bz2
here=`pwd`
cd `dirname "$BLOG_DIR"`

# --- exclude files ----
EXCLUDE_OPTS=''
if [ -d wp-content/plugins/ktai_entry ]
then
  EXCLUDE_OPTS="${EXCLUDE_OPTS} --exclude wp-content/plugins/ktai_entry/logs"
fi

tar -cjf ${BACKUP_DIR}/${BLOG_DIR##*/}-$(date +%Y%m%d).tar.bz2 `basename "$BLOG_DIR"` ${EXCLUDE_OPTS}
cd $here
if [ "$?" -ne "0" ]; then
  cd $here
  echo "failed!"
  exit 1
fi
echo "done"

# ----------------------------------
#  Create DB backup files
# ----------------------------------
echo -n "dumping database... "
DUMP_NAME=${DB_NAME}-$(date +%Y%m%d).sql.bz2
mysqldump --user=${DB_USER} --password=${DB_PASS} --host=${DB_HOST} \
 --databases ${DB_NAME} \
 | bzip2 -c > ${BACKUP_DIR}/${DUMP_NAME}
if [ "$?" -ne "0" ]; then
  cd $here
  echo "failed!"
  exit 2
fi
echo "done"

# ----------------------------------
#  Garbage Contents Backup
# ----------------------------------
here=`pwd`
cd $BACKUP_DIR

# 1ヶ月以上前のファイルは、各旬1の日を残して削除
echo -n "garbage contents files over 1 month ago(exclude 01, 11, 21, 31). ... "
YMD=`date +%Y%m%d -d '1 months ago'`

for FILE_NAME in wp-content-*.bz2
do
  if [ $FILE_NAME '<' wp-content-$YMD ];then
    TMP_DIR=`echo $FILE_NAME | cut -c 19`

    if [ $TMP_DIR '!=' 1 ];then
      /bin/rm $BACKUP_DIR/$FILE_NAME;
    fi
  fi
done
echo "done"

# 3ヶ月以上前のファイルは、毎月1日を残して削除
echo -n "garbage contents files over 3 months ago(exclude 01 of every month). ... "
YMD=`date +%Y%m%d -d '3 months ago'`

for FILE_NAME in wp-content-*.bz2
do
  if [ $FILE_NAME '<' wp-content-$YMD ];then
    TMP_DIR=`echo $FILE_NAME | cut -c 18-19`

    if [ $TMP_DIR '!=' 01 ];then
      /bin/rm $BACKUP_DIR/$FILE_NAME;
    fi
  fi
done
echo "done"

# ----------------------------------
#  Garbage DB Backup
# ----------------------------------

# 1ヶ月以上前のファイルは、各旬1の日を残して削除
echo -n "garbage db files over 1 month ago(exclude 01, 11, 21, 31). ... "
YMD=`date +%Y%m%d -d '1 months ago'`

for FILE_NAME in $DB_NAME-*.sql.bz2
do
  if [ $FILE_NAME '<' $DB_NAME-$YMD ];then
    TMP_DIR=`echo $FILE_NAME | cut -c 18`

    if [ $TMP_DIR '!=' 1 ];then
      /bin/rm $BACKUP_DIR/$FILE_NAME;
    fi
  fi
done
echo "done"

# 3ヶ月以上前のファイルは、毎月1日を残して削除
echo -n "garbage db files over 3 months ago(exclude 01 of every month). ... "
YMD=`date +%Y%m%d -d '3 months ago'`

for FILE_NAME in $DB_NAME-*.sql.bz2
do
  if [ $FILE_NAME '<' $DB_NAME-$YMD ];then
    TMP_DIR=`echo $FILE_NAME | cut -c 17-18`

    if [ $TMP_DIR '!=' 01 ];then
      /bin/rm $BACKUP_DIR/$FILE_NAME;
    fi
  fi
done
echo "done"

cd $here
echo "finish!"
exit 0

このシェルの「Configure」の部分をご自分の環境に合わせて書き換えて頂き、例えば「wp-backup.sh」とかなんとか名前をつけて、「/etc/cron.daily」の中に置いて下さい。(あ、シェルは実行権限持たせてね。)
これで1日1回自動的に実行されるでしょう。(多分。まだ初回が流れてないので分からんです(苦笑。

使って頂く方へご注意!

このシェルを置くディレクトリとバックファイルを置くディレクトリ(シェルの「BACKUP_DIR」で書いたディレクトリ)は、Webサーバの公開領域(このシェルの例だと「/var/www/httpdocs/」の下)に置いてはいけません。
Webサーバ越しに外部からデータ取り放題だからです。(当たり前か)

レンタルサーバの都合などで「どうしてもここに置かなきゃいけないのよ!」という方は、せめて.htaccessでアクセスをはじいて下さい。例えば環境が

  • シェルの名前 : 「/var/www/httpdocs/wp-backup.sh」
  • バックアップファイル保存先 : 「/var/www/httpdocs/wp-backup/blog-backup」

だとしたら、「/var/www/httpdocs/.htaccess」というファイルに、

RewriteEngine On
RewriteBase /

RewriteRule ^wp-backup.sh$ - [F]
RewriteRule ^wp-backup/(.*)$ - [F]

とでも書いておいて下さい。これで外部からアクセスしても「403:アクセス権限なし」で弾く事ができます。(ゴメンなさい、この部分テストしてないです。違ってたらどなたか突っ込んで下さい。)


コメントを残す