Docker で Laravel + React を構築する手順

2025/03/08に公開

Laravel(バックエンド)と React(フロントエンド)を Docker で構築する手順を書きます。

目次

  • プロジェクトのディレクトリ構成
  • Docker 環境のセットアップ
  • Laravel のセットアップ(バックエンド)
  • React のセットアップ(フロントエンド)
  • Docker Compose でコンテナを起動
  • フロントエンドから Laravel API を叩く
  • トラブルシューティング
  • 詰まったポイント
  • まとめ

プロジェクトのディレクトリ構成

まず、以下のようなディレクトリ構成でプロジェクトを作成します。

my-project/
 ├── back/             # Laravel (API)
 │   ├── app/
 │   ├── bootstrap/
 │   ├── config/
 │   ├── database/
 │   ├── public/       # Apache/Nginx で公開
 │   ├── resources/
 │   ├── routes/
 │   ├── .env
 │   ├── Dockerfile    # Laravel 用 Dockerfile
 │   ├── composer.json
 │   ├── artisan
 ├── front/            # React (フロントエンド)
 │   ├── src/
 │   ├── public/
 │   ├── Dockerfile    # React 用 Dockerfile
 │   ├── package.json
 ├── docker-compose.yml # Docker Compose 設定
 ├── nginx/            # Nginx の設定(本番環境用)
 │   ├── default.conf

Docker 環境のセットアップ

まずは docker-compose.yml を作成し、Laravel(PHP + Apache + MySQL)と React(Node.js)を動かせるようにします。

📌 docker-compose.yml

version: "3.8"

services:
  # Laravel API (Apache + PHP-FPM)
  back:
    container_name: laravel_back
    build: ./back
    volumes:
      - ./back:/var/www/html
    environment:
      TZ: Asia/Tokyo
    ports:
      - "9000:80" # 外部 9000 → コンテナ内 80(Apache)
    depends_on:
      - db
    tty: true
    stdin_open: true

  # MySQL
  db:
    image: mysql:5.7
    container_name: laravel_db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    ports:
      - "13306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

  # React フロントエンド
  front:
    container_name: react_front
    build: ./front
    volumes:
      - ./front:/app
      - /app/node_modules # node_modules はコンテナ内で管理
    ports:
      - "3000:3000"
    depends_on:
      - back
    stdin_open: true
    tty: true

volumes:
  mysql_data:

Laravel のセットアップ

次に、Laravel の Docker 環境を作成します。

📌 back/Dockerfile

FROM php:8.2-apache

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
    libxml2-dev libzip-dev unzip git curl \
    && docker-php-ext-install pdo pdo_mysql zip

# Apache の設定(mod_rewrite を有効化)
RUN a2enmod rewrite

# Composer をインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

WORKDIR /var/www/html

COPY . .

# Laravel のセットアップ
RUN composer install --no-scripts --no-dev --prefer-dist
RUN php artisan key:generate
RUN php artisan config:cache

# 権限設定
RUN chown -R www-data:www-data /var/www/html
RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache

EXPOSE 80

React のセットアップ

React 用の Dockerfile を作成します。

📌 front/Dockerfile

FROM node:18

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . .

EXPOSE 3000
CMD ["npm", "start"]

📌 front/package.json

{
  "name": "front",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build"
  }
}

📌 front/src/index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Docker Compose でコンテナを起動

docker-compose up -d --build

1.すべてのコンテナが正常に動作しているか確認

docker ps

2.Laravel API が動いているか確認

curl http://localhost:9000/api/hello

3.React アプリにアクセス

http://localhost:3000

  1. フロントエンドから Laravel API を叩く
    📌 front/src/App.js
import React, { useEffect, useState } from "react";

function App() {
  const [message, setMessage] = useState("");

  useEffect(() => {
    fetch("http://localhost:9000/api/hello")
      .then((res) => res.json())
      .then((data) => setMessage(data.message))
      .catch((err) => console.error("Error fetching API:", err));
  }, []);

  return (
    <div>
      <h1>React + Laravel API</h1>
      <p>{message}</p>
    </div>
  );
}

export default App;

✅ ブラウザで http://localhost:3000 にアクセスすると、Laravel API のデータが表示される!

詰まったポイント & 解決策

途中詰まったポイントをまとめました!💡

❌ docker-compose up で Cannot start service db: Ports are not available
docker-compose.yml の ports を 13306:3306 に変更

❌ Laravel の php artisan コマンドが動かない
✅ 解決策

docker exec -it laravel_back bash
composer install --no-scripts
php artisan key:generate
php artisan config:cache

❌ React が npm start でエラー
✅ 解決策

docker run --rm -v $(pwd)/front:/app -w /app node:18 bash -c "rm -rf node_modules package-lock.json && npm install"

そして、Docker コンテナを再起動

docker-compose down
docker-compose up -d --build

❌ React の画面が真っ白
✅ 解決策
ブラウザの F12 → Console を確認
src/index.js を修正

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

❌ Uncaught TypeError: react_dom__WEBPACK_IMPORTED_MODULE_1__.render is not a function
✅ 解決策
React 18 では ReactDOM.render() の代わりに createRoot() を使用!

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

まとめ

✅ docker-compose up -d --build で Laravel + React を起動
http://localhost:3000 で React アプリを表示
http://localhost:9000/api/hello で Laravel API が動作
✅ React から Laravel API を fetch で取得

Discussion