はじめに
モダンなウェブアプリケーション開発において、LaravelとReactの組み合わせは非常に人気があります。Laravelの堅牢なバックエンドフレームワークとReactの柔軟なフロントエンドライブラリを組み合わせることで、高品質なウェブアプリケーションを効率的に開発できます。
さらに、Docker を導入することで、開発環境の構築と共有が容易になり、「自分の環境では動くのに」という問題を解決できます。この記事では、Laravel、React、そしてDockerを組み合わせた開発環境の構築方法を詳しく解説します。
前提条件
この記事を進めるにあたり、以下のツールがインストールされていることを前提とします:
- Docker Desktop
- Git
- コードエディタ(VS Code など)
プロジェクトの構成
今回構築する開発環境は以下のような構成になります:
project-root/
├── docker/ # Docker関連ファイル
│ ├── nginx/ # Nginxの設定
│ ├── php/ # PHPの設定
│ └── mysql/ # MySQLの設定
├── backend/ # Laravelプロジェクト
├── frontend/ # Reactプロジェクト
├── docker-compose.yml # Docker Compose設定
└── .env # 環境変数
1. プロジェクトのセットアップ
まず、プロジェクトのルートディレクトリを作成し、必要なフォルダ構造を準備します。
mkdir laravel-react-docker
cd laravel-react-docker
mkdir -p docker/nginx docker/php docker/mysql
2. Dockerの設定
docker-compose.yml の作成
プロジェクトのルートディレクトリに docker-compose.yml
ファイルを作成します。
version: '3'
services:
# PHP サービス
app:
build:
context: ./docker/php
volumes:
- ./backend:/var/www/html
depends_on:
- db
networks:
- laravel-network
# Nginx サービス
web:
build:
context: ./docker/nginx
ports:
- "80:80"
volumes:
- ./backend:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- laravel-network
# MySQL サービス
db:
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: laravel_db
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
networks:
- laravel-network
# Node.js サービス (React用)
node:
image: node:18-alpine
working_dir: /app
volumes:
- ./frontend:/app
ports:
- "3000:3000"
command: sh -c "if [ -f package.json ]; then npm install && npm start; else echo 'Waiting for frontend setup...'; fi"
networks:
- laravel-network
networks:
laravel-network:
driver: bridge
volumes:
mysql-data:
PHPの設定
docker/php/Dockerfile
を作成します。
FROM php:8.2-fpm
# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip
# PHPの拡張機能をインストール
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Composerのインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# 作業ディレクトリの設定
WORKDIR /var/www/html
# UIDとGIDを設定して権限の問題を回避
RUN usermod -u 1000 www-data
Nginxの設定
docker/nginx/Dockerfile
を作成します。
FROM nginx:1.23-alpine
WORKDIR /var/www/html
次に、Nginxの設定ファイル docker/nginx/default.conf
を作成します。
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
3. Laravelプロジェクトの作成
Dockerを使用してLaravelプロジェクトを作成します。
# Dockerイメージのビルド
docker-compose build
# Laravelプロジェクトを作成
docker-compose run --rm app composer create-project laravel/laravel .
# 権限を設定
sudo chown -R $USER:$USER backend
Laravelの環境設定
backend/.env
ファイルを編集して、データベース接続情報を設定します。
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel
DB_PASSWORD=secret
4. Reactプロジェクトの作成
次に、Reactプロジェクトを作成します。
# Reactプロジェクトを作成
docker-compose run --rm node sh -c "npx create-react-app . --template typescript"
# 権限を設定
sudo chown -R $USER:$USER frontend
Reactの設定
API通信のためのプロキシ設定を行います。frontend/package.json
に以下の行を追加します。
"proxy": "http://web"
5. CORSの設定
Laravelで異なるオリジンからのリクエストを許可するために、CORSを設定します。
# LaravelのCORSパッケージをインストール
docker-compose run --rm app composer require fruitcake/laravel-cors
backend/app/Http/Kernel.php
の $middleware
配列に \Fruitcake\Cors\HandleCors::class
を追加します。
backend/config/cors.php
を編集して、以下のように設定します。
return [
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:3000'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
6. Laravel SanctumによるAPI認証の設定
LaravelでAPIの認証を簡単に実装するために、Sanctumを使用します。
# Sanctumのインストール
docker-compose run --rm app composer require laravel/sanctum
# Sanctumのインストール
docker-compose run --rm app php artisan sanctum:install
# マイグレーションの実行
docker-compose run --rm app php artisan migrate
backend/app/Http/Kernel.php
の api
ミドルウェアグループに \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
を追加します。
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
7. バックエンドAPIの作成
シンプルなAPIを作成してみましょう。
# コントローラーの作成
docker-compose run --rm app php artisan make:controller API/TaskController --api
backend/app/Http/Controllers/API/TaskController.php
を編集します。
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class TaskController extends Controller
{
/**
* タスク一覧を取得
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$tasks = [
['id' => 1, 'title' => 'タスク1', 'completed' => false],
['id' => 2, 'title' => 'タスク2', 'completed' => true],
['id' => 3, 'title' => 'タスク3', 'completed' => false],
];
return response()->json($tasks);
}
}
APIルートを設定します。backend/routes/api.php
を編集します。
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\API\TaskController;
// ユーザー情報取得のルート
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
// タスク一覧取得のルート
Route::get('/tasks', [TaskController::class, 'index']);
8. フロントエンドでAPIの利用
必要なパッケージをインストールします。
docker-compose run --rm node npm install axios
APIからデータを取得するコンポーネントを作成します。frontend/src/App.tsx
を編集します。
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import './App.css';
interface Task {
id: number;
title: string;
completed: boolean;
}
function App() {
const [tasks, setTasks] = useState<Task[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
// APIからタスク一覧を取得
const fetchTasks = async () => {
try {
const response = await axios.get('/api/tasks');
setTasks(response.data);
setLoading(false);
} catch (err) {
setError('タスクの取得に失敗しました');
setLoading(false);
}
};
fetchTasks();
}, []);
if (loading) return <div>読み込み中...</div>;
if (error) return <div>{error}</div>;
return (
<div className="App">
<header className="App-header">
<h1>タスク一覧</h1>
</header>
<main>
<ul>
{tasks.map(task => (
<li key={task.id} style={{ textDecoration: task.completed ? 'line-through' : 'none' }}>
{task.title}
</li>
))}
</ul>
</main>
</div>
);
}
export default App;
9. 開発環境の起動
すべての設定が完了したら、Docker Composeを使って開発環境を起動します。
docker-compose up -d
これで以下のURLでアプリケーションにアクセスできます:
- Laravel: http://localhost
- React: http://localhost:3000
10. 開発環境の使用方法
Laravelコマンドの実行
# Artisanコマンドの実行
docker-compose exec app php artisan <command>
# 例: マイグレーション
docker-compose exec app php artisan migrate
# 例: シーダーの実行
docker-compose exec app php artisan db:seed
npmコマンドの実行
# npmコマンドの実行
docker-compose exec node npm <command>
# 例: パッケージのインストール
docker-compose exec node npm install <package-name>
# 例: ビルド
docker-compose exec node npm run build
データベースへのアクセス
# MySQLへの接続
docker-compose exec db mysql -u laravel -p
11. 本番環境への準備
本番環境にデプロイする前に、以下のステップを実行してください。
フロントエンドのビルド
docker-compose exec node npm run build
環境変数の設定
本番環境用の .env
ファイルを作成し、適切な設定を行います。
キャッシュの最適化
docker-compose exec app php artisan config:cache
docker-compose exec app php artisan route:cache
docker-compose exec app php artisan view:cache
12. トラブルシューティング
権限の問題
コンテナ内で生成されたファイルのパーミッション問題が発生した場合、以下のコマンドを実行します。
sudo chown -R $USER:$USER backend
sudo chown -R $USER:$USER frontend
コンテナ間の通信問題
コンテナ間で通信できない場合、ネットワーク設定を確認し、必要に応じて再起動します。
docker-compose down
docker-compose up -d
ポートの衝突
ポートが既に使用されている場合、docker-compose.yml
ファイルでポート設定を変更します。
ports:
- "8080:80" # 80ポートの代わりに8080を使用
まとめ
この記事では、Laravel、React、そしてDockerを組み合わせた開発環境の構築方法を解説しました。このセットアップにより、以下のメリットが得られます:
- 環境の一貫性: Dockerを使用することで、開発環境と本番環境の一貫性を確保できます。
- 簡単なセットアップ: 新しいチームメンバーがプロジェクトに参加する際、簡単に開発環境を構築できます。
- 分離された開発: バックエンド(Laravel)とフロントエンド(React)の開発を明確に分離できます。
- スケーラビリティ: 必要に応じてサービスを追加または変更できます。
この構成を基に、あなたのプロジェクトに合わせてカスタマイズしてください。Dockerを活用することで、開発プロセスがよりスムーズになり、「自分の環境では動くのに」という問題から解放されるでしょう。
次のステップとして、CI/CDパイプラインの設定や、本番環境へのデプロイ方法などを検討することをお勧めします。
コメント