🦋

UbuntuベースでLaravelを動かすDocker環境構築

に公開

はじめに

本記事では、UbuntuベースでWebサーバー(nginx)とAPサーバー(PHP-FPM)のDockerイメージを構築し、Laravelアプリが動作する環境を一から作りながら、その仕組みを学んでいきます。

🤔 なぜUbuntuベースでイメージを作るのか?

公式イメージ(php:8.3-fpm など)は便利ですが、中に何が入っていてどう動いているかがブラックボックスになりがちです😭
Ubuntuベースで自作することで、

  • どんなパッケージを入れているか
  • なぜそれが必要なのか

といった仕組みを理解することができます。

💡 実運用やチーム開発では、公式イメージを使う方が効率的です。

🛠 この環境でできること(目的)

  • Laravelの開発環境をDockerで構築する
  • UbuntuベースでWebサーバー(nginx)とAPサーバー(PHP-FPM)をそれぞれ構築
  • localhost:8080 にアクセスして Laravel の welcome ページを確認できる

🌟 前提条件(この手順を進める前に)

以下のツールがローカルPCにインストールされていることを前提としています:

ツール 用途 確認コマンド
Docker コンテナ実行環境 docker -v
Docker Compose 複数コンテナの定義と管理 docker compose version
Composer Laravelプロジェクトの作成 composer -V
PHP(8.1以上) Composerが動くために必要 php -v
Git Laravel内部やComposerで利用されることがある git --version

💡 Docker Desktop をインストールしていれば、Docker + Compose は含まれています。

📁 最終的なディレクトリ構成

.
├── docker-compose.yml
├── docker
│   ├── app
│   │   ├── Dockerfile         # PHP-FPM (APサーバー) 用
│   │   └── www.conf           # PHP-FPM プール設定ファイル
│   └── web
│       ├── Dockerfile         # nginx (Webサーバー) 用
│       └── default.conf       # nginx の設定ファイル
├── src                        # Laravelプロジェクト

🧠 前提知識

  • Docker
    1台のPC上に、アプリごとに独立した「小さな実行環境」を作って動かせる仕組み。
    仮想マシンのようにOSを丸ごと起動するのではなく、ホストOSのカーネルを共有して軽量に動く。

  • Dockerfile
    Docker環境を作るための設計書。
    どのOSイメージを使うか、どのソフトを入れるかを記述する。

  • イメージ
    Dockerfileから作られるコンテナの元データ。
    動かす前の状態で、起動するとコンテナになる。

  • コンテナ
    イメージを実際に起動したもの。中でアプリが動く。
    ホストOS上で隔離されたプロセス群として動作し、独立した環境のように振る舞う。

  • webサーバー (nginx)
    ブラウザからのHTTPリクエストを受け取り、
    静的ファイルは自分で返し、動的処理はAPサーバーに渡す。

  • APサーバー (php-fpm)
    Webサーバーから渡されたリクエストを受け、
    PHPやLaravelなどのアプリを実行し、結果を返す。

  • PHP-FPM
    PHPを常駐プロセスとして管理・実行するサービス。

  • FastCGI
    WebサーバーとAPサーバーをつなぐための通信プロトコル。
    HTTPではなく、内部向けの高速なバイナリ通信でデータをやり取りする。


ここからは手順の説明をしていきます🏃‍♀️

1. リポジトリの準備

まずは、LaravelのプロジェクトとDocker用の設定ファイルを整理して置くための「フォルダ構成」を作ります。

mkdir docker-laravel            # プロジェクト用のフォルダを作る
cd docker-laravel               # フォルダの中に移動
mkdir -p docker/app docker/web  # Docker設定ファイル用のサブフォルダを作る(AP・WEB用)

📁 完成イメージ:

docker-laravel/
├── docker/        ← Docker設定ファイルを置く
│   ├── app/       ← PHP(APサーバー)用
│   └── web/       ← nginx(Webサーバー)用
└── src/           ← Laravelのソースコードを配置する場所

*srcディレクトリは次で作成されます

2. Laravel プロジェクトの作成

次に、Laravelのアプリ本体を作成します。

composer create-project laravel/laravel ./src

これを実行すると、公式のLaravelプロジェクト一式が src/ ディレクトリの中にインストールされます。

📦 ここでLaravelアプリの中身を手に入れている

3. Dockerfile・設定ファイルの作成

🔸docker/web/Dockerfile

# Ubuntuベース
FROM ubuntu:22.04

