Laravelをバックアップ!定期的にDBやファイルをAWSへ保存する

こんにちは❗フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、これはLaravelだけに限りませんがサイトやシステムをつくっても、それで全て終わりというわけではなく、そこから拡張や不具合の修正などが必要になることが多いです。

そして、そんなサイト公開後にとても重要になってくる機能があります。

それが・・・・・・

バックアップ機能

です。

ソースコードはgitなどでバージョン管理することがほとんどなので、なくなったからといってそれほど焦りはしませんが、特にユーザーさんがアップロードした画像などのファイルや、DBデータは一度なくなってしまえば復活させることは難しいと言わざるをえません。

そこで❗

今回はLaravelを使って運営しているサイトの「DBデータ」と「ファイル」を自動でAWS(S3)にバックアップできる機能を作ってみます。(しかも定期的に自動実行できるようにします👍)

ぜひ皆さんのお役に立てましたら嬉しいです😊✨

「10月になると、ビールの税金が
安くなるらしいですねっ🍻✨」

 

環境: Laravel 8.x(6.xや7.xでもほぼ同じです)

作業に入る前に: 「AWS」「S3」とは

簡単にいうと、AWSとは大手ショッピングサイトAmazonが提供するクラウドサービス(インターネット上でいろんなことができるサービス)のことで、S3(えすすりー)はその内のひとつです。

そして、S3はファイルを保存しておくことができるサービスで、主にバックアップしたファイルを別管理するために保存しておいたり、サーバーのディスク容量が足りない場合や、負荷を軽減したい場合などに利用されます。

AWSで準備をする

まずAWSに登録してログインしておいてください。

バケット(保存領域)をつくる

ログインしたら「サービス > S3」へ移動します。

すると、以下のような表示になりますので「バケットを作成する」ボタンをクリックします。

クリックすると、ポップアップが表示されるので、バケット名を入力してください。

※ちなみにこのバケット名は他の人が使っていない文字列である必要があります。また、このバケット名は、後で.envに登録することになります。
※今回、リージョン(データセンターの場所)は東京で実装します。

続いていくつか選択する項目がありますが、今回はデフォルトのまま進めます。
そして、最後に「バケットを作成」ボタンをクリックします。

これでバケットが作成され以下のように一覧に表示されることになります。

では、リージョンとバケット名を.envに登録しておきましょう。

.env

AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=*********************

アクセスキー&秘密キーを取得する

続いて、LaravelS3にアクセスするために必要なキーを取得します。

サービス > IAM」へ移動してください。

ページ移動したら、メニューにある「ユーザー」をクリック。

ユーザーを追加」ボタンをクリック。

すると、ユーザー情報のフォームが表示されるので、「ユーザー名」を入力し、「プログラムによるアクセス」にチェックを入れます。

次のステップ:アクセス権限」ボタンをクリックして次へ移動します。

すると追加するグループが選択できるようになりますので、S3にチェックを入れます。

「次のステップ:タグ」ボタンをクリックします。

タグは初期状態のまま「次のステップ:確認」ボタンをクリック。(お好みでOKです)

最後に「ユーザーの作成」ボタンをクリックすればユーザーが新規追加されます。

ユーザーが追加されると以下のように一覧に表示されますので、「アクセスキーID」と「シークレットアクセスキー」を取得して.envへ登録しておきましょう。

.env

AWS_ACCESS_KEY_ID=********************
AWS_SECRET_ACCESS_KEY=***************************

これでAWSでの作業は完了です。

パッケージをインストールする

ここからはLaravel側での作業になります。

Laravelをバックアップするパッケージをインストールする

LaravelのファイルやDBデータをバックアップしてファイル化するパッケージをインストールします。

以下のコマンドを実行してください。

composer require spatie/laravel-backup

ストレージパッケージをインストールする

次に、S3へ簡単にアップロードできるようになるパッケージをインストールします。

以下のコマンドを実行してください。

composer require league/flysystem-aws-s3-v3

ちなみに、これで以下のようにするだけでAWSへファイルをアップロードできるようになります。

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// 省略

$path = public_path('text/test.txt');
$filename = now()->format('Ymd_His') .'_test.txt';
Storage::disk('s3')->putFileAs('/', new File($path), $filename);

実行するとS3に次のように反映されます。

これでバックアップ機能が有効になっています😊

実行方法は、以下のコマンドを実行するだけです。

php artisan backup:run

ちなみに:特定のフォルダだけ指定する方法

パッケージspatie/laravel-backupは、初期状態では「vendor」と「node_modules」フォルダ以外は全てのファイルをバックアップするようになっています。

ただ、正直なところソースコード自体はgitで管理することが多いと思いますので、毎回バックアップを続けてしまうと不要な容量に予算を使うことになってしまいます。

そのため、以下のようにすることで、例えば「アップロードされた画像だけ」とか「自動生成されたPDFだけ」をバックアップすることができるようになります。

では、今回はアップロードされたプロフィール画像(+DB)だけをバックアップする方法をご紹介します。

まずは、以下のコマンドを実行してパッケージから設定ファイルをLaravel側にコピーします。

php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider"

