Cronを使ってWEBサイトのデータをバックアップする(CentOSとsh)

Cronを使ってWEBサイトのデータをバックアップする(CentOSとsh)

WEBサイトのデータをバックアップしておかないといけないな。と思っていても、FTP接続でディレクトリを同期させるのも1つのサイトだけ運営していれば手間は少ないですが、複数のサイトを運営していると面倒になってきます。

それに、最近はSFTP経由でサーバー内のファイルを直接変更できる環境が整ってきたので、自宅だけでなく職場だったり、iPad経由でちょっとした修正ができるようにもなってきており、すっごく便利すぎてローカルにファイルを落とすのは書き戻し用として保存している程度になってきています。

それでも、ローカル側にはバックアップを置いておくべきことには変わりありません
そこで、シェルスクリプトをCronで定期実行させて1ヶ月に1回程度はサイト用のファイルとデータベースのバックアップをとっておこうと考えました。


最初に決まりごととして、

  • サイトデータはサイトごとにZIP化してパスワードをかける
  • DBのDUMPファイルもZIP化してパスワードをかける
  • 3ヶ月以上前のバックアップデータは削除する

ファイルをバックアップしていく上で最低限抑えていきたいところは、漏れたら困るファイルを含んでいる場合は必ずパスワードをかけること
htmlファイルのみだけならそのまんまZIP化してもいいとは思いますが、人には見せたくない情報がある場合は気をつけましょう


それではシェルスクリプトを作っていきます
WebBK.shというファイルで作ってみます。

1行目に

を書きます
これは、シバン(シェバン)というスクリプトを読み込むインタプリタを指定します。
『このファイルはbashで動くスクリプトだから、bashを使って書いてある通りに実行しなさいよ』なんて感じの宣言みたいなもんです

次に、バックアップを実行させる日付の指定と、スクリプトが実施された日付を求めまた上で処理を実行するかの判断をさせます

とりあえずこれだけ書いて試してみましょう。
シバン部分と続けて書くと

試した日が1日ならば『処理を実行します』とでますが、1日以外ならば『処理は実行しません』とでているはずです
結果が『処理は実行しません』とでたならば、処理を実行させる日付のActionDayの設定を現在の日付に変更して再度試してみてください

『処理を実行します』という表示がでたならば、次は処理自体を設定していきます
マンスリーで処理をさせたいので、保存するフォルダ名、ファイル名は実施をした年月をつけます

バックアップしたファイルはどこに保存しておいてもいいですが、ローカルに保存する場合の利便性を考えるとSFTP接続ができるフォルダ内に保存しておいた方が便利ですが、セキュリティを考慮すると普通は外部からアクセスできないフォルダ内に置いておいて、ローカル保存したいときにファイルを一旦移動させるということが望ましいです

今回は/var/www/html/内にBackUpというフォルダが存在してその中でバックアップ作業を実施するという流れにしています
BackUp内に実施年月のフォルダを作成し、そこが保存場所になるという設定です

これでバックアップファイルが保存されるフォルダが出来上がりました。
場所を変えたいのであれば作業フォルダへの記述を変更すればOKです

続いてZIP化していく作業です
2つのサイトを持っている(SiteNameAとSiteNameB)と仮定します

zipコマンドに -P をつけるとパスワードをつけることができますが、平文でシェルスクリプトに埋め込んでいますのでシェルスクリプト自体を外部からアクセスできる位置に保存するのは危険です。
-rを付けるとフォルダを丸ごと対象と出来ます

今回設定したzipコマンドの内容は下記になっています

zip -P 設定したいパスワード -r(フォルダ丸ごと) ZIP化した後のファイル名 ZIP化したいファイルが保存されている場所

3行目でSiteNameBというサイトに対してもzip化しているのですが、SiteNameBは画像サイトになっており数千点の画像ファイルが保存さています。画像ファイル自体はローカルにもあるので画像ファイルに関してはバックアップは不要と考えて拡張子単位でファイルを除外したうえでzip化しているという記述になっています。

ZIP化した後のファイル名には実施年月をファイル名の頭に入れることで、保存フォルダから個別にダウンロードしてもいつの分か判別できるようにしています

特定のフォルダだけファイルを除外したい場合

これだとサイト全体の画像ファイルを除外してしまいます。
『img』フォルダだけの画像フォルダを除外したい場合には

こんな設定もできます

次はMySQLデータのバックアップです
mysqldumpコマンドで実施します。

こちらもパスワードを平文で保存していますので取扱注意です
ファイル名には同じように実施年月を入れるようにしています。どうせ削除してしまうので日付を入れなくてもいいですけど・・・
MySQLでのデータを丸ごとダンプしてもいいのですが1つのファイルが重くなるのは必要な情報を取り出しにくくもなるのでダンプデータに関してはデータベース個別に出力するようにしています

WEBサイトのファイルをバックアップするときと同じように個別でZIP化していってもいいですが、DBデータの容量が少なければファイル数が多くなってしまうので、DBのダンプデータに関しては丸ごとZIP化するようにしています

ZIP化が終われば元のsqlファイルを削除します。

2014年09月01日にバックアップ作業が実施されたとすると
/var/www/html/BackUp には

201409 というフォルダと
ZIP化された下記のファイルが存在します

・201409.SiteNameA.zip
・201409.SiteNameB.zip
・201409.DUMP.zip

ZIP化処理が終わったので、実施年月のフォルダである【201409】へ移動させます

これでバックアップの一連の作業は終わりました


が、延々と続けているとバックアップファイルがHDDの容量を圧迫してくることになります
使わないバックアップファイルのせいでサーバーがパンクしたなんて笑えません

そこで、90日以上経過しているデータは消すように設定します

findコマンドで 2から始まるフォルダで最終更新日から90日以上経過しているものだけを検索して、それをフォルダごと削除する
既に作業用フォルダ内で作業を実施しているのでfindの後のフォルダ指定は必要ありませんが、削除コマンド(rm)を実施しているので誤ったフォルダで動作するのを防ぐためにパスをベタ書きしています


ここまでの流れをまとめると下記のようになります

このファイルを外部からアクセスされない場所に保存します
シェルスクリプトのファイルに実行権限を与えておきましょう

Cronの設定を行います

毎月1日のAM5:30に実施にすると設定するならば

但し、WebBK.shに設定したActionDayと同じでないといけません。気をつけてください。
指定日にしか反応しないスクリプトなので毎日動かしていてもいいので

これなら毎日AM5:30にスクリプトが動き出して設定された指定日にバックアップが実施されます


【Cronが正常に動かなかったら】
単体でシェルスクリプトを動作させると正常にバックアップしてくれるのに、Cronだと動かない・・・
そんな時はCronの動作ログをとればいいのです

bkcron.logには正常ログ
bkcron-err.logにはエラーログが蓄積されます

これで毎月決まった日付にバックアップデータが作成されます
ローカルに保存するのは忘れないようにしないといけませんけどね