配置用コピーからpublicを分け、公開側のindex.phpが非公開のLaravel本体を読み込む流れ

GitHubへ置いたサンプルを、ブラウザーからも試せるようにしたい。
そのために、Laravelアプリをレンタルサーバーへ配置する準備を進めました。

Laravelには、ブラウザーへ配信しない.envやDB、ログも含まれます。
本体をWebから直接アクセスできない場所へ置き、配信に必要なpublic/の内容だけを公開側へ分けた配置用コピーを作りました。

配置用ファイルの作成とローカルでの動作確認には、Codexを使いました。
この記事では、何を分け、どの参照先を変更し、どこまで確認できたかを説明します。
サーバー事業者名と実際の配置は掲載せず、図は役割の関係を、パスやURLは説明用の例を示します。

説明は2026年11月時点のものです。
扱う範囲は、サーバーへ転送する前のローカル準備と検証です。

本体と公開入口を分ける手順

public/には、HTTPの入口となるindex.phpや.htaccess、配信ファイルがあります。
公開側へ移したindex.phpから、非公開側の本体を読み込む構成にしました。
本体への公開リンクは作りません。

1. 配置用コピーからpublicを分ける

元の開発アプリや公開サンプルは直接変更せず、公開するコミットから配置用コピーを作りました。
本番用の依存ライブラリとビルド済みアセットを用意してから、コピー内のpublic/を公開側へ移しました。

配置用コピー内の対象 分離後の置き場所と役割
public/index.php、public/.htaccess 公開側。リクエストを受け付ける入口
public/build/などの配信ファイル 公開側。CSS・JavaScriptなどを配信
app/、bootstrap/、vendor/など 非公開側。アプリの処理と依存ライブラリ
.env、SQLite、storage/ 非公開側。本番設定や保存データ。実際の設定・DBは配置時に用意

移動後は相対パスが変わるため、入口から本体、本体から公開側への参照先を調整しました。

2. index.phpから非公開側の本体を読み込む

公開側のindex.phpで、本体にある次の3か所の読み込み先を変更しました。

読み込み先 役割
storage/framework/maintenance.php Laravelのメンテナンス表示
vendor/autoload.php Composerが管理するクラスの読み込み
bootstrap/app.php Laravelアプリの初期化

次は変更部分の抜粋です。
仮のパスを使った説明用コードであり、index.php全体の置き換えには使えません。

$basePath = '/path/to/private/tool-a';

if (file_exists($maintenance = $basePath.'/storage/framework/maintenance.php')) {
    require $maintenance;
}

require $basePath.'/vendor/autoload.php';
$app = require_once $basePath.'/bootstrap/app.php';

ブラウザーからの要求は公開側で受け、PHPがサーバー内の本体を読み込みます。
本体の保存場所を公開URLにする必要はありません。

3. 本体にも公開側の場所を設定する

Laravelが元のpublic/を参照しないよう、配置用コピーのbootstrap/app.phpにも公開先を指定しました。
設定する位置は、アプリ生成後のreturn $app;の前です。

// Application::configure(...)から生成した$appに設定する。
$app->usePublicPath('/path/to/web-root/demo/tool-a');

return $app;

このパスも仮値です。
HTTPとArtisanの両方が読むbootstrap/app.phpに設定し、公開先をそろえました。
省略部分を含む変更は、配置用コピーの作成処理へ組み込んでいます。

4. 分離した配置用コピーで動作を確認する

分離したコピーをローカルで起動し、画面・CSS・JavaScriptと、非公開ファイルを求めた場合の応答を確認しました。
条件と結果は、後半の「サブフォルダーで画面とアセットを確認する」にまとめます。
サーバーの公開設定は、この検証の対象外です。

共通の一覧とアプリごとの領域を用意する

後から別のアプリを追加できるよう、共通一覧とアプリの領域を分けました。

領域 役割
共通の一覧 利用できるアプリへの案内
アプリごとの公開側 そのアプリのindex.phpと配信ファイル
アプリごとの非公開側 そのアプリの本体・設定・DB・ログ

共通一覧は静的ページとし、各アプリは自分のURL範囲だけを処理します。
表は役割の整理であり、実際の階層ではありません。
用意したのは学習用だけで、未実装の業務アプリへのリンクはありません。