# nginxをインストールし、不要なキャッシュを削除
RUN apt-get update \
    && apt-get install -y nginx \
    && rm -rf /var/lib/apt/lists/*

# コンテナが即終了しないようにフォアグラウンドでnginxを実行
CMD ["/usr/sbin/nginx", "-g", "daemon off;"]

🔸docker/web/default.conf(nginxの設定ファイル)

server {
    # ポート80(HTTP)で待ち受ける
    listen 80;

    # localhost にアクセスしたときに適用
    server_name localhost;

    # Web公開ディレクトリ
    root /var/www/html/public;

    # ディレクトリアクセス時に探すデフォルトファイル
    index index.php index.html;

    # ルート配下(全URL)へのルール
    location / {
         # 静的ファイルがなければ index.php に処理を渡す
        try_files $uri $uri/ /index.php?$query_string;
    }

    # .php のリクエストの処理
    location ~ \.php$ {
        include fastcgi_params; # FastCGI 用のパラメータを読み込み
        fastcgi_pass app:9000;  # PHP-FPM(app:9000)に処理を転送
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

🔸docker/app/Dockerfile

# Ubuntuベース
FROM ubuntu:22.04

# apt install 時の対話を防止
ENV DEBIAN_FRONTEND=noninteractive

# 外部からPHPを追加インストールするための準備ツールを入れる
# curl や unzip、git などもここでまとめてインストール
RUN apt-get update && apt-get install -y --no-install-recommends \
    software-properties-common lsb-release curl ca-certificates gnupg2 unzip git

# PHPの最新版が使える外部リポジトリ(ondrej/php)を追加
RUN add-apt-repository ppa:ondrej/php -y && apt-get update

# PHP8.3 + Laravel拡張のインストール
RUN apt-get install -y --no-install-recommends \
    php8.3-cli php8.3-fpm php8.3-mysql php8.3-sqlite3 \
    php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-zip php8.3-intl

# 不要なキャッシュ削除
RUN rm -rf /var/lib/apt/lists/*

RUN mkdir -p /run/php

# 作業ディレクトリ(Laravelをここに展開)
WORKDIR /var/www/html

# Composerを実行できるようにする準備
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer

# フォアグラウンドで php-fpm
CMD ["/usr/sbin/php-fpm8.3", "-F"]

🔸docker/app/www.conf(PHP-FPMの設定ファイル)

PHPプロセスの起動・管理の設定をする

[www]

; 実行ユーザー・グループ(Ubuntuでは通常 www-data)
user = www-data
group = www-data

; TCP 9000 番ポートで待ち受け(別コンテナの nginx から接続できる)
listen = 0.0.0.0:9000

; プロセスマネージャ(pm)設定
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

; 開発用途:.env の環境変数を PHP に引き継ぐ
clear_env = no

🔸docker-compose.yml

version: "3.9" # Docker Compose ファイルのバージョン

services:
  # APサーバー(PHP + Laravel 実行)
  app: 
    build: 
      context: ./docker/app # このフォルダ内のDockerfileを使ってビルド
      dockerfile: Dockerfile # 使用するDockerfileの名前

    # ホストPCのアプリをコンテナから見られるように設定(ビルドし直さなくても同期される)
    volumes: 
      # Laravelのソースコードをコンテナにマウント
      - ./src:/var/www/html 
     # PHP-FPM の設定ファイルを読み取り専用でマウント
      - ./docker/app/www.conf:/etc/php/8.3/fpm/pool.d/www.conf:ro

    # コンテナに入った時の初期ディレクトリを指定
    working_dir: /var/www/html

  # Webサーバー(nginx)
  web: 
    build:
      context: ./docker/web
      dockerfile: Dockerfile

    # ホストの8080番を、nginxの80番に接続(http://localhost:8080でアクセス)
    ports:
      - "8080:80"

    # ホストPCのアプリをコンテナから見られるように設定(ビルドし直さなくても同期される)
    volumes:
      # publicフォルダだけをnginxに見せる
      - ./src/public:/var/www/html/public:ro
      # nginxの設定ファイルをマウント
      - ./docker/web/default.conf:/etc/nginx/sites-available/default:ro

    depends_on:
      - app # appサービスを先に起動するよう指示

4. コンテナのビルドと起動

docker compose up -d --build

Laravel の welcome 画面が localhost:8080 に表示されたら成功!

💡 技術的な補足解説

👫 コンテナ間の連携

  • docker-compose.yml で定義した services は、同一ネットワーク上に配置される
  • 同じネットワークにあると、サービス名がDNS名として解決され、nginx から app:9000 のようにアクセスできる

⛰️ volume(ボリューム)の意味

  • 開発時:volumes: - ./src:/var/www/html のようにして、ホストのコード変更が即コンテナに反映されるようにする
  • 本番時:コードをボリュームではなくイメージに含めることが多い
    (セキュリティ・安定性のため)

🔄 ビルドと作業ディレクトリ

  • Dockerfile のWORKDIR:ビルド時・CMD/RUN のカレントディレクトリに影響
  • docker-compose.yml のworking_dir:コンテナ実行時のカレントディレクトリ

🎁 Webサーバー(nginx)

  • 役割:静的ファイルの配信やPHPファイルをAPサーバーへ中継
  • Laravelプロジェクトでは public/ 配下のみ見せる
  • default.confでルーティング制御の設定をする

🎁 APサーバー(php-fpm)

  • 役割:PHPコードを実行してHTMLなどのレスポンスに変換する
  • Laravelのロジック(Controller, Modelなど)はここで実行される
  • www.confで設定をする

🔌 nginxとphp-fpmの通信方式

  • UNIXソケット:高速・安全だが同一ホスト内専用
  • TCP通信:listen = 9000 にして、別コンテナからも接続可能にする
    ➡️ Dockerでは別コンテナになるためTCP化が必要(listen = 0.0.0.0:9000

🔁 リクエストの流れ(http://localhost:8080/hoge)

1. ブラウザ → nginx (port:8080)
2. nginx が public/index.php にリダイレクト
(try_filesで静的ファイルは返す、なければ index.php にリダイレクト)
3. nginx → FastCGI プロトコルで APサーバー(php-fpm)に中継(fastcgi_pass app:9000)
4. php-fpm が Laravel を起動 → routes/web.php にルーティング
5. レスポンスがブラウザに返る
  • nginxはHTTPを受けるフロント
  • nginxは .php を自分で実行できないので FastCGIでPHP-FPMに渡す
  • PHP-FPMがPHPを動かし、Laravelが処理した結果をnginxに返す

📝 最後に

この構成を通して、「Dockerって実際にこうつながってるんだ!」という理解と手応えが得られたら大成功です☺️

ぜひ手元で動かしながら、試行錯誤してみてください!

参考記事

https://zenn.dev/toshi052312/articles/caabb8821d6f59

Discussion