Mac環境におけるDockerを使用したNginx、PHP、MySQL環境の構築と負荷分散の実装

環境構成

検証環境および前提条件は以下の通りです。

  • OS: macOS Sonoma 14.3
  • アーキテクチャ: Apple Silicon (M3 Pro)
  • コンテナ管理: OrbStack または Docker Desktop 25.0.5
  • ターミナル: iTerm2

1. PHP-FPM環境の構築

まず、PHPアプリケーションの実行環境を準備します。PHP 8.2のFPMイメージを使用し、ソースコード用のディレクトリをローカルにマウントします。

# ワーキングディレクトリの作成
mkdir -p ~/workspace/docker-project/src

# PHPコンテナの起動(バックエンド処理用)
docker run -d \
  --name php-backend \
  -v ~/workspace/docker-project/src:/var/www/html \
  php:8.2-fpm

2. Nginx環境の構築と連携

Nginxのデフォルト設定をローカルに取り出し、PHPとの連携設定を行った上でコンテナを起動します。

設定ファイルの抽出

設定ファイルの編集を容易にするため、一度ダミーコンテナを起動して設定ファイルをホストマシンへコピーします。

# ダミーコンテナ起動
docker run --name nginx-tmp -d nginx

# 設定ファイルのコピー
mkdir -p ~/workspace/docker-project/nginx
docker cp nginx-tmp:/etc/nginx ~/workspace/docker-project/nginx/conf
docker cp nginx-tmp:/usr/share/nginx/html ~/workspace/docker-project/src

# ダミーコンテナの削除
docker stop nginx-tmp && docker rm nginx-tmp

Nginxコンテナの起動とネットワーク設定

PHPコンテナと通信するために、カスタムブリッジネットワークを作成し、そこに両方のコンテナを接続します。

# 共通ネットワークの作成
docker network create app-net

# Nginxコンテナの起動
docker run -d \
  --name web-server \
  -p 8080:80 \
  -v ~/workspace/docker-project/src:/usr/share/nginx/html \
  -v ~/workspace/docker-project/nginx/conf:/etc/nginx \
  --network app-net \
  nginx

PHP処理の設定編集

ローカルにコピーした設定ファイル(nginx/conf/conf.d/default.conf)を修正し、PHPスクリプトのリクエストをphp-backendコンテナへ転送するように設定します。

location ~ \.php$ {
    fastcgi_pass   php-backend:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
    include        fastcgi_params;
}

3. データベースとキャッシュサーバーの導入

MySQLの構築

docker run -d \
  --name db-server \
  -e MYSQL_ROOT_PASSWORD=dev_root_pass \
  -p 3306:3306 \
  --network app-net \
  mysql:8.0

コンテナ内部からホストマシン上のMySQLデータベースに接続する必要がある場合は、接続ホスト名をhost.docker.internalに設定します。

Redisの構築

docker run -d \
  --name cache-server \
  --network app-net \
  redis:7-alpine

4. Nginxによる負荷分散の実装

複数のWebサーバーに対してトラフィックを分散する構成を構築します。Dockerのユーザー定義ネットワークを活用することで、コンテナ名をホスト名として利用し、IPアドレスの管理を簡略化します。

Webサーバー用コンテナの群作成

3つのWebサーバー(web-node-01, web-node-02, web-node-03)を起動し、それぞれ内部ポート80で待ち受けさせます。

docker run -d --name web-node-01 -p 8081:80 --network app-net -v ~/workspace/docker-project/src:/usr/share/nginx/html nginx
docker run -d --name web-node-02 -p 8082:80 --network app-net -v ~/workspace/docker-project/src:/usr/share/nginx/html nginx
docker run -d --name web-node-03 -p 8083:80 --network app-net -v ~/workspace/docker-project/src:/usr/share/nginx/html nginx

ロードバランサーの設定

新たにNginxコンテナ(lb-server)を作成し、upstream設定を用いてトラフィックを上記のノードへ振り分けます。IPアドレスを直指定する代わりに、コンテナ名で解決します。

# lb.confの設定内容
upstream backend_cluster {
    least_conn;
    server web-node-01 weight=3 max_fails=3 fail_timeout=30s;
    server web-node-02 weight=3 max_fails=3 fail_timeout=30s;
    server web-node-03 weight=4 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name lb.example.local;

    location / {
        proxy_pass http://backend_cluster;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

この設定ファイルをマウントしてロードバランサーを起動します。

docker run -d \
  --name lb-server \
  -p 80:80 \
  -v ~/workspace/docker-project/nginx/conf/lb.conf:/etc/nginx/conf.d/default.conf \
  --network app-net \
  nginx

5. Docker操作リファレンス

構築および運用における主要なコマンド一覧です。

# ネットワークの一覧表示
docker network ls

# コンテナのIPアドレス確認
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web-node-01

# 実行中のコンテナへの設定ファイルコピー
docker cp ./nginx.conf web-server:/etc/nginx/conf.d/custom.conf

# コンテナの再起動
docker restart web-server

# 複数コンテナの削除(停止済みのもの)
docker container prune

タグ: Docker nginx php-fpm MySQL redis

8月9日 14:44 投稿