React × LaravelをAWSにデプロイする方法

はじめに

モダンなウェブアプリケーション開発において、フロントエンドにReact、バックエンドにLaravelを組み合わせる構成は非常に人気があります。ReactはFacebookが開発したJavaScriptライブラリで、動的でインタラクティブなユーザーインターフェースの構築に優れており、LaravelはPHPベースのウェブアプリケーションフレームワークで、エレガントな構文と強力な機能を提供します。

この記事では、React × Laravelのアプリケーションを、AWSの各種サービスを活用してデプロイする方法を詳しく解説します。開発環境から本番環境への移行を円滑に進め、スケーラブルで安全、そして費用対効果の高いデプロイを実現するためのガイドラインを提供します。

アーキテクチャ概要

React × LaravelアプリケーションをAWSにデプロイする際の一般的なアーキテクチャは以下のようになります:

  1. フロントエンド(React): Amazon S3 + CloudFrontでホスティング
  2. バックエンド(Laravel): EC2、Elastic Beanstalk、またはECSでホスティング
  3. データベース: Amazon RDSまたはAurora
  4. ストレージ: Amazon S3
  5. キャッシュ: Amazon ElastiCache
  6. CDN: Amazon CloudFront
  7. DNS管理: Amazon Route 53
  8. SSL証明書: AWS Certificate Manager

この構成により、フロントエンドとバックエンドを分離し、それぞれに最適な環境でホスティングすることが可能になります。

前提条件

デプロイを始める前に、以下の準備が必要です:

  1. AWSアカウント
  2. AWS CLI(設定済み)
  3. Reactアプリケーション(ビルド可能な状態)
  4. Laravelアプリケーション(本番環境用に設定済み)
  5. GitリポジトリまたはCI/CDツール(オプション)

ステップ1: Reactアプリケーションの準備

まず、Reactアプリケーションを本番環境用にビルドします。

# 依存関係のインストール
npm install

# 本番用ビルド
npm run build

ビルドが完了すると、buildディレクトリに静的ファイルが生成されます。APIエンドポイントが正しく設定されていることを確認してください。

// .env.production の例
REACT_APP_API_URL=https://api.yourdomain.com

ステップ2: Amazon S3バケットの作成と設定

Reactアプリケーションをホスティングするためのバケットを作成します。

# S3バケットの作成
aws s3 mb s3://your-app-frontend --region us-east-1

# 静的ウェブサイトホスティングの有効化
aws s3 website s3://your-app-frontend --index-document index.html --error-document index.html

