九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、これは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=*********************
アクセスキー&秘密キーを取得する
続いて、Laravel
がS3
にアクセスするために必要なキーを取得します。
「サービス > 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
を設定します。
※ただし、cron
はLinux
サーバーのタイマー実行機能ですので、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
で作成したサイトをできるだけ労力を使わずにバックアップする方法をご紹介しました。(・・・とはいえ、やることは多かったですが😂)
最近はレンタルサーバーであっても万が一のためにバックアップできるサービスがついているところもありますし、サーバー自体のファイルやデータがなくなってしまったという話はあまり聞きませんが、二度と取り戻せないものは、運用中のサーバーに加えて、AWS
やGCP
(Googleのクラウド)などにも保存しておくことをおすめします。
ぜひ皆さんも挑戦してみてくださいね。
ではでは〜❗
「何回停車してもカレーの匂いがするので、
てっきり激戦区かと思ったら、
ウーバー・イーツが並走してただけでした😂」