公開するコードと本番設定を分ける

配置したコードを特定できるよう、公開するコミットを固定しました。
Gitからファイルを取り出し、lockファイルに従って本番用の依存を導入します。
CSS・JavaScriptはローカルでビルドし、開発用の依存とnode_modules/は転送候補から除きました。

資材へ含めるもの 配置時に用意するもの
対象コミットのコード・本番依存 実際の.envとAPP_KEY
ビルド済みCSS・JavaScript アプリ用SQLiteとセッション・ログ
本番設定のひな形 サーバー内の実際のパス・書込み権限
ファイルのハッシュ一覧 配置前のバックアップ

本番設定のひな形は次のとおりです。
URL・Cookie名・Pathは説明用の仮値です。

APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://example.com/demo/tool-a
SESSION_DRIVER=file
SESSION_COOKIE=tool_a_session
SESSION_PATH=/demo/tool-a
SESSION_SECURE_COOKIE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=lax
CACHE_STORE=file

空欄のAPP_KEYは初回配置時に生成し、更新時も維持します。
SQLiteは非公開の本体側に作り、実際のパスを設定します。

セッションとキャッシュはファイル保存とし、storage/とbootstrap/cache/の書込みを確認します。
Cookie名・Path、設定・DB・ログ・依存ライブラリ・APP_KEYはアプリごとに管理します。
Cookieの範囲を分けても、同じドメイン内のアプリを完全には隔離できません。
業務用の認証・権限は別途実装が必要です。

サブフォルダーで画面とアセットを確認する

APP_URLの設定に加え、リンク・フォーム送信先・CSS・JavaScriptのURLが、公開用サブフォルダーの範囲に収まるかを調べました。
分離した候補をローカルで起動し、次を確認しました。

  • 共通の一覧から学習用へ移動でき、未実装アプリへのリンクがないこと。
  • Hello World、名前入力、入力エラーとCSRFの確認。
  • 共通メニューからパスワード生成までの移動、生成とコピー。
  • 公開用サブフォルダーからのCSS・JavaScript取得。
  • セッションCookieのPath、Secure、HttpOnly、SameSite。
  • 存在しないURLや本体ファイルを求めたときの応答。

基礎サンプルは375・1280px幅、ツール画面は320・375・768・1280px幅で操作確認が通りました。
本番用の依存要件確認、設定・ルート・ビューのキャッシュ作成もローカルでは成功しています。

検証にはPHPの開発サーバーを使ったため、Apacheの.htaccess処理や.user.iniの実効値は未確認です。
サーバーではAPP_DEBUG=falseに加え、PHP自体のエラー表示設定も確認する必要があります。
既存サイトへ影響を及ぼさないよう、アプリ専用の設定ファイルを用意しました。

更新と切戻しも配置前に決める

更新では新旧のファイルが混ざらないよう、次の手順を用意しました。

  1. 別の場所に、新しい本体と同じ版の公開ファイル(build/を含む)を用意する。
  2. .env・APP_KEY・DB・必要な保存データを引き継ぐ。
  3. 対象アプリをメンテナンス状態にし、その本体と公開側だけを切り替える。
  4. 動作を確認して保守を解除する。問題があれば本体・公開側を両方とも前の版へ戻す。

共通入口のフォルダー全体は置き換えず、ほかのアプリを更新・切戻しの対象に含めません。

保守中の応答は、本体の外に置くメンテナンス用ファイルで制御します。
ローカルでは次の動作を確認しました。

状態 対象アプリ 共通一覧
保守用ファイルあり 503を返す 表示を続ける
保守用ファイルを除去 通常表示へ復帰 表示を続ける

実配置時にも、保守用ファイルの位置と応答を確認します。
DB構造を変える更新は、コードを戻すだけでは復旧できない場合があります。
バックアップ方法と、更新後のデータを失わずに戻せる範囲も事前に確認が必要です。

配置候補の作成・ローカル検証と、初回配置・更新・切戻しの手順を用意できました。
次は手順を確認してサーバーへ配置し、既存サイトへの影響と公開動作を確かめます。