Laravel + Inertia.js + Vue 3:Docker と Nginx を活用した SSR 環境構築 (Part 1)
Laravel + Inertia.js の環境構築において、php artisan serve を使用する例が多く見られますが、これはローカル開発には適していますが、Docker 環境や本番環境では推奨されません。
本記事では、Laravel + Inertia.js + Vue 3 + SSR を Docker で構築する方法を解説します。使用する技術スタックは以下の通りです。
- Nginx
- PHP-FPM
- Node.js(Inertia SSR 用)
1. アーキテクチャ概要
リクエストフローは以下の通りです。
Browser
↓
Nginx (port 80)
↓
PHP-FPM (Laravel)
↓
Inertia SSR Server (Node.js - port 13714)
Laravel がルーティングを処理し、SSR は初期 HTML のレンダリングのみを担当します。
2. ディレクトリ構造
.
├── docker
│ ├── nginx
│ │ └── default.conf
│ └── php
│ └── Dockerfile
├── docker-compose.yml
├── resources
├── bootstrap
├── public
├── composer.json
├── package.json
└── artisan
3. php artisan serve を使用しない理由
php artisan serve は開発環境専用であり、以下の理由から本番環境や Docker 環境には適していません。
- シングルスレッドで動作
- キャッシュ機能が限定的
- Docker / 本番環境に非対応
代わりに、以下の構成を採用します。
- Nginx を Web サーバーとして使用
- PHP-FPM で PHP を処理
- Node.js を SSR 専用コンテナで実行
4. PHP-FPM の Dockerfile
docker/php/Dockerfile:
FROM php:8.2-fpm
WORKDIR /var/www/html
RUN apt-get update && apt-get install -y \
git curl zip unzip \
nodejs npm \
libzip-dev \
&& docker-php-ext-install pdo pdo_mysql zip
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY . .
RUN composer install --no-dev --optimize-autoloader
RUN npm install
RUN npm run build
RUN chown -R www-data:www-data /var/www/html
EXPOSE 9000
CMD ["php-fpm"]
この PHP コンテナは以下の処理を行います。
- Laravel のビルド
- Vite のビルド
- PHP-FPM のみを実行(HTTP サーバーは実行しない)
5. Nginx の設定
docker/nginx/default.conf:
server {
listen 80;
root /var/www/html/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Nginx は以下の役割のみを担当します。
- リクエストの受信
- PHP リクエストを PHP-FPM に転送
6. docker-compose.yml
version: "3.8"
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
container_name: laravel_app
volumes:
- .:/var/www/html
networks:
- laravel
nginx:
image: nginx:stable-alpine
container_name: laravel_nginx
ports:
- "8000:80"
volumes:
- .:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- laravel
ssr:
image: node:18-alpine
container_name: inertia_ssr
working_dir: /var/www/html
volumes:
- .:/var/www/html
command: >
sh -c "npm install && npm run build && php artisan inertia:start-ssr"
ports:
- "13714:13714"
networks:
- laravel
networks:
laravel:
driver: bridge
重要なポイント:
- SSR は独立したコンテナとして実行
- PHP とは分離されている
- スケーリングとデバッグが容易
7. Inertia SSR の設定
config/inertia.php:
'ssr' => [
'enabled' => true,
'url' => 'http://ssr:13714',
],
重要な注意点: Docker 環境では 127.0.0.1 ではなく、サービス名(ssr)を使用する必要があります。
8. ビルドと実行
docker-compose up --build
実行後、以下の URL でアクセス可能です。
- Web: http://localhost:8000
- SSR server: http://localhost:13714
9. SSR のファイル構造
SSR を有効にすると、以下のファイルが使用されます。
-
SSR エントリーポイント:
resources/js/ssr.js -
ビルド後の SSR ファイル:
bootstrap/ssr/ssr.mjs -
Vite 設定:
vite.config.js(SSR エントリーポイントを含む)
10. SSR ファイルの基本構造
resources/js/ssr.js:
import { createInertiaApp } from '@inertiajs/vue3'
import createServer from '@inertiajs/vue3/server'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'
createServer(page =>
createInertiaApp({
page,
render: renderToString,
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ App, props, plugin }) {
return createSSRApp({
render: () => h(App, props),
}).use(plugin)
},
}),
)
11. Vite の設定
vite.config.js:
import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
ssr: 'resources/js/ssr.js',
refresh: true,
}),
vue(),
],
})
12. SSR ポートの変更
デフォルトでは、Inertia.js の SSR サーバーは port 13714 で動作します。以下の場合にポートを変更する必要があります。
- ポートが既に使用されている場合
- ホスティングプロバイダーが特定のポート範囲のみ許可している場合
- セキュリティポリシーで特定のポートを要求する場合
ポート変更手順
1. SSR ファイルでポートを指定
resources/js/ssr.js を編集し、createServer の第2引数にポートを指定します。
createServer(page =>
createInertiaApp({
// ... config ...
}),
8080 // カスタムポート
)
その後、ビルドを実行します。
npm run build
2. Laravel の設定を更新
Inertia の設定ファイルを公開します(未作成の場合)。
php artisan vendor:publish --provider "Inertia\ServiceProvider"
config/inertia.php で SSR サーバーの URL を更新します。
'ssr' => [
'enabled' => true,
'url' => 'http://127.0.0.1:8080',
],
13. 環境変数による管理
環境ごとにポートを管理するため、環境変数を使用することを推奨します。
1. SSR ファイルの更新
resources/js/ssr.js:
createServer(page =>
createInertiaApp({
// ... config ...
}),
parseInt(process.env.VITE_INERTIA_SSR_PORT || 13714)
)
注意: Vite で環境変数を公開するには、VITE_ プレフィックスが必要です。
2. Laravel 設定の更新
config/inertia.php:
'ssr' => [
'enabled' => true,
'url' => 'http://127.0.0.1:' . env('VITE_INERTIA_SSR_PORT', 13714),
],
3. .env ファイルに追加
VITE_INERTIA_SSR_PORT=8080
重要な注意点: ポートはビルド時にバンドルに含まれるため、ポートを変更した場合は再ビルドが必要です。
npm run build
14. 本番環境の設定
本番環境では、Supervisord などのプロセスマネージャーを使用して SSR サーバーを管理します。
/etc/supervisor/conf.d/inertia-ssr.conf:
[program:inertia_ssr]
process_name=%(program_name)s
command=php /var/www/html/artisan inertia:start-ssr
autostart=true
autorestart=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/inertia-ssr.log
stdout_logfile_maxbytes=0
プロセスマネージャーが SSR サーバーを自動的に起動・再起動します。
15. ビルドスクリプト
package.json に SSR ビルド用のスクリプトを追加します。
{
"scripts": {
"dev": "vite",
"build": "vite build",
"build:ssr": "vite build && vite build --ssr"
}
}
build:ssr スクリプトは以下を実行します。
- クライアントサイドアセットのビルド(
vite build) - SSR バンドルのビルド(
vite build --ssr)
16. SSR の動作確認
設定後、SSR サーバーを起動します。
php artisan inertia:start-ssr
以下の出力が表示されます。
Starting SSR server on port 8080...
Inertia SSR server started.
SSR が正常に動作しているか確認する方法:
-
ページソースの確認: HTML に完全なコンテンツが含まれている(空の
<div id="app"></div>ではない) - JavaScript を無効化: JavaScript を無効にしてもページが表示される
- ネットワークタブの確認: サーバーからのレスポンスに完全な HTML が含まれている
17. まとめ
Laravel + Inertia.js + Vue 3 + SSR を Docker で構築する方法を解説しました。主なポイントは以下の通りです。
- Nginx + PHP-FPM の構成で本番環境に適したアーキテクチャ
- SSR を独立したコンテナで実行し、スケーラビリティと保守性を向上
- 環境変数によるポート管理で柔軟な設定が可能
- プロセスマネージャーによる本番環境での自動管理