演習の対象を、復旧が必要なものから選ぶ

この演習では、Gitに保存したLaravelのコードと、実行に必要な依存ライブラリを新しいローカル作業先で起動します。本番の作業先には上書きしません。使うコミット、PHP・Composerの環境、確認するページ、保存データを使うかを先に決めます。

本番の.envをそのまま複製すると、本物のメールやAPIへ接続する可能性があります。演習用のAPP_KEY・APP_URL・セッション・キャッシュ・メール設定を使い、本番の宛先や秘密を参照しないことを確認します。DBやアップロードが必要なサイトでは、その匿名化・隔離が別途必要です。

サイトの構成で、バックアップ方法を選ぶ

自分のサイトに必要な対象を選びます。どの方法も、取得後の内容確認と隔離先での復元確認を組み合わせます。

サイトの構成保存するもの取得方法と注意点
HTML・CSS中心の静的サイト公開ファイル、画像、.htaccess等の設定。別のフォームや外部サービスはその管理情報も必要許可されたファイル転送やサーバーの取得機能で保存。手元の制作データと公開中の版が同じか確認する
WordPressなどDBを使うCMSファイル・テーマ・プラグイン・アップロードと、記事・設定の入ったDBファイルとDBを一組で取得。記事だけのエクスポートやpublic_htmlだけでは不足する場合がある
Laravelなど独自アプリソース、依存の固定情報、ビルド成果物、必要な設定・暗号鍵、DB・アップロードGitに入るものと別保管のものを照合。Gitのアーカイブだけで本番データや.envは戻らない

復旧対象を、コードと実行時の情報に分ける

evulixでは記事と画面のコード、画像、ビルド済みCSS・JSをGitで管理しています。一方、.env、依存ライブラリのvendor、セッション、ログ、アップロード領域は追跡対象から外れています。コードを戻せても、本番の設定やユーザーが追加したデータは同じ操作では戻りません。

まず自分のサイトでgit ls-filesを確認し、復旧に必要なものがどちら側にあるかを書き出します。秘密情報をGitへ追加して不足を埋めるのではなく、暗号化した別の保管場所とアクセス手順を用意します。記事がDBにあるサイトではDBのバックアップと復元確認も必要です。evulixのような設定ファイル型のサイトの結果を、DBを使うサイトへそのまま当てはめないでください。

ホームページのファイルとDBを保存する

保存する対象はサイトの作り方で変わります。構成別の表で必要な対象を確認してから取得します。

  1. ファイルを別の保存先へダウンロードする

    ホスティングのバックアップ取得機能や、契約で許可されたSFTP等を使い、公開ファイルと画像・アップロードを保存します。.htaccessなどの隠しファイルや、公開領域外にある必要な設定も一覧と照合します。

  2. DBを使うサイトはDBも書き出す

    WordPressなどでは、ファイルだけで記事や設定をすべて戻せません。管理画面やDB管理ツールのバックアップ機能で対象DBをエクスポートし、ファイルと取得日時を対応づけます。ツールの「記事エクスポート」だけをサイト全体のバックアップにしません。

  3. 更新中のデータを揃える

    取得中に画像や記事が更新されると、ファイルとDBの時点がずれることがあります。更新を止める時間を決めるか、利用環境の整合性を保つバックアップ機能を使います。停止できないサイトはDB管理担当と方法を決めます。

  4. 取得したファイルを開けるか確認する

    アーカイブが展開でき、必要なファイルとDBの書き出しがあるか確認します。取得日、対象ドメイン、保存範囲、復元方法を同じ控えに残します。秘密を含む設定やDBはアクセスを制限し、公開フォルダや公開Gitへ置かないでください。

取得できたことと、復元して使えることは別です。サーバー内だけに保存せず、必要な人が取り出せる別の保管先も用意します。頻度は更新量と失ってよい期間から決め、重要な変更前にも取得します。

手順の参照:WordPress公式:ファイルとDBのバックアップ(英語)(別タブ)。に資料を確認しました。

エックスサーバーの自動バックアップを取得する

自動バックアップの取得と、稼働中の領域へ戻す復元は別の操作です。ここでは取得側の手順を説明します。

  1. 取得する日付と範囲を選ぶ

    サーバーパネルの「自動バックアップデータ取得・復元」から「自動バックアップデータの取得」を選びます。対象日とドメインを確認し、Web領域と必要なWeb用設定ファイルを選びます。保持日数は使用中のサーバーの表示で確認します。

  2. 取得を実行し、保存先からダウンロードする

    容量と注意事項を確認して取得を実行します。取得されたデータはサーバーの/userbackupに置かれるため、管理者がアクセスできるファイル転送手段で別の保管先へダウンロードします。取得データは24時間後に削除され、再取得で古い取得データも削除されるため、完了後に取り出します。

  3. MySQLはDB側のバックアップを取得する

    MySQLを使う場合は、Web領域の取得だけで完了にしません。「MySQLバックアップ」の「手動バックアップ」で対象DBと圧縮形式を選び、「ダウンロードする」で取得します。過去の日付を復元したい場合は、その日付のDBバックアップを別に確認します。

  4. 本番へ戻す前に、内容と復元先を照合する

    WebとDBの取得日時・対象を揃え、新しい隔離先で必要な内容を確認します。本番側の「復元」は対象領域を上書きし、バックアップ日以降のファイルが削除される場合があります。取得の確認だけのつもりで実行しないでください。