バケットポリシーを設定して、公開アクセスを許可します:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-app-frontend/*"
        }
    ]
}

Reactビルドをアップロードします:

aws s3 sync build/ s3://your-app-frontend --delete

ステップ3: CloudFrontの設定

より高速でセキュアな配信のため、CloudFrontディストリビューションを作成します。

  1. AWSコンソールからCloudFrontディストリビューションを作成
  2. オリジンドメインとしてS3バケットのウェブサイトエンドポイントを指定
  3. ビヘイビアとして、すべてのリクエスト(*)をS3に転送するよう設定
  4. デフォルトルートオブジェクトをindex.htmlに設定
  5. カスタムエラーレスポンスを設定し、404エラーをindex.htmlにリダイレクト(SPAのルーティング対応)
  6. SSL証明書をACMで発行し、適用

これにより、静的コンテンツがCloudFrontを通じて高速に配信され、SPAのルーティングも正常に機能します。

ステップ4: Laravelアプリケーションの準備

Laravelアプリケーションを本番環境用に準備します。

.envファイルの設定例:

APP_ENV=production
APP_DEBUG=false
APP_URL=https://api.yourdomain.com

DB_CONNECTION=mysql
DB_HOST=your-rds-endpoint.rds.amazonaws.com
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_username
DB_PASSWORD=your_password

CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_HOST=your-elasticache-endpoint.cache.amazonaws.com

AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=your-app-storage

Composerの依存関係をインストールし、最適化を行います:

composer install --optimize-autoloader --no-dev
php artisan config:cache
php artisan route:cache
php artisan view:cache

ステップ5: Amazon RDSの設定

Laravel用のデータベースをAmazon RDSで準備します。

  1. AWSコンソールからRDSインスタンスを作成(MySQL、MariaDB、またはPostgreSQLを選択)
  2. マルチAZ配置を有効化(本番環境では推奨)
  3. 適切なインスタンスタイプとストレージを選択
  4. セキュリティグループを設定し、必要な接続のみを許可
  5. データベースを作成し、マイグレーションを実行
# マイグレーションの実行
php artisan migrate --force

ステップ6: Amazon ElastiCacheの設定(オプション)

キャッシュパフォーマンスを向上させるため、ElastiCacheを設定します:

  1. AWSコンソールからElastiCacheクラスターを作成(Redisを推奨)
  2. 適切なノードタイプを選択
  3. セキュリティグループを設定し、Laravelサーバーからのアクセスのみを許可

ステップ7: Laravelのデプロイ

Laravelアプリケーションをデプロイする方法はいくつかありますが、ここでは代表的な3つの方法を紹介します。

方法1: EC2インスタンスへのデプロイ

基本的なEC2インスタンスへのデプロイ手順:

  1. EC2インスタンスを起動(Amazon Linux 2またはUbuntu推奨)
  2. 必要なソフトウェアをインストール(PHP、Nginx/Apache、Composer等)
  3. GitからLaravelアプリケーションをクローン、または直接アップロード
  4. Webサーバーの設定(Nginxの例):
server {
    listen 80;
    server_name api.yourdomain.com;
    root /var/www/laravel/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

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

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
  1. 必要に応じてロードバランサーを設定

方法2: AWS Elastic Beanstalkを使用する

Elastic Beanstalkを使えば、インフラストラクチャの管理をAWSに委託できます:

  1. Elastic Beanstalk環境を作成(PHP 8.xプラットフォーム)
  2. アプリケーションをZIPまたはGitリポジトリから直接デプロイ
  3. 環境変数を設定
  4. 必要に応じてスケーリングポリシーを設定

.ebextensions/01_deploy.configの設定例:

container_commands:
  01_migrate:
    command: "php artisan migrate --force"
  02_cache_clear:
    command: "php artisan cache:clear"
  03_storage_link:
    command: "php artisan storage:link"

option_settings:
  aws:elasticbeanstalk:container:php:phpini:
    document_root: /public
    memory_limit: 256M
    zlib.output_compression: "Off"
    display_errors: "Off"
  aws:elasticbeanstalk:application:environment:
    APP_ENV: production
    APP_DEBUG: false

方法3: Amazon ECSを使用する

コンテナ化されたデプロイを行いたい場合は、Amazon ECSが適しています:

  1. LaravelアプリケーションのDockerイメージを作成
FROM php:8.1-fpm

# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    nginx

# PHPの拡張機能をインストール
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

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

# Nginxの設定
COPY nginx.conf /etc/nginx/sites-available/default

# アプリケーションのコピー
WORKDIR /var/www
COPY . /var/www

# 権限の設定
RUN chown -R www-data:www-data /var/www

# Composerの依存関係をインストール
RUN composer install --optimize-autoloader --no-dev

# キャッシュのクリア
RUN php artisan config:cache && \
    php artisan route:cache && \
    php artisan view:cache

# ポート80を開放
EXPOSE 80

# スタートアップスクリプト
COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh
CMD ["/usr/local/bin/start.sh"]
  1. Docker Hubまたは Amazon ECRにイメージをプッシュ
  2. ECSでタスク定義とサービスを作成
  3. ロードバランサーとサービスディスカバリーを設定

ステップ8: Route 53でのドメイン設定

Route 53を使用して、フロントエンドとバックエンドのドメインを設定します:

  1. ドメインをRoute 53に登録または移管
  2. フロントエンド用のレコードを作成(CloudFrontディストリビューションを指定)
  3. バックエンド用のレコードを作成(EC2、Elastic Beanstalk、またはECSの前にあるALBを指定)
# Route 53のホストゾーン作成(すでに持っている場合は不要)
aws route53 create-hosted-zone --name yourdomain.com --caller-reference $(date +%s)

# フロントエンド用のレコード作成
aws route53 change-resource-record-sets --hosted-zone-id YOUR_HOSTED_ZONE_ID --change-batch '{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.yourdomain.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "YOUR_CLOUDFRONT_DISTRIBUTION.cloudfront.net",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}'

# バックエンド用のレコード作成
aws route53 change-resource-record-sets --hosted-zone-id YOUR_HOSTED_ZONE_ID --change-batch '{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "api.yourdomain.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "YOUR_ALB_HOSTED_ZONE_ID",
          "DNSName": "YOUR_ALB_DNS_NAME",
          "EvaluateTargetHealth": true
        }
      }
    }
  ]
}'

ステップ9: SSL証明書の設定

AWS Certificate Manager (ACM) を使用して、SSL証明書を発行・管理します:

  1. ACMでワイルドカード証明書 (*.yourdomain.com) または個別のサブドメイン証明書を発行
  2. Route 53でドメイン所有権を自動検証
  3. CloudFrontディストリビューションに証明書を適用
  4. ALB(バックエンド用)に証明書を適用
  5. HTTPSリダイレクトを設定

ステップ10: CORS設定

フロントエンドとバックエンドが異なるドメインで動作する場合、CORS設定が必要です。

Laravelのapp/Http/Middleware/Cors.php

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class Cors
{
    public function handle(Request $request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', env('FRONTEND_URL', 'https://app.yourdomain.com'))
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
            ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, X-XSRF-TOKEN');
    }
}

app/Http/Kernel.phpにミドルウェアを登録:

protected $middleware = [
    // その他のミドルウェア
    \App\Http\Middleware\Cors::class,
];

ステップ11: CI/CDパイプラインの構築(オプション)

自動デプロイを実現するため、AWS CodePipelineを設定します:

  1. CodeCommitリポジトリを作成(または既存のGitHubリポジトリと連携)
  2. CodeBuildプロジェクトを設定(ビルドスペックの例):
version: 0.2

phases:
  pre_build:
    commands:
      - echo Installing backend dependencies...
      - cd backend && composer install --no-dev --optimize-autoloader
      - echo Installing frontend dependencies...
      - cd ../frontend && npm install
  
  build:
    commands:
      - echo Building the frontend...
      - npm run build
      - echo Preparing the backend...
      - cd ../backend
      - php artisan config:cache
      - php artisan route:cache
      - php artisan view:cache
  
  post_build:
    commands:
      - echo Deploying the frontend...
      - aws s3 sync ../frontend/build/ s3://your-app-frontend --delete
      - aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"
      - echo Preparing the backend deployment...
      - zip -r ../backend.zip .

artifacts:
  files:
    - backend.zip
    - appspec.yml
  discard-paths: yes
  1. CodeDeployを設定して、バックエンドを自動デプロイ
  2. CodePipelineを作成し、すべてのステップを接続

ステップ12: モニタリングとログ管理

最後に、アプリケーションのモニタリングとログ管理を設定します:

  1. CloudWatch:
    • EC2インスタンス、RDS、ElastiCacheのメトリクスを監視
    • アラームを設定して異常を検知
    • ダッシュボードを作成して全体を可視化
  2. CloudWatch Logs:
    • Laravel、Nginx/Apacheのログを集約
    • ログフィルターとメトリクスフィルターを作成
    • 異常パターンのアラートを設定
  3. X-Ray(オプション):
    • トレースを有効化し、アプリケーションのパフォーマンスを分析
    • ボトルネックを特定
// X-Rayをセットアップする例
// composer require aws/aws-xray-sdk-php
\AwsXRayDataCollector::init([
    'version' => 'app_version',
    'fixed_segment_name' => 'laravel-app',
]);

コスト最適化のヒント

AWSでのデプロイコストを最適化するためのヒント:

  1. 開発環境と本番環境を分離: 開発中は低スペックのリソースを使用
  2. スポットインスタンス: 非本番環境や耐障害性の高いアプリケーションにはスポットインスタンスを活用
  3. 自動スケーリング: 需要に応じてリソースを調整
  4. リザーブドインスタンス: 長期間使用する予定のリソースにはリザーブドインスタンスを検討
  5. S3ライフサイクルポリシー: 古いファイルを自動的に削除または低コストのストレージクラスに移動
  6. CloudFrontのキャッシュ最適化: TTLを適切に設定して、オリジンへのリクエストを減らす

トラブルシューティング

よくある問題とその解決策:

  1. CORS関連のエラー:
    • ブラウザのコンソールでエラーメッセージを確認
    • LaravelのCorsミドルウェアが正しく設定されているか確認
    • CloudFrontのキャッシュヘッダーも確認
  2. ルーティングの問題:
    • CloudFrontのエラーページ設定を確認
    • Reactのルーティング設定を確認
    • API URLが正しく設定されているか確認
  3. データベース接続エラー:
    • RDSのセキュリティグループが正しく設定されているか確認
    • 接続文字列と認証情報が正しいか確認
    • RDSインスタンスのステータスを確認
  4. パフォーマンスの問題:
    • CloudWatchメトリクスを確認
    • ElastiCacheが正しく設定されているか確認
    • Laravel Debugbarを使用して詳細なパフォーマンス情報を取得

最終チェックリスト

デプロイ前に確認すべき項目:

  • すべての環境変数が正しく設定されているか
  • ビルドプロセスが成功しているか
  • SSL証明書が正しく設定され、期限切れではないか
  • セキュリティグループとネットワークACLが適切に構成されているか
  • バックアップ戦略が計画されているか
  • スケーリングポリシーが設定されているか
  • モニタリングとアラートが機能しているか

まとめ

React × LaravelアプリケーションをAWSにデプロイするプロセスは、複数のステップと考慮事項がありますが、適切に設定すれば、スケーラブル、安全、かつコスト効率の高いアプリケーションを運用することができます。

この記事で解説したアーキテクチャと方法論は、一般的なベストプラクティスに基づいていますが、実際のプロジェクト要件やチームの経験に合わせて調整することをお勧めします。

AWSのサービスは常に進化しているため、最新の機能やベストプラクティスについては、公式ドキュメントを参照することも重要です。

React × Laravelの強力な組み合わせと、AWSの柔軟なインフラストラクチャを活用して、素晴らしいウェブアプリケーションを構築してください!

コメント

タイトルとURLをコピーしました