0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon EC2 に Laravel + React(Inertia)アプリを Docker で本番デプロイする手順【SSL認証】【Amazon Linux 2023 対応】

Last updated at Posted at 2025-10-14

はじめに

この記事では、開発環境で動いていた Laravel + React (Inertia.js) アプリを、EC2 上で Docker を使って本番運用できる構成にする手順を解説します。
対象読者は以下のような方です:

  • 開発環境では Laravel Sail を使っている
  • EC2 に本番環境を構築したい
  • RDS + Nginx + Docker の構成で運用したい
  • HTTPS(Let’s Encrypt)も有効化したい

1. EC2に接続する

EC2インスタンス作成後、EC2 インスタンスに SSH 接続します。

mkdir -p ~/.ssh
mv ~/Downloads/*****.pem ~/.ssh/
chmod 400 ~/.ssh/*****.pem
ssh -i ~/.ssh/Tripost.pem ec2-user@ec*******.ap-northeast-1.compute.amazonaws.com

2. Docker のインストールと設定(Amazon Linux 2023)

EC2 上で Docker を使って開発環境に近い構成をそのまま再現。
開発環境と差が少ないので「動いたのに本番で動かない」問題が減る。

Amazon Linux 2023 は dnf を使用します。

sudo dnf update -y
sudo dnf install -y docker
sudo systemctl enable --now docker
docker --version

非 root ユーザーで Docker を使えるようにする

sudo usermod -aG docker ec2-user
newgrp docker

これで sudo なしで docker ps が動きます。

3. Docker Compose をインストール

Amazon Linux 2023 ではパッケージが無いため、バイナリから直接入れます。

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

4. GitHub からプロジェクトをクローン

sudo dnf install -y git
cd /home/ec2-user
git clone https://github.com/your-username/your-repo.git <プロジェクト名>
cd <プロジェクト名>
sudo chown -R ec2-user:ec2-user .

5. RDS の設定と接続確認

RDS 未作成の場合は先に作成しておきましょう。
EC2 から接続テスト:

sudo dnf install -y mariadb105
mysql -h (RDSのエンドポイント) -u admin -p

👉 パスワード入力 → mysql> プロンプトが出たら成功。
接続後、DB作成:

CREATE DATABASE (DB名) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

もし RDS で作成済みの DB 名が既にあるなら、新規作成は不要です。
名前を変える場合は .env.production と RDS の DB 名を必ず一致させること。
文字セットは utf8mb4 + utf8mb4_unicode_ci にしておくと絵文字や特殊文字も対応できます。

6. 環境変数ファイル .env.production の作成

nano .env.production
.env.production
APP_NAME=Tripost
APP_ENV=production
APP_KEY=base64:*****
APP_DEBUG=false
APP_URL=http://*****

APP_LOCALE=ja
APP_FALLBACK_LOCALE=ja
APP_FAKER_LOCALE=ja_JP

CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_CLIENT=phpredis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

DB_CONNECTION=mysql
DB_HOST=*****.rds.amazonaws.com
DB_PORT=3306
DB_DATABASE=*****-db
DB_USERNAME=admin
DB_PASSWORD=*****
# その他 APIキー / S3設定など
VITE_GOOGLE_MAPS_KEY=*****

.env.production は Git にコミットしないよう .gitignore に追記

echo ".env.production" >> .gitignore
chmod 600 .env.production

.env や設定ファイル: アプリ/デプロイプロセスがファイルを書き換える必要があるなら 600、読み取りだけなら 400 でも可。多くは 600 を使うのが無難。

7. Dockerfile と docker-compose.production.yml の準備

開発環境でLaravel Sailを使用している場合、本番環境では使用不可なのでNginx+PHP-FPMを構築する。
Dokerfile

Dokerfile
FROM php:8.3-fpm

# 必要パッケージ & PHP拡張
RUN apt-get update && apt-get install -y \
    git unzip curl libzip-dev libonig-dev libxml2-dev mariadb-client nodejs npm \
    procps iproute2 net-tools \
    && docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath zip

# phpredis 拡張を追加
RUN pecl install redis \
    && docker-php-ext-enable redis

# Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

# FPM listen を全インターフェースに変更
RUN sed -i 's/listen = .*/listen = 0.0.0.0:9000/' /usr/local/etc/php-fpm.d/www.conf

WORKDIR /var/www/html

# php-fpm をフォアグラウンドで起動
CMD ["php-fpm"]

docker-compose.production.yml

docker-compose.production.yml
services:
laravel:
  build:
    context: .
    dockerfile: Dockerfile
  container_name: *****-laravel
  env_file:
    - .env.production
  volumes:
    - .:/var/www/html
  ports:
    - "9000:9000"
  depends_on:
    - redis
  networks:
    - *****

nginx:
  image: nginx:1.25
  container_name: *****-nginx
  ports:                 
    - "80:80"
  volumes:
    - .:/var/www/html
    - ./nginx/conf.d:/etc/nginx/conf.d
  depends_on:
    - laravel
  networks:
    - *****


redis:
  image: redis:7
  container_name: *****-redis
  ports:
    - "6379:6379"
  networks:
    - *****

networks:
*****:
  driver: bridge

8. コンテナビルド & 起動

コンテナビルド & 起動

docker compose -f docker-compose.production.yml --env-file .env.production up -d --build
docker compose ps // laravel コンテナが Up になっているか確認

本番用APP_KEY作成:

docker compose -f docker-compose.production.yml exec laravel php artisan key:generate --show

docker compose -f docker-compose.production.yml exec laravel php artisan config:cache

