Laravel 11 Docker 環境構築手順
この手順では、提出されたDockerfileおよび設定ファイルを使用して、Laravel 11の開発環境を構築する方法を説明します。
前提条件
- Dockerがインストールされていること
- Docker Composeがインストールされていること
バージョン
Laravel 11
PHP 8.3.10
node v18.20.2
npm 10.5.0
Composer version 2.8.1
1. プロジェクトディレクトリ構成
プロジェクトディレクトリを以下のように構成します。
.
├── docker-compose.yml
├── src
│ └── (Laravelのソースコードを配置)
├── mysql
│ ├── Dockerfile
├── web
│ ├── Dockerfile
│ ├── www.conf
│ └── entrypoint.sh
└── nginx
├── Dockerfile
└── nginx.conf
2. 各ファイルの内容
docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
dockerfile: web/Dockerfile
volumes:
- ./src:/usr/share/nginx/html
- ./web/www.conf:/etc/php-fpm.d/www.conf
ports:
- '5173:5173'
expose:
- 9000
- 5173
networks:
- app-network
nginx:
build:
context: .
dockerfile: nginx/Dockerfile
ports:
- '8443:443'
- '8085:80'
volumes:
- ./src:/usr/share/nginx/html:ro
depends_on:
- web
networks:
- app-network
mysql:
build:
context: .
dockerfile: mysql/Dockerfile
ports:
- '13306:3306'
expose:
- 3306
networks:
- app-network
networks:
app-network:
driver: bridge
web/Dockerfile
# Amazon Linuxの指定バージョンをベースイメージとして使用
FROM amazonlinux:2023.5.20241001.1
# パッケージのアップデートとインストールを実行
# - dnf update: 既存パッケージを最新バージョンに更新
# - dnf install: 必要なソフトウェアをインストール(例: nginx, PHP, MySQLなど)
RUN dnf update -y && \
dnf install -y nginx \ # Nginx(ウェブサーバー)
vim \ # vim(テキストエディタ)
openssl \ # OpenSSL(暗号化ライブラリ)
php8.3 \ # PHP 8.3(プログラミング言語)
php8.3-bcmath \ # PHPのBCMath拡張(高精度な数値計算用)
php8.3-cli \ # PHP CLI(コマンドライン用のPHP)
php8.3-common \ # PHP共通パッケージ
php8.3-fpm \ # PHP-FPM(FastCGI Process Manager、PHPの処理を効率化)
php8.3-mbstring \ # マルチバイト文字列処理用のPHP拡張
php8.3-mysqlnd \ # MySQL対応のPHP拡張
php8.3-zip \ # ZIPファイル操作用のPHP拡張
mariadb105 # MariaDB 10.5(MySQL互換のデータベース)
# Node.jsとnpmをインストールするためのセットアップ
# - dnf install: Node.jsとnpmをインストール
RUN dnf install -y nodejs npm # Node.jsとnpm(JavaScriptの環境、パッケージ管理ツール)
# PHP-FPMの実行に必要なディレクトリを作成し、適切な権限を設定
# - mkdir -p: ディレクトリを作成
# - chown: ディレクトリの所有者をnginxユーザーに設定
# - chmod: ディレクトリに適切なアクセス権を付与(770は読み書き実行権限)
RUN mkdir -p /run/php-fpm && \
chown -R nginx:nginx /run/php-fpm && \
chmod 770 /run/php-fpm
# Composerのインストール(PHP用のパッケージ管理ツール)
# - php -r: PHPでコマンドを実行する
# - copy: Composerのインストーラをダウンロード
# - composer-setup.php: Composerのインストーラを実行
# - unlink: インストール後、不要なインストーラファイルを削除
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
php composer-setup.php --install-dir=/usr/local/bin --filename=composer && \
php -r "unlink('composer-setup.php');"
# 作業ディレクトリを設定(ファイル操作のデフォルト場所)
WORKDIR /usr/share/nginx/html/
# アプリケーションソースコードをコンテナ内にコピー
# - src: ローカルのソースコードディレクトリ
# - /usr/share/nginx/html/: Nginxのドキュメントルート
COPY src /usr/share/nginx/html/
# PHP-FPMの設定ファイルをコンテナ内にコピー
COPY web/www.conf /etc/php-fpm/www.conf
# エントリーポイントスクリプトをコンテナ内にコピーし、実行権限を付与
# - entrypoint.sh: コンテナが起動する際に最初に実行されるスクリプト
RUN COPY web/entrypoint.sh /usr/local/bin/ && \
chmod +x /usr/local/bin/entrypoint.sh # 実行可能な権限を付与
# 外部に公開するポートを指定
# - 9000: PHP-FPMがリクエストを受け付けるポート
# - 5173: Vite(フロントエンドの開発ツール)が使うポート(例として記載)
EXPOSE 9000 5173
# コンテナが起動した際に実行されるスクリプトを指定
# - entrypoint.sh: コンテナ起動時に実行するスクリプト
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# コンテナが実行するデフォルトのコマンドを指定
# - php-fpm: PHP-FPMをフォアグラウンドで実行する
CMD ["php-fpm", "-F"]
web/www.conf
[www] ; この設定はPHP-FPMの "www" プールに関するものです。
; PHP-FPMを実行するユーザーとグループを設定
user = nginx
group = nginx
; PHP-FPMがリクエストを受け付けるアドレスとポートの設定
; すべてのネットワークインターフェースでポート9000をリッスン
listen = 0.0.0.0:9000
; リスンするソケットの所有者を "nginx" に設定
listen.owner = nginx
; リスンするソケットのグループを "nginx" に設定
listen.group = nginx
; リスンするソケットのアクセス権限を設定(読み書き可能)
listen.mode = 0660
; プロセスマネージャーの設定
; 動的にPHP-FPMのプロセス数を調整(リクエストに応じて増減)
pm = dynamic
; 同時に生成できる最大プロセス数(50に設定)
pm.max_children = 50
; サーバー起動時に生成されるプロセス数(5に設定)
pm.start_servers = 5
; 最小アイドルプロセス数(アイドルプロセスが少ない場合は追加)
pm.min_spare_servers = 5
; 最大アイドルプロセス数(アイドルプロセスが多すぎる場合は減らす)
pm.max_spare_servers = 35
; スローログの設定(長時間処理にかかるリクエストを記録)
; スローログの出力先ファイル
slowlog = /var/log/php-fpm/www-slow.log
; エラーログの設定
php_admin_value[error_log] = /var/log/php-fpm/www-error.log ; エラーログの出力先
php_admin_flag[log_errors] = on ; エラーログの記録を有効にする
; セッション関連の設定
php_value[session.save_handler] = files ; セッションの保存方法を "files" に設定(ファイルに保存)
php_value[session.save_path] = /var/lib/php/session ; セッションデータの保存パス
; SOAPキャッシュの設定
php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache ; SOAPのWSDLファイルのキャッシュディレクトリ
各設定項目の説明:
user
と group
PHP-FPMがnginx
ユーザーとグループで動作するように設定されています。セキュリティの観点から、サーバーソフトウェアを専用の非特権ユーザーで実行するのが一般的です。
listen
PHP-FPMがどのアドレスとポートでリクエストを受け付けるかを指定しています。この場合、0.0.0.0
はすべてのネットワークインターフェースを指し、ポート9000
で接続を待機します。
pm
(Process Manager)
PHP-FPMはプロセスマネージャーを使ってリクエストごとにプロセスを生成・破棄します。pm
設定でプロセス数の動的管理を行い、効率よくリソースを利用します。
slowlog
スローログは、特定の時間を超えて処理に時間がかかるPHPリクエストを記録するログです。長時間のリクエストをデバッグしたいときに役立ちます。
error_log
PHPエラーを記録するファイルのパスを指定し、ログをオンにする設定です。これにより、発生したエラーを追跡できます。
セッションの設定
PHPのセッションデータをファイルとして保存する方法が指定されており、保存場所は/var/lib/php/session
に設定されています。
SOAPのキャッシュ設定
SOAPリクエストを利用する場合、WSDL(Webサービス定義言語)ファイルのキャッシュ場所を指定します。これにより、SOAPリクエストのパフォーマンスが向上します。
web/entrypoint.sh
#!/bin/sh
chown -R nginx:nginx /usr/share/nginx/html && \
chmod -R 775 /usr/share/nginx/html/storage /usr/share/nginx/html/bootstrap/cache
# Execute the main process
exec "$@"
説明
chown -R nginx:nginx /usr/share/nginx/html
ディレクトリ全体の所有者をnginxユーザーに再帰的に変更します。
chmod -R 775 /usr/share/nginx/html/storage /usr/share/nginx/html/bootstrap/cache
Laravelのキャッシュおよびストレージディレクトリに対して適切な書き込み権限を設定します。
Laravelプロジェクトが存在しない場合は、スクリプトは次のメッセージを出力して処理をスキップします:
echo "Laravel project not found. Skipping permissions setup."
これにより、プロジェクトが存在しない場合でも、エラーが発生せずにスムーズに進行できるようになっています。
exec "$@":
このコマンドは、スクリプトに渡された引数(通常はCMDやdocker runで指定されたコマンド、例えばphp-fpmなど)を実行します。exec
は、シェルプロセスを指定されたコマンドに置き換える役割を持っており、これによりphp-fpmなどのメインプロセスが正常に起動します。コンテナが終了しないように、このプロセスはフォアグラウンドで実行され続けます。
nginx/Dockerfile
# ベースイメージとしてAmazon Linux 2023を使用
FROM amazonlinux:2023.5.20241001.1
# 必要なパッケージをインストール
# - dnf update: 既存のパッケージを最新バージョンに更新
# - dnf install: 必要なソフトウェアをインストール
RUN dnf update -y && \
dnf install -y nginx vim openssl # Nginx(ウェブサーバー)、vim(テキストエディタ)、openssl(SSL/TLS)
# SSL証明書や秘密鍵を保存するためのディレクトリを作成
# - /etc/pki/nginx/private: 秘密鍵を保存するディレクトリ
# - /etc/nginx/ssl: SSL証明書を保存するディレクトリ
RUN mkdir -p /etc/pki/nginx/private /etc/nginx/ssl
# OpenSSLを使って自己署名証明書を作成
# - openssl genrsa: 秘密鍵を生成(2048ビット)
# - openssl req: 証明書署名要求(CSR)を作成("/CN=localhost" で共通名をlocalhostに設定)
# - openssl x509: CSRに基づいて自己署名証明書を生成(365日間有効)
RUN openssl genrsa -out /etc/pki/nginx/private/server.key 2048 && \
openssl req -new -key /etc/pki/nginx/private/server.key -out /etc/pki/nginx/server.csr -subj "/CN=localhost" && \
openssl x509 -req -days 365 -in /etc/pki/nginx/server.csr -signkey /etc/pki/nginx/private/server.key -out /etc/pki/nginx/server.crt
# Nginxの設定ファイルをコンテナ内にコピー
# - nginx.conf: Nginxの主要な設定ファイル
COPY nginx/nginx.conf /etc/nginx/nginx.conf
# コンテナ外部に公開するポートを指定
# - 80: HTTP用ポート
# - 443: HTTPS用ポート
EXPOSE 80 443
# Nginxをフォアグラウンドで実行
# - daemon off: Nginxをデーモンとしてではなく、フォアグラウンドで実行してコンテナが終了しないようにする
CMD ["nginx", "-g", "daemon off;"]
nginx/nginx.conf
user nginx; # Nginxを実行するユーザーを指定
worker_processes auto; # ワーカープロセス数を自動で設定(CPUコア数に基づく)
error_log /var/log/nginx/error.log notice; # エラーログの出力先とログレベルを設定
pid /run/nginx.pid; # プロセスID(PID)ファイルのパスを指定
# 動的モジュールの設定を読み込む
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024; # 各ワーカープロセスが処理できる接続数を指定
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; # ログフォーマットを定義
access_log /var/log/nginx/access.log main; # アクセスログの出力先とフォーマットを指定
sendfile on; # 高速なファイル送信を行うためにsendfileを使用
tcp_nopush on; # データのまとめ送信でネットワークの効率を向上
keepalive_timeout 65; # クライアントとの接続を保持する時間(秒)
types_hash_max_size 4096; # MIMEタイプのハッシュテーブルの最大サイズを指定
include /etc/nginx/mime.types; # MIMEタイプ定義ファイルを読み込む
default_type application/octet-stream; # 拡張子がないファイルに対するデフォルトMIMEタイプを設定
# /etc/nginx/conf.d/ディレクトリ内の設定ファイルを読み込む
include /etc/nginx/conf.d/*.conf;
server {
listen 80; # ポート80でHTTPリクエストを受け付ける
server_name localhost; # このサーバーブロックが処理するホスト名を指定
root /usr/share/nginx/html/public; # ドキュメントルートを設定(Laravelのpublicディレクトリ)
add_header X-Frame-Options "SAMEORIGIN"; # クリックジャッキング防止
add_header X-Content-Type-Options "nosniff"; # MIMEタイプの推測を防止
index index.php; # デフォルトのインデックスファイルを指定
charset utf-8; # UTF-8文字エンコーディングをデフォルトで使用
location / {
try_files $uri $uri/ /index.php?$query_string; # ファイルやディレクトリがなければindex.phpにリクエストを渡す
}
location = /favicon.ico { access_log off; log_not_found off; } # favicon.icoへのアクセスログを無効化
location = /robots.txt { access_log off; log_not_found off; } # robots.txtへのアクセスログを無効化
error_page 404 /index.php; # 404エラーが発生した場合、index.phpにリクエストを転送
ssl_certificate "/etc/pki/nginx/server.crt"; # SSL証明書のパス
ssl_certificate_key "/etc/pki/nginx/private/server.key"; # SSL証明書の秘密鍵のパス
ssl_session_cache shared:SSL:1m; # SSLセッションキャッシュの設定
ssl_session_timeout 10m; # SSLセッションのタイムアウト時間
ssl_ciphers PROFILE=SYSTEM; # 使用する暗号スイートを指定
ssl_prefer_server_ciphers on; # サーバーが優先する暗号スイートを使用
# PHPファイルの処理をPHP-FPMに渡す設定
location ~ \.php$ {
fastcgi_pass web:9000; # PHP-FPM(port 9000)にリクエストを渡す
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # 実際のPHPファイルパスを指定
include fastcgi_params; # FastCGIのパラメータをインクルード
fastcgi_hide_header X-Powered-By; # セキュリティのためにX-Powered-Byヘッダーを隠す
}
# デフォルトサーバーブロックの設定を読み込む
include /etc/nginx/default.d/*.conf;
# 隠しファイル(.で始まるファイル)へのアクセスを禁止
location ~ /\.(?!well-known).* {
deny all;
}
}
# TLS対応サーバーの設定
server {
listen 443 ssl http2; # HTTPSリクエストをポート443で受け付ける
server_name localhost; # このサーバーブロックが処理するホスト名を指定
root /usr/share/nginx/html/public; # ドキュメントルートを指定(Laravelのpublicディレクトリ)
add_header X-Frame-Options "SAMEORIGIN"; # クリックジャッキング防止
add_header X-Content-Type-Options "nosniff"; # MIMEタイプの推測を防止
index index.php; # デフォルトのインデックスファイルを指定
charset utf-8; # UTF-8文字エンコーディングをデフォルトで使用
location / {
try_files $uri $uri/ /index.php?$query_string; # ファイルやディレクトリがなければindex.phpにリクエストを渡す
}
location = /favicon.ico { access_log off; log_not_found off; } # favicon.icoへのアクセスログを無効化
location = /robots.txt { access_log off; log_not_found off; } # robots.txtへのアクセスログを無効化
error_page 404 /index.php; # 404エラーが発生した場合、index.phpにリクエストを転送
ssl_certificate "/etc/pki/nginx/server.crt"; # SSL証明書のパス
ssl_certificate_key "/etc/pki/nginx/private/server.key"; # SSL証明書の秘密鍵のパス
ssl_session_cache shared:SSL:1m; # SSLセッションキャッシュの設定
ssl_session_timeout 10m; # SSLセッションのタイムアウト時間
ssl_ciphers PROFILE=SYSTEM; # 使用する暗号スイートを指定
ssl_prefer_server_ciphers on; # サーバーが優先する暗号スイートを使用
# PHPファイルの処理をPHP-FPMに渡す設定
location ~ \.php$ {
fastcgi_pass web:9000; # PHP-FPM(port 9000)にリクエストを渡す
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # 実際のPHPファイルパスを指定
include fastcgi_params; # FastCGIのパラメータをインクルード
fastcgi_hide_header X-Powered-By; # セキュリティのためにX-Powered-Byヘッダーを隠す
}
# デフォルトサーバーブロックの設定を読み込む
include /etc/nginx/default.d/*.conf;
# 隠しファイル(.で始まるファイル)へのアクセスを禁止
location ~ /\.(?!well-known).* {
deny all;
}
}
}
mysql/Dockerfile
# ベースイメージとして公式のMySQLイメージを使用
FROM mysql:8.0
# データベース名の設定
ENV MYSQL_DATABASE=laravel_db
# データベースユーザーの設定
ENV MYSQL_USER=laravel_user
# データベースユーザーのパスワード設定
ENV MYSQL_PASSWORD=laravel_password
# ルートユーザーのパスワード設定(必要に応じて変更)
ENV MYSQL_ROOT_PASSWORD=root_password
# 初期化用SQLスクリプトを追加(任意、必要な場合のみ)
# ADD init.sql /docker-entrypoint-initdb.d/
# ポートの公開
EXPOSE 3306
3. 環境構築手順
プロジェクトディレクトリを作成
mkdir laravel-docker && cd laravel-docker
ファイルを作成・配置
上記のdocker-compose.yml
、web/Dockerfile
、nginx/Dockerfile
、nginx.conf
などのファイルをそれぞれのディレクトリに配置します。
Laravelプロジェクトを準備
src
フォルダ内にLaravelのソースコードを配置します。まだプロジェクトがない場合は、以下のコマンドで作成できます。
cd src
composer create-project --prefer-dist laravel/laravel .
コンテナをビルド・起動
docker-compose up --build -d
セットアップ
- webコンテナに入る
docker compose exec web bash
- Composerパッケージのインストール
LaravelのPHPパッケージをインストールします。これにより、アプリケーションの必要なライブラリがすべてインストールされます。composer install
- Laravelアプリケーションキーの生成
php artisan key:generate
- Breezeのインストール
php artisan breeze:install react --typescript
- Inertiaをインストール
composer require inertiajs/inertia-laravel npm install @inertiajs/inertia-react
- フロントエンドの依存関係のインストール
npm install
- データベースのマイグレーション
php artisan migrate
- vite.config.jsの設定
vite.config.jsは、LaravelプロジェクトにViteを導入した際に使用する設定ファイルです。Viteはフロントエンドのビルドツールで、特にReactなどのJavaScriptフレームワークとの組み合わせで、高速な開発環境を提供します。
ファイルパス: src/vite.config.js
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [
laravel({
input: "resources/js/app.jsx",
refresh: true,
}),
react(),
],
server: {
host: "0.0.0.0",
hmr: {
host: "localhost",
},
watch: {
usePolling: true,
},
port: 5173,
},
});
設定内容の説明
plugins セクション
この部分は、ViteにLaravelとReactのプラグインを使うように指示しています。
-
input: "resources/js/app.jsx"
という設定で、メインのJavaScriptファイルであるapp.jsx
をエントリポイントとして指定しています。これは、Reactコンポーネントが使用されるファイルです。
-refresh: true
は、開発中にコードが変更された際、ブラウザが自動でリロードされるように設定するオプションです。 - reactプラグイン: これはViteにReactをサポートさせるためのプラグインです。Reactを使っている場合は必ず追加します。
server
セクション
ここでは、Vite開発サーバーに関する設定を行っています。
-
host: "0.0.0.0"
: 開発サーバーを0.0.0.0で起動することで、ネットワーク内の他のデバイスからもアクセスできるようにします。通常の開発ではこの設定は必要ないかもしれませんが、特定のネットワーク環境で使う場合に便利です。 -
hmr: { host: "localhost" }
: HMR(Hot Module Replacement)は、コードが変更されたときにページをリロードせずに新しいコードに置き換える機能です。ここでは、HMRが動作するホスト名をlocalhostに設定しています。 -
watch: { usePolling: true }
: この設定は、ファイルの変更を検出するために「ポーリング」という手法を使用します。特定の環境やファイルシステムの問題がある場合に役立ちます。 -
port: 5173
: 開発サーバーが動作するポート番号を指定しています。デフォルトでは5173番ポートでViteが動作するように設定されています。
tsconfig.jsonの各オプションについて
{
"compilerOptions": {
"allowJs": true,
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"isolatedModules": true,
"target": "ESNext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"noEmit": true,
"paths": {
"@/*": ["./resources/js/*"],
"ziggy-js": ["./vendor/tightenco/ziggy"]
}
},
"include": ["resources/js/**/*.ts", "resources/js/**/*.tsx", "resources/js/**/*.d.ts"]
}
allowJs
: true
JavaScriptファイル(.js)をTypeScriptプロジェクト内で許可します。必要がなければfalseにすることも可能です。プロジェクトが完全にTypeScript化されている場合は、特にJavaScriptを許可する必要はないかもしれません。
module
: "ESNext"
最新のECMAScriptモジュールシステム(ES Modules)を使用します。特に問題はありません。ESNextは将来のJavaScriptの標準を指しますが、他のモジュールシステムを使用する必要がある環境(例えば、Node.jsの特定バージョン)であれば調整が必要です。
moduleResolution
: "bundler"
これは、Viteなどのモジュールバンドラーで推奨される設定です。WebpackやViteなど、モジュールバンドラーに依存している場合は問題ありません。
jsx
: "react-jsx"
React 17以降のjsx自動インポートを利用する設定です。特に問題ありません。React 17以前を使用している場合は、reactに変更する必要があります。
strict
: true
厳格な型チェックを有効にします。TypeScriptの推奨設定で、開発中に潜在的なバグを防ぐのに役立ちます。
isolatedModules
: true
モジュールごとにTypeScriptコンパイルを独立して行う設定です。これはViteやWebpackなどのモジュールバンドラーとの互換性を高めるため、問題ありません。
target
: "ESNext"
出力するJavaScriptのターゲットバージョンです。最新のJavaScript(ESNext)に設定しているため、モダンなブラウザや環境では問題なく動作します。
esModuleInterop
: true
CommonJSとESモジュールの互換性を有効にします。多くのパッケージとの互換性を保つために推奨される設定です。
paths
:
"@/*": ["./resources/js/*"]
エイリアスを設定しており、@/Components
のような簡単なインポートパスを実現できます。これは推奨される構成で、特に問題ありません。
"ziggy-js": ["./vendor/tightenco/ziggy"]
ziggy-js
をエイリアスとして設定しています。Laravelのziggy
ライブラリが使われている場合、適切にモジュールが解決されるようにしています。
キャッシュのクリア
設定の変更や環境設定に関連するキャッシュをクリアして、Laravelが最新の設定を反映するようにします。
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan config:cache
4. その他設定
環境ファイルの設定
src/.env
ファイルで、データベースなどの設定を変更します。MySQLコンテナのホスト名はmysql
です。
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=root
DB_PASSWORD=root_password
権限設定
Laravelのstorage
やbootstrap/cache
ディレクトリの権限を適切に設定します。
chmod -R 775 src/storage src/bootstrap/cache
ブラウザでアクセス
http://localhost:8085
でLaravelのウェブサイトにアクセスできます。
https://localhost:8443
でSSL経由のアクセスが可能です。