3か月ほどRaspberryPiでWordPressサーバを稼働させていて、未だにバックアップを取っていなかったので、バックアップを行います。WordPressのバックアップを行うプラグインも多々あるようですが、勉強のためシェルスクリプト(bashスクリプト)で作ってみました。
バックアップは、mysqlのダンプをmysqldumpで、WordPressのコンテンツをtarで取得して、圧縮して保存、さらに世代管理します。
同じシェルでリストアを行なえるよう、オプションで機能を選択できるようにしています。ログはloggerコマンドを使って、rsyslogに出力します。
シェルスクリプト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
#!/bin/bash # Fixed appname="wp_backup.sh" flag_b="Backup" flag_r="Restore" dumpfile="mysql.dump.gz" wpfile="wordpress_files.tar.gz" # Command mysql="/usr/bin/mysql" mysqldump="/usr/bin/mysqldump" mysqladmin="/usr/bin/mysqladmin" tar="/bin/tar" mkdir="/bin/mkdir" cp="/bin/cp" rm="/bin/rm" zcat="/bin/zcat" id="/usr/bin/id" logger_i="/usr/bin/logger -ip local0.info" logger_e="/usr/bin/logger -ip local0.error" # Setting wp_dir="/var/www/html/" bak_dir="/var/bak/" arc_dir="${bak_dir}archives/" day_dir="${arc_dir}`date +%Y%m%d`/" sav_dir="${bak_dir}save/" dbuser="root" dbpass="*********" dbname="wordpress" age=10 # Function Options mistake function usage_exit(){ cat << _EOS_ Usage: ${appname} [-br] -b or Nothing -> Backup execution -r -> Restore execution _EOS_ exit 1 } # Function Error exit function error_exit(){ echo "Exit the ${appname}" 2>&1 exit 1 } # Function Failback function failback(){ echo "To return to the first state." 2>&1 ${cp} -fp ${sav_dir}*.gz ${bak_dir} 2>&1 error_exit } # Identify the options case ${1} in "-b") flag=${flag_b} ;; "-r") flag=${flag_r} ;; "") flag=${flag_b} ;; *) usage_exit ;; esac # Main { if [ `${id} -u` -gt 0 ] ; then echo "lack administrator authority." error_exit fi if [ ${flag} = ${flag_b} ] ; then #### Backup #### echo "Backup START" # Make Directory if [ ! -d ${bak_dir} ] ; then ${mkdir} ${bak_dir} [ $? -gt 0 ] && error_exit fi [ ! -d ${arc_dir} ] && ${mkdir} ${arc_dir} [ ! -d ${day_dir} ] && ${mkdir} ${day_dir} [ ! -d ${sav_dir} ] && ${mkdir} ${sav_dir} # Save the old file ${cp} -fp ${bak_dir}*.gz ${sav_dir} # Backup database ${mysqldump} -u${dbuser} -p"${dbpass}" -hlocalhost --add-drop-table --single-transaction -A | gzip > ${bak_dir}${dumpfile} [ ${PIPESTATUS[0]} -gt 0 ] && failback # Backup WordPress contents ${tar} -czf ${bak_dir}${wpfile} -C ${wp_dir} ./ [ $? -gt 0 ] && failback # Generation management [ ! -d ${day_dir} ] && ${mkdir} -p ${day_dir} ${cp} -pfu ${bak_dir}*.gz ${day_dir} cd ${arc_dir} ls -lt | awk '/^d/ {print $9}' | sed -n ${age}',$p' | xargs rm -rf echo "Backup END" exit 0 elif [ ${flag} = ${flag_r} ] ; then #### Restore #### echo "Restore START" # Error check [ ! -e ${bak_dir}${dumpfile} ] && echo "dumpfile does not exist." && error_exit [ ! -e ${bak_dir}${wpfile} ] && echo "wpfile does not exist." && error_exit [ ! -d ${wp_dir} ] && echo "wp_dir does not exist." && error_exit # Restore WordPress contents ${rm} -rf ${wp_dir}/* ${zcat} ${bak_dir}${dumpfile} | ${mysql} -u${dbuser} -p${dbpass} # Restore database ${tar} -xzf ${bak_dir}${wpfile} -C ${wp_dir} echo "Restore END" exit 0 fi } 1> >(${logger_i}) 2> >(${logger_e}) |
12行~23行(# Command)
コマンドの定義です。環境に合わせてコマンドをフルパスで設定します。
25行~36行(# Setting)
ディレクトリやデータベースの設定です。以下の変数を設定します。
wp_dir : WordPressのデータがあるディレクトリ
bak_dir: バックアップの保存先となるディレクトリ
dbuser : mysqlのrootユーザ
dbpass : mysqlのrootユーザパスワード
dbname : データベース名
age : 世代管理数
38行~46行 “usage_exit”
オプションが誤っていた場合の処理を行う関数です。コマンドの例を表示して終了します。
48行~52行 “error_exit”
エラーメッセージを表示して、戻り値1で終了します。
54行~59行 “failback”
エラー発生時にシェル実行前の状態に戻す関数です。
sav_dirに退避していた実行前のバックアップファイルを元の場所に戻します。
61行~67行
オプションの種類を識別します。
77行~106行
バックアップ処理です。
ディレクトリを作成した後、旧ファイルの退避、データベースのダンプ、WordPressファイルのアーカイブ、世代管理処理を行っています。
109行~126行
リストア処理です。必要なファイル・ディレクトリのチェックを行った後、WordPressファイルのリストア、データベースのリストアを行なっています。
128行
{}で囲まれたスクリプト内での標準出力、標準エラー出力を、loggerコマンドでrsyslogdに出力します。
バックアップの実行
バックアップする場合は、任意の場所にスクリプトを置いて、以下のコマンドを実行します。。
$ sudo ./wp_backup.sh -b
※ “-b” は省略可能です。
Ansible Playbookでセットアップ
上記シェルスクリプトでバックアップできますが、cronで定期的に稼働させたり、ログの書式や出力先の設定も行いたいので、AnsibleのPlaybookでセットアップします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
--- - hosts: <セットアップ対象ホスト名またはIPアドレス> sudo: yes vars_files: - vars/vars.yml tasks: - name: Copy the backup.sh copy: src=wp_backup.sh dest=/home/{{remote_user}}/ mode=0744 - name: Copy the rsyslog setting file copy: src=conf/wp_backup.rsyslog.conf dest=/etc/rsyslog.d/ - name: Reload rsyslog service: name=rsyslog state=restarted - name: Creates an cron entry cron: name="WordPress backup" minute="10" hour="3" weekday="1" user="root" job="/home/{{remote_user}}/wp_backup.sh -b > /dev/null" |
8行~9行
バックアップを行うスクリプト「wp_backup.sh 」を実行ユーザーのホームディレクトリに配置します。
11行~12行
rsyslogの設定ファイル「wp_backup.rsyslog.conf」をrsyslogの設定ディレクトリに配置します。
14行~15行
設定反映のため、rsyslogdを再起動します。
17行~18行
シェルスクリプトが毎週月曜、AM3:10に稼働するよう、rootユーザーのcron設定を行います。
rsyslog設定ファイルは以下の通り。
1 2 |
$template template_backuplog,"%timegenerated% %hostname% %programname%: \[%syslogpriority-text%\] %msg%\n" local0.* /var/log/backup;template_backuplog |
1行目
templateでログの書式を定義しています。
2行目
ユーザー定義のファシリティ「local0」でログを受信した際の、出力先ファイル名とテンプレートを指定します。
Ansibleサーバに上記ファイルを配置し、ansible-playbookコマンドを実行してセットアップします。
ansible-playbook wp_backup.sh_setup.yml -K
これで、毎週月曜、AM3:00にシェルスクリプトが稼働し、bak_dirで指定されたディレクトリにバックアップが取得され、10世代まで保存されるようになります。
Ansible Playbookでバックアップ
bak_dirをNFS領域にすれば他サーバへバックアップできますが、私の自宅には常時稼働している他のサーバはないので、週次バックアップとは別に以下のようなplaybookを随時実行して、Ansibleサーバにバックアップを取得しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
--- - hosts: <セットアップ対象ホスト名またはIPアドレス> sudo: yes vars_files: - vars/vars.yml tasks: - name: Install the sshpass apt: pkg=sshpass state=present - name: Run wp_backup.sh shell: /home/{{remote_user}}/wp_backup.sh -b removes="/home/{{remote_user}}/wp_backup.sh" - name: Get backup file shell: sshpass -p '{{local_user_pass}}' scp -o StrictHostKeyChecking=no /var/bak/*.gz {{local_user}}@{{local_address}}:/home/{{local_user}}/wp_bak/ removes="/var/bak/mysql.dump.gz" |
リストア
リストアしたい場合は、wp_backup.shのbak_dirに指定したディレクトリに、リストアしたいバージョンの”mysql.dump.gz”と”wordpress_files.tar.gz”を置いて、以下のコマンドを実行します。
$ sudo ./wp_backup.sh -r
※ “-b” は省略可能です。
リストアもplaybook化しましたが、ごくローカルな内容だったので割愛。