NginxでLaravelを動作させるまでに行ったこと

はじめに

今回はNginxでLaravelを動作させるためにDocker上でNginx+PHP-FPM+MySQL環境を用意し、Laravelを動かす手順を紹介します。

ディレクトリ構成

docker-laravel-starter/
├── Makefile
├── docker-compose.yml
├── docker/
│   ├── app/
│   │   └── Dockerfile
│   ├── nginx/
│   │   └── nginx.conf
│   └── php/
│       └── php.ini
└── src/

ディレクトリ構成は上記の通りで各ファイルの説明をしていきます。

Makefile

.PHONY: up down build composer-install artisan

# コンテナ起動
up:
    docker-compose up -d
# コンテナ削除
down:
    docker-compose down
# コンテナ作成
build:
    docker-compose build

# webコンテナにssh接続
exec:
    docker-compose exec app bash

# LaravelのCLIコマンドを実行
artisan:
    docker-compose run --rm app php artisan

# Laravelプロジェクトを作成 (初回のみ実行、末尾で指定したバージョンのLaravelをインストール)
init:
    docker-compose run --rm app composer create-project --prefer-dist laravel/laravel=11 .

各コマンドの簡単な説明です。

  • up/down: Dockerコンテナの起動・停止を実行
  • build: Dockerイメージをビルド
  • exec: appコンテナ内でbashコマンドを実行
  • artisan: LaravelのArtisanコマンドを実行
  • init: Laravelの新規プロジェクトを作成(初回のみ実行する想定)

docker-compose.yml

services:
  app:
    build:
      context: ./docker/app
    container_name: laravel-app
    working_dir: /var/www/html
    volumes:
      - ./src:/var/www/html
      - ./docker/php/php.ini:/usr/local/etc/php/php.ini
    networks:
      - laravel
    depends_on:
      - mysql
  web:
    image: nginx:latest
    container_name: laravel-web
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./docker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
    networks:
      - laravel
    depends_on:
      - app
  mysql:
    image: mysql:8.0
    container_name: laravel-mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: laravel
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - laravel

  phpmyadmin:
    image: phpmyadmin:latest
    container_name: laravel-phpmyadmin
    ports:
      - "8081:80"
    environment:
      PMA_HOST: mysql
      MYSQL_ROOT_PASSWORD: root
    networks:
      - laravel
volumes:
  db_data:
networks:
  laravel:
  • app: PHP-FPMコンテナ。Dockerfileで必要なPHP拡張やComposerを導入するために使用しています
  • web: Nginxコンテナ。ポート8080をコンテナ内の80番にマッピングし、Laravelのpublicディレクトリをドキュメントルートに指定しています
  • mysql: MySQLコンテナ。DB名やユーザ名、パスワードを定義しました
  • phpmyadmin: DB操作をGUIで行える便利なパッケージ、ポート8081をコンテナ内の80にマッピングしてアクセスできるように設定しています

Dockerfile

FROM php:8.3-fpm

# 必要な依存パッケージをインストール
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    zip \
    && apt-get clean

# Composerをインストール
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# 作業ディレクトリを設定
WORKDIR /var/www/html
  • Composerをインストールして、Laravelのセットアップを容易にしました
  • 作業ディレクトリを /var/www/html に設定しています

nginx.conf

server {
    listen 80;

    server_name localhost;

    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 app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~ /\.ht {
        deny all;
    }
}
  • ポートは80にしました
  • root /var/www/html/public; でLaravelのpublicフォルダをルートに指定しています
  • .phpファイルのリクエストは fastcgi_pass app:9000; を通じてPHP-FPMコンテナへアクセスできるようにしました

php.ini

memory_limit=512M
upload_max_filesize=100M
post_max_size=100M
max_execution_time=300

このあたりは好みですが、初期設定より大きなファイルを扱うことを想定して設定を変更しました。

  • 大容量ファイルを扱う際の制限値を引き上げています
  • スクリプトの最大実行時間を300秒に設定しました

コンテナ起動とLaravel初期画面まで

Dockerイメージのビルド

make build

Dockerコンテナの起動

make up

docker-compose.ymlに定義された4つのコンテナ(app, web, mysql, phpmyadmin)を一斉に起動させます。appコンテナではPHP-FPMが稼働し、webコンテナがNginxの役割を担います。phpmyadminコンテナはGUIでDBを操作可能になります。

Laravelプロジェクトの新規作成

make init

指定バージョンのLaravelが src 以下にインストールされます。初回実行時のみ必要な手順で、すでに実行済みの場合は省略可能です。

ブラウザで確認

http://localhost:8080 にアクセスしてLaravelの初期表示が表示されます。

http://localhost:8081 にアクセスすれば、phpmyadminが表示されます。

終わりに

以上がNginxでLaravelを動作させるためにDockerとNginx、PHP-FPM、MySQLを使ったLaravelのセットアップ手順です。

今までApacheは使ったことがありましたがNginxは使ったことがなかったため、ところどころ苦戦したものの、とてもよい経験になったと思います。みなさんも同じようなものが必要であればこちらを参考にしてください。