9. マイグレーション & シード

docker compose -f docker-compose.production.yml exec laravel php artisan migrate --force
docker compose -f docker-compose.production.yml exec laravel php artisan db:seed --force

10. Nginx 設定(EC2 フロント用)

sudo amazon-linux-extras install nginx1 -y
sudo systemctl enable nginx
sudo systemctl start nginx

//ディレクトリ作成(存在しない場合)
sudo mkdir -p /etc/nginx/conf.d
//EC2 上の Nginx を Laravel コンテナのフロントとして動かす設定
sudo nano /etc/nginx/conf.d/*****.conf
//設定テスト
sudo nginx -t  
sudo systemctl restart nginx

11. React / Inertia.js のビルド設定

Inertia.js(React)で構築したフロントエンドを本番環境用にビルドします。
Vite を使用している場合、Laravel 側で JS / CSS を正しく読み込むための設定が必要です。

  • ビルドコマンドの実行
docker compose -f docker-compose.production.yml exec laravel npm install
docker compose -f docker-compose.production.yml exec laravel npm run build

もしエラーで「manifest.jsonが見つからない」と出た場合:

docker exec -it tripost-laravel bash
cp public/build/.vite/manifest.json public/build/manifest.json
chown -R www-data:www-data public/build
chmod -R 755 public/build
php artisan config:clear && php artisan cache:clear
exit
  • Laravel 側の設定確認
    resources/views/app.blade.php や vite.config.js、config/vite.php の設定を正しく行っていない場合も
    manifest 読み込みエラーが発生します。以下の設定を確認しましょう。

resources/views/app.blade.php

Laravel × Inertia.js のエントリーポイント。
Vite のビルド済み JS / CSS を読み込むよう指定します。

app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title inertia>{{ config('app.name', 'Laravel') }}</title>

      @routes
      @viteReactRefresh
      @vite([
        'resources/js/app.jsx',
        isset($page['component']) ? "resources/js/Pages/{$page['component']}.jsx" : null
      ])
      @inertiaHead
  </head>
  <body class="font-sans antialiased">
      @inertia
  </body>
</html>

vite.config.js

開発環境(npm run dev)と本番環境(npm run build)を切り替える設定です。
ビルド後のファイルは /public/build に出力されます。

vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

const isProduction = process.env.NODE_ENV === 'production';

export default defineConfig({
  plugins: [
    laravel({
      input: 'resources/js/app.jsx',
      refresh: !isProduction,
    }),
    react(),
  ],
  base: isProduction ? '/build/' : '/',
  build: {
    outDir: 'public/build',
    emptyOutDir: true,
    manifest: true,
    rollupOptions: {
      input: 'resources/js/app.jsx',
    },
    assetsDir: 'assets',
  },
});

config/vite.php

Laravel 側で Vite の manifest ファイルを参照できるようにします。
.vite/manifest.json ではなく build/manifest.json に変更しておくことが重要です。

config/vite.php
  <?php

return [
    /*
    |--------------------------------------------------------------------------
    | Vite manifest path
    |--------------------------------------------------------------------------
    |
    | Vite のビルド後 manifest.json のパス
    |
    */
    'manifest_path' => public_path('build/manifest.json'),
];

キャッシュクリア

docker compose -f docker-compose.production.yml exec laravel php artisan config:clear
docker compose -f docker-compose.production.yml exec laravel php artisan view:clear

12. HTTPS(Let’s Encrypt + Certbot)

//Certbotのインストール
sudo dnf install -y certbot python3-certbot-nginx

// Nginxコンテナを一時停止
docker stop tripost-nginx

// 証明書取得(your-domain.comを実際のドメインに置き換え)
sudo certbot certonly --standalone -d your-domain.com

// Nginxコンテナを再起動
docker start tripost-nginx

Nginx設定の更新。*****.conf に HTTPS 設定を追加:

# HTTP → HTTPS リダイレクト
server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    return 301 https://$host$request_uri;
}

# HTTPS設定
server {
    listen 443 ssl http2;
    server_name your-domain.com www.your-domain.com;

    # SSL証明書の設定
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    
    # SSL設定の最適化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # HSTS設定(セキュリティ強化)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    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 laravel:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        # HTTPS用パラメータ追加
        fastcgi_param HTTPS on;
        fastcgi_param SERVER_PORT 443;
    }

    location ~ /\.ht {
        deny all;
    }
    
    # Let's Encrypt用のアクセス許可
    location ~ /.well-known/acme-challenge {
        allow all;
        root /var/www/html/public;
    }

docker-compose.production.yml に HTTPS ポートを追加:

docker-compose.production.yml
ports:
  - "80:80"
  - "443:443"
volumes:
  - /etc/letsencrypt:/etc/letsencrypt:ro

また、.env.productionファイルの該当部分をhttpsへ変更しておく。

13. 証明書の自動更新(cron)

echo "0 0 * * 0 root certbot renew --quiet && docker restart tripost-nginx" | sudo tee -a /etc/crontab

14. 動作確認

http://<EC2のパブリックIP>
https://your-domain.com

まとめ

項目 内容
OS Amazon Linux 2023
Web サーバ Nginx (Docker)
アプリ Laravel + React (Inertia.js)
DB Amazon RDS (MySQL)
キャッシュ Redis
HTTPS Let’s Encrypt (Certbot)
デプロイ方式 Docker Compose + 手動更新 or CI/CD

この構成により、開発環境(Sail)とほぼ同等の構成を EC2 上で再現でき、
「開発では動いたのに本番で動かない」問題を大幅に減らすことができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?