サーバーパネルからの取得・復元は、このサイトの実測として掲載していません。画面と利用条件は公式資料で確認してください。次のGit演習は、これとは別の保存元からコードを戻した記録です。

手順の参照:エックスサーバー:自動バックアップからのデータ取得(別タブ)。に資料を確認しました。

ソースを取り出してから、画面が動くまで
  1. Gitの追跡ファイルを新しい場所へ展開1501950:162ファイルのSHA-256一致
  2. PHP・依存・演習用の設定を準備本番とは別のキー・arrayメールで隔離
  3. publicを入口にして起動・応答を確認24ページ・配信ファイル・フォーム往復・404を確認

2026年10月6日の隔離演習の工程を整理した説明図です。初回は起動先を誤り修正しました。本番DB・アップロード・SMTP配送・DNS・サーバー全体の復旧は対象外です。

本番を触らず、新しい場所へ展開する

最初の演習ではコミット315ba5dをgit archiveでZIP化し、新しい一時フォルダへ展開して152ファイルを照合しました。その後、起動まで確認する追加演習では1501950を使い、162ファイルのSHA-256が一致しました。数が増えたのは改稿や検証用ファイルを追加したためです。記録には数だけでなく元の版も残します。

どちらも展開直後のフォルダに.envとvendorはありませんでした。追跡していない情報が含まれないという結果です。 また、.gitattributesのexport-ignoreが指定されたファイルは、追跡されていてもgit archiveの対象から外れます。git ls-filesの一覧だけで必要なものが揃うと判断せず、展開後の内容を対象コミットと除外条件に照らして確認します。既存の作業フォルダは上書きせず、次の工程でも本番の秘密情報をコピーしません。下は自分のリポジトリで追跡対象とアーカイブを調べるコマンド例です。

追跡対象とアーカイブを確認する(説明用)
git ls-files
git rev-parse HEAD
git archive --format=zip -o ../source-snapshot.zip HEAD
# 新しい空フォルダへ展開して確認する。既存サイトには上書きしない。

今回のGit復元で戻ったもの・戻らないもの

追跡対象はプロジェクトごとに違います。自分のgit ls-filesとデータ保存先を確認します。

対象Gitスナップショット追加の準備
記事・コード・追跡画像照合一致使うコミットを記録
.env・秘密情報含まれない制限された別保管と復旧手順
vendor含まれないPHPとComposerで依存を復元
アップロード・DBサイトごとに別確認データ保存と復元演習

設定と依存ライブラリを別に準備する

evulixの実行にはPHP、Composerの依存ライブラリ、.envの設定、書き込み可能なstorageが必要です。復旧先でPHPの要件を確認し、composer.lockに沿って依存を復元します。 lockファイルがある場合のcomposer installは記録されたバージョンを使います。composer updateは依存を選び直してlockも更新するため、同じ版を戻す演習の代わりには使いません。APP_KEYなど継続性が必要な設定を失うと、既存の暗号化データを読めなくなることがあります。既存サイトの復旧で不用意に新しいキーを作らないでください。

追加演習ではPHP 8.5.1のWindows環境で、composer.lockに沿って開発用依存を除くライブラリをインストールしました。演習用に新しい.envとキーを作り、セッションとキャッシュはファイル、メールは外部へ配送しないarray方式に設定しました。この新しいキーは隔離演習専用です。本番で使っていた暗号化データを復旧する方法ではありません。

設定を用意した後、config・route・viewのキャッシュを作りました。本番と同じ宛先やAPIへ処理が流れないことを先に確認します。今回は記事を設定ファイルから読む構成なので、DB内のデータを復元・照合したとは扱いません。メール受信も、ローカルで送信処理が成功したこととは別の工程です。

起動の入口を直し、ページとフォームを確認する

初回は検証スクリプトの作業ディレクトリがプロジェクトのルートになっており、PHPの開発サーバーがpublicではない場所のindex.phpを探して失敗しました。サーバーのプロセスが起動しただけでは、Laravelが画面を返せるとは言えません。publicを作業・公開ディレクトリにする指定へ直して再確認しました。

修正後はサイトマップの24ページがHTTP 200で返り、各ページの見出しとローカルのcanonicalを確認しました。CSS・JS・検証画像も配信され、存在しないURLは404/noindexになりました。フォームはCSRFトークンとセッションを使い、対象URLを省いた入力から成功表示へ戻ることを確認しています。array方式なので実メールの配送は行っていません。

再確認は先にインストールした依存を再利用しています。その実行時間だけを、空の環境から復旧する所要時間としては使いません。本番のSMTP、DB、アップロード、DNS、Webサーバーの設定まで含めると、別の確認と時間が必要です。

