GattsCOM

ブログ

BLOG

  1. Home
  2. Blog

Laravelで簡単にバックアップしてCronで別サーバーへFTP転送までを自動化してみた

久しぶりの投稿です。

12月は忙しく、事務所の移転もしたりとバタバタでした。

回線の移動が、ビビりまくりでしたねぇ!!

と言うことで、本題に戻しますw

今までCronを使ってシェルなどを動かしてバックアップを取っていたのですが

Laravelには凄く便利なバックアップ方法がありましたので、そちらを共有したいと思います!!

//SSHで下記実行(Laravelのルートへ移動して実行してくださいね)
composer require "spatie/laravel-backup:5.*"

spatie/laravel-backup:5.* ← 5.*はLarave V5系ならこれ。

Laravel 6系なら
spatie/laravel-backup:5.* → spatie/laravel-backupとしてください。

実行したら、だらだら〜とインストールが始まってPackage manifest generated successfully.って出たら完了です

次に

//同じくSSHのLaravelルートで実行してください。
php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"

とすると、configディレクトリにbackup.phpが生成されます。

こちらは、特に触らなくても問題ないです。一応実行だけしときます。

このファイルはバックアップの場所とか色々設定ができます。


ここまでしたら、一旦完了です!!すげー!簡単だ!!

//実際に動くのか確認しましょう!!!(Laravelルートで行ってね!!!)
php artisan backup:run

たぶん色々とエラーは出ると思いますが、実行はされてるはずです。

エラーが出る人は
php artisan backup:run --disable-notifications

こちらで実行してみてください。


実行結果は、/Laravel_Root/storage/Laravel/の中にzipファイルが出来上がります。

このzipファイルの中に、LaravelのソースコードとDatabaseのdumpデータが入っています。

もし、zipのパッケージが入ってない人はパッケージをインストールしてください。
インストール方法は

//zipのインストール
yum -y install --enablerepo=remi-php71 php-pecl-zip

zipをインストールしたら、もう一度

php artisan backup:run

を実行してみてください。

/Laravel_Root/storage/Laravel/ の中にzipファイルができましたか??

出来てない人は、チャットなどで問合せてくださいw
時間を見て順次返答してみます。

ここまでで、一旦サーバーにバックアップを創ることが出来たと思います。

ですが、サーバーにバックアップを取っても、サーバーがぶっ飛んだら意味がない!!!

と言うことで、弊社は別のサーバーをバックアップに立てて、そちらにバックアップデータを入れています。

この場合はFTPやSFTPとかでアップしてるので(scpとか使わないの?とか言わないでくださいね。)

先にそちらの話しをしてみましょう!!!

LaravelにはStorageクラスというものがあり、こちらが非常に便利です!!!

まずは、config/filesystem.phpを開いてみましょう!!

//config/filesystem.phpの中身(一部)

'disks' => [

        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
        ],

        'public' => [
            'driver' => 'local',
            'root' => storage_path('app/public'),
            'url' => env('APP_URL').'/storage',
            'visibility' => 'public',
        ],

        's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
        ],
	
	//↓こちらを追加してください。
	'ftp' => [
		'driver'   => 'ftp',
		'host'     => 'hostname or IPアドレス',
		'username' => 'FTPユーザー名',
		'password' => 'FTPパスワード',
	],

    ],

今回はFTPとしていますが、SFTPなどもいけますし
見てわかるように、s3などへも簡単に出来ますよ。

https://readouble.com/laravel/5.5/ja/filesystem.html

こちらを参考にしてもらったら、Storageクラスがある程度わかると思います。
細かくポートやパッシブモードなども設定できます。

次に、転送させる為のコードを書くのですが

Storage::disk('ftp')->put('保存するファイル名', '保存する中身');

このコードを実行すると、自動的にconfig/filesystem.phpで設定した、FTPへファイルを作ります。

なんとたったの1行!!すげー!

さて、ここまでで、バックアップファイルの生成からFTPへ転送までが完了しました

ここから、それじゃーバックアップしたデータを自動的にFTPへ転送してぇ〜よ!ってところで

ここで登場するのが、Cronです。

Cronはサーバーで指定した時間に自動的に実行してくれる便利な機能です。

Cronの設定は、各々扱うユーザーなどが違うかもなので、私の設定で書きます。

まずはSSHで書かないといけないので、順に説明しながら書いていきます。

//SSHでディレクトリを移動してください。
cd /etc

//etcの中にあるcrontabと言うファイルを開きます。
vim crontab

