Contents
ブログ・Web回覧サイト構築の要点まとめ
技術選択:
- Laravel:管理画面重視、複数人管理向け
- Next.js:デザイン・高速表示重視、個人向け
管理画面の差:
- Laravel:Filament等のパッケージで簡単構築
- Next.js:自作が必要で工数2-3倍
構成・費用:
- Laravel:VPS + MySQL + S3 = 月1,500円程度
- Next.js:Vercel + Supabase = 小規模なら無料
- 最小構成:VPS + SQLite = 月500円
開発工数:
- 管理画面含めて2-3ヶ月(最小構成なら1-2ヶ月)
結論: 管理のしやすさ重視 → Laravel コスト・モダンUI重視 → Next.js
プロジェクト流れ
- 開発環境
- 要件洗い出し
- DBスキーマ
- コーディング
- テスト
Laravel + Docker(Sail)構築手順 – Windows版
前提確認
環境 | 状態確認方法 |
---|---|
Docker Desktop | 起動してる?右下のクジラアイコン |
WSL2(推奨) | wsl -l -v で確認(Ubuntuなど) |
Windows Terminal / CMD | どちらでも可 |
Git Bash(推奨) | Bashの方がLinuxコマンド使える |
構築手順ステップ
composer create-project laravel/laravel web-circular
- Laravel Sailというパッケージを開発環境用の依存関係としてインストール
composer require laravel/sail --dev
–devオプションについて
- Sailを導入
php artisan sail:install
Which services would you like to install? [mysql]
None ............................................................................................................. 0
mysql ............................................................................................................ 1
pgsql ............................................................................................................ 2
mariadb .......................................................................................................... 3
mongodb .......................................................................................................... 4
redis ............................................................................................................ 5
valkey ........................................................................................................... 6
memcached ........................................................................................................ 7
meilisearch ...................................................................................................... 8
typesense ........................................................................................................ 9
minio ........................................................................................................... 10
mailpit ......................................................................................................... 11
rabbitmq ........................................................................................................ 12
selenium ........................................................................................................ 13
soketi .......................................................................................................... 14
❯ 1
選択肢リスト、Laravel Sail の「どのサービス(コンテナ)を含めるか」を選べるようです。
無駄なサービスを入れすぎるとDockerコンテナが激重に
表示されるリストから Ubuntu (WSL) を選ぶ
- SailコマンドでDockerコンテナ起動
- Docker Desktopを起動
- Ubuntu(WSL)に切り替える
VSCodeターミナル右上の + 横の 下矢印ボタン ⏷ をクリック
sailコマンドはUbuntuでしか使えない(≒ Linux環境(bash)じゃないと動かない)
/mnt/c/web-circular# vendor/bin/sail up -d
Laravel Sail の正体は、Laravel開発用にチューニングされたDockerラッパースクリプト
処理内容 | 自動化されてる? | 実際の挙動 |
---|---|---|
Dockerイメージの取得 | ✅ | laravelsail/php82-composer とか mysql:8 をPull |
docker-compose.yml生成 | ✅ | sail:install 実行時に .docker と docker-compose.yml を作成 |
コンテナ起動 | ✅ | sail up -d で Laravel(PHP)と MySQL の2コンテナが起動 |
ネットワーク/ボリューム作成 | ✅ | LaravelとDBが同一ネットワークで通信できるように設定 |
先ほどのコンテナ起動でMySQLも一緒に起動されてます
- データベースが生きてるか確認
vendor/bin/sail artisan migrate
INFO Preparing database.
Creating migration table ...................................................... 308.69ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table .......................................... 586.27ms DONE
0001_01_01_000001_create_cache_table .......................................... 171.50ms DONE
0001_01_01_000002_create_jobs_table ........................................... 400.70ms DONE
※Laravelの初期DBスキーマ(テーブル)をMySQLコンテナ上に作成
Laravelのマイグレーションは「データベースのバージョン管理システム」Gitみたいなもの
以上でブラウザでウェルカムページが確認できます
xserverのような共用サーバーではvendor/bin/sail artisan~のようなsailコマンドが使用できない??ので下記の方法がいいかも
XserverにそのままアップできるLaravelプロジェクトをローカルで開発する
Xserver上では原則「composer は使えない」
※Xserverは共用サーバー。つまり、root権限はないし、OSレベルで自由にツールをインストールすることもできない。
→ローカルで composer install を済ませて vendor/ をUPする、npm run buildも
つまりLaravel + Vite構成で開発してる場合、開発サーバーは実質2つ
(開発中はnpm run devでTailwind CSSとか見た目の確認はできます)
項目 | 内容 |
---|---|
ComposerはXserverで使える? | ❌ ローカルで完了させて vendor/ をアップ |
npm run build は必要? | ✅ public/build/ に出力してアップ必須 |
artisanコマンドはXserverで? | ❌ 基本ローカルで済ませておく |
public_html/ の中身は? | index.php , .htaccess , build/ , css/ , etc |
Laravel本体はどこに? | public_html/ の外に laravel_project/ として設置 |
laravel-xserver-dev/
├── docker/
│ ├── php/
│ │ └── Dockerfile
│ └── mysql/
├── docker-compose.yml
├── .env
└── laravel/ ← Laravel本体(後で Composer で生成)
docker-compose.yml
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
container_name: laravel-app
volumes:
- ./laravel:/var/www
ports:
- "8000:8000"
depends_on:
- db
working_dir: /var/www
db:
image: mysql:8.0
container_name: laravel-db
restart: unless-stopped
environment:
MYSQL_DATABASE: laravel
MYSQL_ROOT_PASSWORD: secret
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
ports:
- "3306:3306"
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
Dockerfile
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
git curl zip unzip libonig-dev libxml2-dev \
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath
# Composer install
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www
Laravelをインストール(コンテナ内で)
docker compose up -d
docker compose exec app bash
# コンテナ内で以下を実行
composer create-project laravel/laravel .
exit
結構時間かかります
タイムアウトしてしまったらcomposer config –global process-timeout 900
どの.env?
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
.env のキー | 反映される場所 |
---|---|
APP_ENV | config/app.php の 'env' => env('APP_ENV') |
APP_DEBUG | config/app.php の 'debug' => env('APP_DEBUG') |
DB_* | config/database.php で使用される |
MAIL_* | config/mail.php で使用される |
※Laravelは、起動時に環境変数を読み込んで設定クラスにバインドします
コンテナ内でLaravelがHTTPサーバーを立てる
→ホスト側(ブラウザ)から http://localhost:8000
でアクセス可能になる。
docker compose exec app php artisan serve --host=0.0.0.0 --port=8000
FTPでxservernのサブディレクトリにデプロイする場合、本番サーバーでもローカルと同じ構成にするのが、ベストプラクティス
vendor/ は 1万ファイル以上あるからFTPクライアント(WinSCPやFileZilla)でアップするのに時間かかる。焦るな。
Xserver/public_html/
└── laravel-xserver/
├── app/
├── public/(中身あり)
├── .env
├── index.php ← public/index.phpを書換コピペ
├── .htaccess ← public/.htaccessをコピー
└── ... その他Laravel一式
- public/index.php → laravel-xserver/index.php にコピーして、以下のように修正:
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
- public/.htaccess → laravel-xserver/.htaccess にそのままコピー
環境変数を編集してデプロイ
XserverはMySQLをサービスとして提供している
┌─────────────┐ ┌────────────┐
│ ローカルPC │ │ Xserver │
│ Docker(MySQL)│ │ MySQL提供 │
│ Laravel dev │ │ Laravel prod │
└────┬────────┘ └────┬───────┘
│ DB接続 → localhost │ DB接続 → mysql1234.xserver.jp
│ │
│ migrate │ 手動インポート(phpMyAdmin)
▼ ▼
OK OK
ローカルと本番のDBは「違って当然」、だからマイグレーションで定義する。
内容 | ローカル | 本番 |
---|---|---|
DBサーバー | Dockerで構築したMySQL | XserverのMySQL(管理画面で作成) |
接続情報 | .env に DB_HOST=127.0.0.1 | .env に DB_HOST=mysql1234.xserver.jp |
DB中身(データ) | 開発用のサンプル/テストデータ | 本番の実データ |
DB構造(テーブル定義) | Laravelのマイグレーションで定義する | ← 同じマイグレーションで生成される |
つまり、構造(スキーマ)をマイグレーションで共通化し、
中身(データ)は環境に応じて分けるのが基本。
分類 | Laravelディレクトリ | 本番とローカルの差 | 管理方法 |
---|---|---|---|
コード(PHP) | app/ , routes/ | なし(完全共通) | Gitで管理 |
DB構造(テーブル) | database/migrations | なし(マイグレーションで統一) | Git + artisan migrate |
DBデータ(中身) | database/seeders | あり(本番≠開発) | Seeder or 手動 |
設定 | .env | あり(DB, APP_URL等) | .env / .env.production |
静的ファイル | public/build/ | あり(npm run build) | buildしてUP |
https://github.com/idw-coder/laravel-xserver
XserverでMySQLデータベースを作成する手順
https://www.xserver.ne.jp/login_server.php
「MySQL設定」をクリック
レンタルサーバーではDB接続はSSHでなくphpMyAdminからインポートは「あり」
むしろXserverのような共有ホスティングでは、SSHやCLIよりphpMyAdminの方が標準手段。
ローカルDBをダンプ
mysql> show tables;
Empty set
空でしたのでマイグレーション
docker-compose exec app php artisan migrate
まず、ローカルMySQLコンテナから .sql ファイルをエクスポートする:
docker exec [DBコンテナ名] mysqldump -u root -p laravel > laravel.sql
laravel Breeze
前提条件
- Dockerでローカル開発し、xserver(レンタルサーバー)にデプロイしてます
- composer が使える(Xserver本番環境は使えない、ローカルでやる)
- npm が使える(ローカルでフロントビルド用)
- .env に DB 接続ができている(マイグレーションで users テーブルが作られる)
Breeze インストール
Laravel Breezeパッケージがプロジェクトの開発依存関係(dev-dependencies)としてインストールされます
composer require laravel/breeze --dev
インストール後は以下のコマンドを実行して認証システムをセットアップします
php artisan breeze:install
● Blade with Alpineを選択
選択肢 | 内容 |
---|---|
Blade with Alpine | 最もシンプルな構成。Laravel標準のBladeテンプレート + Alpine.js(軽量JS) |
Livewire(Volt API) | フロントのリアクティブ処理をPHPだけで書ける魔改造スタック。SPA風味 |
React/Vue with Inertia | ガチのSPA構成。React/VueとLaravelの融合 |
API only | 認証付きAPI構成(SPAやモバイル用) |
今度はテストフレームワークの選択
● Pestを選択
項目 | Pest | PHPUnit |
---|---|---|
記述の簡潔さ | ✅ 圧倒的に短くて読みやすい | ❌ 冗長なクラス宣言が必須 |
学習コスト | ✅ 初心者でも感覚的に書ける | ⛔ 「setUp()」だの「TestCase」だの面倒 |
Laravel公式推し | ✅ Breezeのデフォルト選択 | ✅ 同じくサポートされてるが古い |
npmビルドはホスト側で(Dockerコンテナ内ではなく)
Node.js入りDockerは構成が複雑になりすぎる
Breezeは「npmビルドさえ済めば」それでOK
cd \laravel-xserver-dev\laravel
npm install --save-dev vite
npm run build
xserver デプロイ用にパスを修正する
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
base: '/laravel-xserver/build/', // xserverデプロイ時の構成に合わせて設定
});
今度はDockerコンテナ内で
php artisan migrate
http://localhost:8000/registerにアクセスで認証画面の確認OK
現状の整理
laravel/
├── app/
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── Auth/ ← Breezeの認証系コントローラ
│ │ │ └── Controller.php
├── database/
│ ├── migrations/ ← users, sessionsなどが定義されてる
├── resources/
│ ├── views/
│ │ ├── auth/ ← login, registerなど
│ │ ├── layouts/ ← app.blade.php 等のレイアウト
├── routes/
│ ├── web.php ← Breezeが登録ルート追加済
├── public/
│ ├── build/ ← npm run build で生成されたフロントJS
npm run buildでフロントのビルド後xserverのサブディレクトリにデプロイしたら表示崩れ、、
原因
「Laravelアプリを本番でサブディレクトリ配下にデプロイする」とローカルとディレクトリ構成がズレる→パスがおかしくなる
正しい設計は?
そもそもサブディレクトリでの運用がよろしくない?
下記のファイルで調節してうまいことする
vite.config.js
export default defineConfig({
plugins: [laravel({ input: [...], refresh: true })],
base: process.env.VITE_ASSET_BASE || '/build/',
});
.env.production
APP_URL=https://bizlabo.site/laravel-xserver
VITE_ASSET_BASE=/laravel-xserver/build/
.env(ローカル)ローカルでビルドする想定なので
APP_URL=http://localhost:8000
VITE_ASSET_BASE=/build/
結局、臨時処置ですが、public配下のbuildディレクトリをコピーし、publicディレクトリと同配下に複製しました。
表示はくずれなくなりました。
ユーザー一覧画面を作成(練習)
Undefined variable $slot
上記エラー発生
{{ $slot }} を使おうとしているにも関わらず、その変数が定義されていないことが原因
こちらおそらくlaravel Breezeをインストールした際、自動生成された下記コンポーネント
<!-- resources/views/components/app-layout.blade.php -->
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- CSS読み込み -->
</head>
<body>
<div class="min-h-screen bg-gray-100">
<!-- ナビゲーション -->
@include('layouts.navigation')
<!-- ページヘッダー -->
@if (isset($header))
<header class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4">
{{ $header }} <!-- 名前付きスロット -->
</div>
</header>
@endif
<!-- メインコンテンツ -->
<main>
{{ $slot }} <!-- メインのコンテンツエリア -->
</main>
</div>
</body>
</html>
上記に合わせて形でlaravel/resources/views/users/index.blade.phpを修正でエラー解消
そもそも$slotってなに?
$slot:コンポーネントタグの開始タグと終了タグの間に書かれた内容を受け取る変数
項目 | 従来の方法 | Bladeコンポーネント |
---|---|---|
主な機能 | @yield / @section | $slot |
ファイル名 | layouts/app.blade.php | components/app-layout.blade.php |
使用方法 | @extends(‘layouts.app’) | <x-app-layout> |
内容の渡し方 | @section(‘content’) | タグの中に直接記述 |
導入時期 | Laravel初期から | Laravel 7以降 |
Breezeをインストールすると、新しい方式のBladeコンポーネントが使われるため、$slotを見かけるようになります。これは正常な動作で、現在のLaravelで推奨されている方法です。
posts テーブルの作成
新しいマイグレーションファイルが生成されます
php artisan make:migration create_posts_table --create=posts
Enum = Enumeration(列挙型)で管理
Enum = 選択肢を限定する仕組み
- 従来: 文字列なので何でも入る → バグの原因
- Enum: 決められた値だけ → 安全
つまり、「決められたルールの中でしか選べない」ようにして、プログラムをより安全にする技術です!
Laravel Enum完全ガイド
https://github.com/idw-coder/laravel-xserver/blob/add_post/laravel_enum_guide.md
マイグレーション実行
php artisan migrate:status で現在の状況を確認
php artisan migrate
Tinkerを使ってテストデータを作成
php artisan tinker
- 必要なクラスを読み込み
>>> use App\Models\{User, Post};
>>> use App\Enums\PostStatus;
- ユーザーのIDを確認
>>> User::count()
>>> $user = User::first();
>>> $user
- 投稿データを作成
>>> Post::create([
... 'user_id' => $user->id,
... 'title' => 'はじめての投稿',
... 'slug' => 'first-post',
... 'body' => 'これは最初のテスト投稿です。',
... 'status' => PostStatus::DRAFT
... ]);
- 作成されたか確認
>>> Post::count()
>>> Post::first()
本番環境にPOSTのデータ構造を反映する
xserverにssh接続してmigrateする場合
もしphp コマンドのバージョンエラーが起きたら下記記事を参考に
[username@sv12345 laravel-xserver]$ php8.3 artisan migrate
INFO Running migrations.
2025_06_14_074533_create_posts_table .............. 87.84ms DONE
php my adminでも確認できました。
User → Post (HasMany)で既存のUserテーブルと関連づけ、詳細は下記のPDFリンクから👇
https://github.com/idw-coder/laravel-xserver/blob/add_post/blog_erd.md
PostControllerを作成
php artisan make:controller PostController --resource
LaravelにWYSIWYGを実装
WYSIWYGのメリデメ
- ユーザーにとって使いやすい(リンク、見出し、画像アップ)
- 実装が難しい(JSライブラリ + Upload + XSS対策)
- 要サニタイズ処理必須(XSSの温床)
- 簡単に実装できるのはMarkdown
TinyMCE
TinyMCEは「WYSIWYGエディタの具体的な製品・ライブラリの名前」
TinyMCE 無料 (Cloud) プランの制限
無料枠では月間 1,000 エディタ読み込み(editor load)まで。それを超えるとエディタが読み込み専用モードになり、閲覧はできても編集不可になる
100ユーザーが各10ページでTinyMCEを起動すれば、100 × 10 = 1000
方法 | 概要 |
---|---|
Self-hosted | CDN 経由ではなく、自前サーバや public/static に TinyMCE スクリプトを置けば、読み込み回数に制限なし(tiny.cloud)。 |
有料プランへ移行 | 5,000 loads/月の Essential ($79/月)、20,000 loads/月の Professional などから選べる(超過分も課金)。 |
動作確認手順
npm install fs-extra
npm run dev
(またはnpm run build
)public/js/tinymce/
にコピーされているか確認