サーバーのファイルをZipに圧縮してダウンロードするCGI

ファーストサーバの障害を受けて、「自分のサイトのデータもバックアップしたい」という方は多いのではないでしょうか。
かといって、サーバー上の大量のファイルをFTPでダウンロードするには、気が遠くなるほどの時間がかかります。
そこで、サーバー上のファイルをZipに圧縮してダウンロードする単純なCGIを作ってみました。

1.注意事項

このCGIを使うにあたって、以下の点にご注意ください。
注意事項を守らなくて何かトラブルがあったとしても、当方では一切責任を負いません。

1-1.CGIのアップロード先

誰もがアクセスできるディレクトリにこのCGIをアップロードすると、Zipファイルを誰でもダウンロードできることになり、Webサーバーのファイルを盗まれることが起こりえます。
そうなると、パスワードが盗まれるなど、セキュリティ上のトラブルにつながります。
そこで、アップロード先のディレクトリにBasic認証を設定するなどして、他人にこのCGIにアクセスされないようにする必要があります。

1-2.事前のテスト

万が一の事態があるかも知れませんので、いきなりサーバーの全ファイルをバックアップしないでください。
テスト用のディレクトリを作ってそのディレクトリのバックアップを試すなど、十分にテストを行ってください。

2.CGIのダウンロードと書き換え

まず、以下のコードをコピーして、テキストエディタに貼り付けます。

#!/usr/bin/perl

my $dir = 'バックアップするディレクトリ';

use File::Temp qw( tempfile );
chdir $dir or die "Can't change directory";
my ($fh0, $backup) = tempfile(SUFFIX => '.zip');
close $fh0;
unlink $backup;
system "zip -r -q ${backup} *";
open my $fh, "<", $backup or die "Can't read zip file";
binmode $fh;
print "Content-Type: application/zip;\n";
print "Content-Disposition: attachment; filename=backup.zip\n\n";
while (read $fh, my $buf, 1048576) {
    print $buf;
}
close $fh;
unlink $backup;

1;

次に、「バックアップするディレクトリ」を、実際にバックアップするディレクトリに合わせて置き換えます。
ディレクトリはフルパスで書きます。
例えば、「/var/data/www」ディレクトリをバックアップしたい場合だと、3行目を以下のように書き換えます。

my $dir = '/var/data/www';

3.CGIのアップロード

出来上がったCGIに「backup.cgi」等のファイル名を付けて保存し、Webサーバーにアップロードします。
また、ファイルのパーミッションを705等に設定して、実行可能にします。

4.Zipファイルのダウンロード

WebブラウザでCGIにアクセスすると、サーバー上でバックアップが行われ、しばらくしたのちに自動的にZipファイルのダウンロードが始まります。

なお、バックアップにはそれなりの時間がかかります。
レンタルサーバーによっては、CGIの実行時間制限によって、ダウンロードされずにエラーが発生することもあります。
残念ながら、そのようなサーバーではこのCGIを使うことはできません。

ちなみに、当方のローカルサーバーで、ファイル容量約130MBのディレクトリに対して、このCGIを実行してみました。
すると、ダウンロードが始まるまでに約15秒かかりました。

また、サーバーにzipコマンドがインストールされていることも必要です。
インストールされていない場合は、このCGIを使うことはできません。

5.データベースもバックアップする必要がある

現在では、Movable TypeやWordPressどのCMSを使って管理しているサイトも多いと思います。
そのようなサイトの場合、ファイルをバックアップするだけではだめで、データベースも別途バックアップする必要があります。

MySQLの場合だと、phpMyAdminでバックアップするのが比較的簡単です。
phpMyAdminでバックアップする方法は、あちこちのWebページで解説されていますので、そちらを参照してみてください。