隔離設定を用意した後の起動手順例(本番では実行しない)
composer install --no-dev --no-interaction --no-scripts --optimize-autoloader
php artisan package:discover
php artisan config:cache
php artisan route:cache
php artisan view:cache
# .envのAPP_URLもこのローカルURLに合わせる
cd public
php -S 127.0.0.1:8015 ../vendor/laravel/framework/src/Illuminate/Foundation/resources/server.php

戻せたもの、戻せないものを記録する

復元演習の記録には、元のバージョン、対象、保存場所、確認結果、不足した情報を書きます。「バックアップあり」とだけ残すと、次の担当者はどのファイルをどこへ戻すのか分かりません。復旧先で確認するURLと、フォーム送信を行う場合のテスト宛先も手順に含めます。

二つの配布表には同じ演習識別名・対象版・隔離先を記入します。不足表で全体の確認範囲を整理し、最初に止まった工程を一件ごとの詳細記録へ移します。残件識別名と保管先を両方に残すと、次の担当がどの失敗の記録か照合できます。ファイル同士は自動で同期されません。

更新頻度はデータの変化と許容できる損失で決めます。1日前の状態でよいコードと、直前までの注文が必要なDBでは同じ周期にできません。世代を残し、誤更新に気づくまでの時間も考えます。保存期限や保管先を変えたら、読み出す権限と復号手順まで再確認してください。

起動できない場合は、最初に失敗した工程へ戻る

ファイルが一致しなければ、元のコミットと展開先を確認します。依存のインストールで止まれば、PHPの要件とComposerのエラーを見ます。起動後の500はログを読み、設定、キャッシュ、権限を分けて調べます。最初に失敗した工程を直し、全部を一度にやり直さないようにします。

ページが表示されてもフォームだけ失敗するなら、入力処理の例外かメール処理の例外かをログで分けます。演習環境から本番SMTPへ接続して確認しようとせず、隔離したメール方式と設定を確認します。DBやアップロードを使う自分のサイトでは、その復元工程が残っていないかも点検してください。

再確認後は、実際に試した工程の結果・日時・根拠だけを不足表へ戻し、変更前の失敗は詳細記録に残します。原因として確認できたことと推測は分け、対象版や隔離先が変われば別の演習として記録します。CSSや起動が直っても、DB・アップロード・実メール配送まで成功としません。

10月7日にはコミット9ca9342を新しい一時フォルダへ展開し、3つの失敗を意図的に作りました。展開直後のvendor欠落、publicを指定せずルートから起動した入口の誤り、ビルド済みCSS一つの欠落です。依存は既存のローカルvendorを再利用し、ダミーのキー・設定とarrayメールを使いました。10月6日の依存インストールを含む演習とは別の記録です。

PHP 8.5.1でdisplay_errors=1だった今回の入口の失敗は、致命的なエラーが出てもHTTP 200でした。正しい入口に直した後も200ですが、こちらはページの本文と見出しが返りました。この差をHTTPコードだけで見分けることはできません。公開環境でエラー表示を有効にして調べるのではなく、管理者が確認できるログで切り分けます。

  1. 最初に止まった工程を一つ残す

    展開、依存、設定、起動、本文、CSS・画像、フォーム・データの順に、どこまで確認できたかを書きます。最初のエラー・時刻・対象だけを控え、秘密の設定値や個人情報は記録へ写しません。

  2. エラーが指すパスを、作業先と比べる

    vendor/autoload.phpなら依存の準備、index.phpなら起動の入口が確認先です。同じ文言でも原因を断定せず、どのフォルダのファイルを探したかを見ます。本番の公開先をルートへ移す方法で直そうとしないでください。

  3. 本文と配信ファイルの応答を別々に確認する

    ブラウザで期待した本文を開き、NetworkでCSS・JS・画像の取得先と応答を確認します。ページが200でもCSSが404なら、HTMLの参照とmanifest・公開先のファイルを比べます。

  4. 一つ直し、同じ条件で確認し直す

    修正した工程を同じURL・同じ起動条件で再確認します。依存やCSSを戻して起動できても、DB・アップロード・メール到達の未確認は残します。次の作業と担当を記入して引き継ぎます。

失敗した工程と、次に見る場所を対応づける

意図的に作った3つの失敗と修正の記録です。本番障害の記録ではありません。HTTPコードだけでなく、本文・ログ・配信ファイルを照合します。

観測したこと最初に確認する場所今回の修正・残る確認
artisanが終了255 / vendor/autoload.phpを開けない展開先とvendorの有無。依存の準備が完了したか演習では既存のローカルvendorを再利用して起動確認。新規インストールを確認した記録ではない
HTTP 200だが、本文がエラー / index.phpを開けない起動時の作業先、公開先、サーバーログの参照パスpublicを作業・公開先にして本文と見出しを確認。200だけで完了にしない
ページ200 / 指定されたCSSが404HTMLのCSS参照とpublic/build/manifest.json、実ファイル同じCSSを戻し、200と元のハッシュを照合。見た目は別途確認
存在しないページが404開いたURLが、確認対象として実在するか演習では正常な404も確認。CSSの欠落や実在ページの404と区別
フォーム・DB・アップロードの結果がない確認した工程と、残っている復元対象今回の3ケースでは未確認。対象を決め、確認できる担当へ残す