すると、ファイルが作成されるので以下のように変更してください。

config/backup.php

<?php

return [

    'backup' => [

        // 省略

        'source' => [

            'files' => [

                'include' => [
//                    base_path(), // 👈 コメントアウトしました
                    storage_path('app/public/profile-photos') // 👈 ここを追加しました
                ],

また、初期状態では「/storage/app/****」にバックアップが保存されますが、今回はS3へアップロードしますので、同じファイルの中にある「disks」も変更しておいてください。

'destination' => [

    // 省略

    'disks' => [
        // 'local',
        's3'
    ],
],

※なお、localはコメントアウトしていますが、もしローカルとS3の両方にバックアップしたい場合は2つとも残しておいてください。

これでphp artisan backup:runを実行すると自動的にファイルとDBデータがzipファイル化され、さらにS3にアップロードまでしてくれるようになります。

定期的に実行できるようにする

では、バックアップが定期的に自動実行できるようにcronを設定します。

※ただし、cronLinuxサーバーのタイマー実行機能ですので、widowsではTask Schedulerなどを使ってください。また、私の環境はUbuntuですので、別のOSの場合は適宜変更してください。(基本的には同じだと思います)

まず、PHPの場所を特定するために以下のコマンドを実行します。

which php

すると以下のように表示されますのでこれを覚えておいてください。

/usr/bin/php

そして、Laravelがインストールされている絶対パスを取得します。(分かっている方は不要です)

Laravelをインストールしたフォルダに移動して以下のコマンドを実行します。

pwd

実行すると、絶対パスが取得できるので覚えておいてください。

/home/*****/php-dev/laravel8x

ではcronの編集です。
以下のコマンドを実行してください。

sudo crontab -e

するとエディタが起動されるので、以下の行を追加して保存してください。

35 * * * * /usr/bin/php /home/*****/php-dev/laravel8x/artisan backup:run

※ちなみに、この例は毎時35分に実行される書き方です。

ちなみに – その1:「Sending notification failed」というエラーが出たら

初期状態では、php artisan backup:runを実行すると以下のようなエラーが表示されます。

Sending notification failed

これは、「通知ができませんでした」という意味になります。もし、通知が必要ない場合は以下のように--disable-notificationsオプションをつけるといいでしょう。

php artisan backup:run --disable-notifications

ちなみに – その2: バックアップされたらメール送信で通知する

実は、設定ファイルには通知用のメールアドレスを指定する場所があるのでここを変更してください。

config/backup.php

'notifications' => [

    // 省略

    'mail' => [
        // 👇 ここが通知先のメールアドレス
        'to' => 'your@example.com',

        // 👇 ここが送信元の情報になります
        'from' => [
            'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
            'name' => env('MAIL_FROM_NAME', 'Example'),
        ],
    ],

なお、お好みでSlackの方へも通知できますよ👍

ちなみに – その3:S3の保存ファイルを一定期間で削除する

これはお好みですが、サイトの運用期間が長くなってくるとバックアップのファイルも無数に増えていくことになります。

無数に増えていくということは、費用もかさんでしまう、ということなのでS3では自動的にある一定期間が過ぎると自動でファイルを削除する設定があります。

ここでは、その設定方法をご紹介します。

まず、バケットのページで「管理 > ライフサイクル > ライフサイクルルールの追加」をクリックしていきます。

すると設定を入力するポップアップが表示されるので、以下のようにお好みで指定します。

次の「ストレージクラスの移行」もお好みですが、今回は何もせず「次へ」ボタンをクリックしました。

では、削除するまでの日数を指定します。

確認のチェックを入れて保存すれば完了です。

テストしてしてみる

では、先ほどのcronを実際に保存して時間になるのを待ち、AWSにバックアップ・ファイルがアップロードされるかをテストしてみます。

(待つ・・・・・)

(待つ・・・・・・・・)

(待つ・・・・・・・・・・・時間です👍)

ではAWSをチェックしてみましょう。

はい❗

うまくAWSの方へ自動でバックアップ・ファイルが保存されました。

そして、メール通知も有効にしておきましたのでこちらも確認しておきましょう。

成功です😊✨

※なお、日本語化データのプルリクエストを送ったら、たった2時間ほどでマージしていただけました。Thank you, freekmurze!

おわりに

ということで、今回はLaravelで作成したサイトをできるだけ労力を使わずにバックアップする方法をご紹介しました。(・・・とはいえ、やることは多かったですが😂)

最近はレンタルサーバーであっても万が一のためにバックアップできるサービスがついているところもありますし、サーバー自体のファイルやデータがなくなってしまったという話はあまり聞きませんが、二度と取り戻せないものは、運用中のサーバーに加えて、AWSGCP(Googleのクラウド)などにも保存しておくことをおすめします。

ぜひ皆さんも挑戦してみてくださいね。

ではでは〜❗

「何回停車してもカレーの匂いがするので、
てっきり激戦区かと思ったら、
ウーバー・イーツが並走してただけでした😂」

開発のご依頼お待ちしております 😊✨
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします!
このエントリーをはてなブックマークに追加       follow us in feedly  

開発効率を上げるための機材・まとめ