🐳

Laravel 12 + React 19 + MySQL 8.0をdocker composeする

に公開

概要

ブログアプリケーションを開発する際の、Laravel + React + MySQLのDocker環境構築方法を紹介します。

※ ブログappを作成しようと思っていたとこから切り出したので、一部ブログappを想定したエンドポイント名になっていたります。

技術スタック

  • フロントエンド: React 19.1.0 + TypeScript 5.8.3 + Vite 7.0.3
  • バックエンド: Laravel 12.0 + PHP 8.2
  • データベース: MySQL 8.0
  • Webサーバー: Nginx (alpine)
  • コンテナ: Docker + Docker Compose 3.8

構成

react-laravel-blog/
├── infra/                     # ローカル開発用インフラ設定
│   ├── docker-compose.yml     # ローカル開発用
│   ├── nginx/
│   │   └── nginx.conf        # Nginx設定
│   ├── backend/
│   │   ├── Dockerfile        # バックエンド用Dockerfile
│   │   └── .dockerignore
│   └── frontend/
│       ├── Dockerfile        # フロントエンド用Dockerfile
│       └── .dockerignore
├── backend/                   # Laravelアプリケーション
├── frontend/                  # Reactアプリケーション
└── ...                        # その他のプロジェクトファイル

docker-compose.yml

version: '3.8'

services:
  frontend:
    build:
      context: ../frontend
      dockerfile: ./frontend/Dockerfile
    ports:
      - "5173:5173"
    volumes:
      - ../frontend:/app
    environment:
      - CHOKIDAR_USEPOLLING=true
    command: npm run dev -- --host 0.0.0.0
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "8000:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ../backend:/app
    depends_on:
      - backend
    networks:
      - app-network

  backend:
    build:
      context: ../backend
      dockerfile: ./backend/Dockerfile
    volumes:
      - ../backend:/app
    depends_on:
      - database
    networks:
      - app-network

  database:
    image: mysql:8.0
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: blog_app
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  mysql_data:

Nginx設定

infra/nginx/nginx.conf

server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /app/public;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass backend:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

使用方法

1. 開発環境の起動

cd infra
docker-compose up -d

2. アクセス

3. 環境変数の設定

Laravelの.envファイルで以下の設定を行ってください:

DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=blog_app
DB_USERNAME=root
DB_PASSWORD=root

APIアクセスフロー

全体構成

┌─────────────────┐    HTTP Request    ┌─────────────┐    FastCGI    ┌─────────────┐
│   React App     │ ──────────────────→ │    Nginx     │ ─────────────→ │   Laravel    │
│ (localhost:5173) │                    │ (localhost:8000) │              │ (backend:9000) │
└─────────────────┘                    └─────────────┘              └─────────────┘
         │                                      │                           │
         │                                      ▼                           │
         │                              ┌─────────────┐                    │
         │                              │  PHP-FPM    │                    │
         │                              │  Process    │                    │
         │                              └─────────────┘                    │
         │                                      │                           │
         │                                      ▼                           │
         │                              ┌─────────────┐                    │
         │                              │ Laravel App │                    │
         │                              │ (index.php) │                    │
         │                              └─────────────┘                    │
         │                                      │                           │
         │                                      ▼                           │
         │                              ┌─────────────┐                    │
         │                              │ API Response│                    │
         │                              │ (JSON/HTML) │                    │
         │                              └─────────────┘                    │
         │                                      │                           │
         │                                      ▼                           │
         │                              ┌─────────────┐                    │
         │                              │   Nginx     │                    │
         │                              │ (Response)  │                    │
         │                              └─────────────┘                    │
         │                                      │                           │
         ▼                                      ▼                           ▼
┌─────────────────┐                    ┌─────────────┐              ┌─────────────┐
│   React App     │ ←────────────────── │    Nginx     │ ←──────────── │   Laravel    │
│ (localhost:5173) │                    │ (localhost:8000) │              │ (backend:9000) │
└─────────────────┘                    └─────────────┘              └─────────────┘

リクエスト例

ブログ記事一覧を取得する場合:

// Reactアプリ内で
fetch('http://localhost:8000/api/posts')
  .then(response => response.json())
  .then(data => console.log(data));

処理フロー:

  1. React: localhost:8000/api/postsにGETリクエスト
  2. Nginx: リクエストを受信
  3. Nginx: /api/posts/index.php?$query_stringにリライト
  4. Nginx: index.phpをPHP-FPMに転送
  5. Laravel: ルーティングで/api/postsを処理
  6. Laravel: JSONレスポンスを返す
  7. Nginx: レスポンスをReactに返す

Discussion