//そうすると、中身が出てきます。
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

急に英語でてきて、わかんねぇ!!って言わないでくださいねw

とりあえず、少し話しは脱線しますが、Cronの説明をしていきます。

* * * * * ← 5つの*がありますが、こちら、英語の説明を簡単に訳すと

1つ目の* 分 (0〜59)
2つ目の* 時間 (0〜23)
3つ目の* 日 (1〜31)
4つ目の* 月 (1〜12) (数字じゃなくて、jan,feb,mar,apr ...みたいに書いてもいいよ!)
5つ目の* 週 (0〜6) (0:日曜、1:月曜、2:火曜、3:水曜、4:木曜、5:金曜、6:土曜) 数字じゃなくても(sun,mon,tue,wed,thu,fri,sat みたいに書いてもいいよ!)

という風になっています。

例題をいくつか作ってみましょう。

毎日朝4時30分に実行したい場合は
30 4 * * * となります。

毎週月曜日の朝4時30分に実行する場合は
30 4 * * 1となります。

毎月1日の朝4時30分に実行する場合は
30 4 1 * *となります。

だいたい、わかりましたか?


それでは、これで話しを本題に戻しましょう。

次に、Laravel側の設定をしないといけません。

/Laravel_Root/app/Console/Karnel.php
のファイルを開きます。

// Laravel_Root/app/Console/Karnel.phpの中(一部)

protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        //          ->hourly();
    }

このようになっていると思います。

こちらのschedule関数の中を少し触ります。

protected function schedule(Schedule $schedule)
    {
		//ソース:DBまるごとバックアップするコマンド
		$schedule->command('backup:clean'); //←追加
		$schedule->command('backup:run'); //←追加

        // $schedule->command('inspire')
        //          ->hourly();
    }

このように、登録することで、SSHからartisanコマンドで、このschedule関数を呼び出すことが出来ます。

実際にやってみましょう!

//SSHで下記実行してみましょう。(Laravelルートでやってくださいね)
php artisan schedule:run

↑さっきは php artisan backup:runでしたが、今回はschedule:runです。

schedule関数を呼び出しています。

これをすることで、先程 /Laravel_Root/app/Console/Karnel.phpで書かれたschedule関数が動きます。

スケジュール関数には
$schedule->command('backup:clean'); //←追加
$schedule->command('backup:run'); //←追加

この2つを登録したので、まずは古いバックアップをクリーンにしてから、新しいバックアップを創る処理をしていますね。
なので、schedule:runをしたらこちらが動きます。

ほんとにわかりやすいですね〜(^o^)v

続いて、この中に(不細工なやり方ではありますが....)scheduleのcall関数を使って、このままFTPへ転送の処理も書いちゃおう!

$schedule->command('backup:clean');
$schedule->command('backup:run');

//↓を更に追加しますよ
//バックアップファイル転送処理
$schedule->call(function(){
	$files = Storage::files('Laravel');

	//バックアップファイルがあれば転送
	if(count($files)){
		Storage::disk('ftp')->put('BKUP/'.date('Ymd_His').'_bkup.zip', Storage::get($files[0]));
	}
});

これで、SSHからphp artisan schedule:runを動かすと

1:古いバックアップデータをクリーンする。
2:新しいバックアップを作成する。(zipの中身は、Laravelのソース+Sqlのdumpデータ)
3:ファイルが出来たら、自動的に別で用意してるFTPへ転送する。

という所が出来ました。

ここまで来たら、あとはCronで設定するだけですね。

//SSHでCronを設定する。
cd /etc

vim crontab

//Crontabで毎日朝4時30分に、schedule:runして!
30 4 * * * cd /Laravel_Root/Laravel Project && php artisan schedule:run >> /dev/null 2>&1

//↑Crontabを保存して↓をSSHで実行してください。
crontab crontab

あとは、朝4時30分になると、Cronが自動的に処理してくれます。


ここまでで、Laravelの公式にも書かれているspatieを使って、Laravelのソースコードやデータベースのバックアップを取って
それを自動的にzipファイルにしてくれて、そのzipをまるごとFTPへ転送!!なんとCronも使って全自動!

ってことで、かなり長くなりましたが、これで出来ると思います。

余談を書くと、zipファイルが残るようであればサーバー内の容量が食われるので
FTPの転送が終われば、Storage::deleteを使ってファイルの削除をしてたほうが良いかも知れませんね。

それでは、長々となりましたが、最後まで読んでいただきありがとうございました〜

ちょくちょく更新がんばります〜m(_ _)m