Nginxとphp-fpmのイメージを使ってphpの開発環境を構築してみた...

PCの環境

  • Mac(intel) Catalina 10.15.7
  • Docker version 20.10.8

ディレクトリの構成

project
    ├── docker
    │   ├── php
    │   │   ├── php.ini
    │   │   └── Dockerfile
    │   └── nginx
    │       └── default.conf
    ├── source
    │   └── index.php
    └── docker-compose.yml
  • Dockerfileなどの設定ファイルは、dockerディレクトリ内に置く。
  • ブラウザに表示するphpファイルなどは、sourceディレクトリ内に置く。

①phpのDockerfileを作成する

project/docker/php/Dockerfile

FROM php:7.4.9-fpm

COPY php.ini /usr/local/etc/php/

RUN apt update

WORKDIR /var/www

以下説明

# 使用するphpのイメージ
FROM php:7.4.9-fpm
  • PHPを動作させるためには、phpモジュールを使うか、またはcgiを使う必要がある。
  • Nginxにはphpのモジュールがないので、cgiを使って動作させる。(Apacheにはphpのモジュールがある)
  • php-fpmはPHPをCGIとして実行するためのツール、今回は、すでにphp-fpmがインストールされているイメージを使う。
# php.iniをコピー(書き換え)する。
COPY php.ini /usr/local/etc/php/

# OS(dockerイメージ)のupdateする
RUN apt update

# カレントディレクトリを/var/wwwにする
WORKDIR /var/www

②dockerイメージ内の/usr/local/etc/php/php.iniの書き換えファイルを作成する

書き換える内容は次のとおり。 project/docker/php/php.ini

# timezoneを日本時間に指定する
date.timezone = "Asia/Tokyo"

# 文字コードをUTF-8にして、日本語のマルチバイトを使えるようにする。
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
  • php.iniはphpの設定ファイル

③Nginxの設定ファイルを作成する

project/docker/nginx/default.conf

server {
    listen 80;
    index index.php index.html;
    server_name localhost;

    root /var/www;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Nginxのconfの説明

    # 使用するポートを指定
    listen 80;

    # indexページを指定
    index index.php index.html;

    # ホスト名を指定
    server_name localhost;
    # 公開ディレクトリを指定
    # $document_root の値
    root /var/www;

    # リクエストに応じたファイルを返す設定
    # $is_argsはリクエストに引数がある場合は「?」、引数がない場合は空文字列
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
# phpファイルにアクセスがあった場合の処理
 location ~ \.php$ {
        # URIをphp拡張子の前後で分割する
        # ( .+\.php ) は $fastcgi_script_name[実行するphpのファイル名] を取得
        # ( /.+ ) は $fastcgi_path_info[phpに渡すパス情報パラメータ]を取得
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # Nginxとphp-fpmを起動しているサーバーとの接続(通信はTCP)
        # phpコンテナ内のwww.confでは、listen = 127.0.0.1:9000がデフォルト設定
        # php:9000のphpはdocker-compose.ymlで定義するコンテナ名
        fastcgi_pass php:9000;

        # $fastcgi_script_name変数の値で、スラッシュで終わるURIの後に追加されるファイル名を設定
        fastcgi_index index.php;

        # phpを実行するのに必要なパラメータの設定ファイル(/etc/nginx/fastcgi_params)を読み込む
        # fastcgi_param SCRIPT_NAME/PATH_INFOより上に記載する
        include fastcgi_params;
                
        # スクリプトとパラメータを渡す設定
        # 実行するスクリプトのパス(ルートディレクトリ/実行するファイル名)
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # パス情報パラメータ($_SERVER['PATH_INFO'])
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

④docker-compose.ymlファイル作成する

docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:1.21.1
    ports:
      - "80:80"
    volumes:
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php

  php:
    build: ./docker/php
    volumes:
      - ./source:/var/www/

※ymlファイルは、フォーマット(インデントなど)が決まっているので記載時に注意。

# Composeのファイルフォーマットのバージョン(バージョンによって書き方が異なる)
version: '3.8'
# Nginxのコンテナを定義
  nginx:
    # nginxのイメージを公式から取得する
    image: nginx:1.21.1

    # PCから80番ポートにアクセスがあったらコンテナの80番ポートを使う
    # もし、PCで8080番ポートからアクセスさせたいときは8080:80とする(:の左がコンテナの外、右がコンテナ)
    ports:
      - "80:80"

    # PCとコンテナ内のデータを共有して、nginxの設定を反映させる(:の左がコンテナの外、:の右がコンテナ内)
    volumes:
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf

    # phpのコンテナが起動してからNginxのコンテナを起動させる
    depends_on:
      - php
  # phpのコンテナを定義
  php:
    # DockerfileからイメージをつくるのでDockerfileがあるパスを指定
    build: ./docker/php

    # PCとコンテナ内のデータを共有する(:の左がコンテナの外、:の右がコンテナ内)
    # PCのファイルを書き換えるとコンテナ内のファイルも書き換わる
    volumes:
      - ./source:/var/www/

⑤docker composeでコンテナを起動させる。

ターミナルを起動させ、docker-compose.ymlファイルがあるディレクトリ内に移動して実行する。

# projectディレクトリに移動
cd project

# コンテナを起動する。オプションの-dは、バックグラウンドで起動、--buildはDockerfileに基づき、最初からイメージをつくるということ
docker compose up --build -d

⑥正常に起動しているかを確認する

# コンテナの起動を確認
docker compose ps

# 次のように2つのコンテナがつくられ、STATUSがrunningになっていれば正常に起動している
NAME                COMMAND                  SERVICE             STATUS              PORTS
project_nginx_1   "/docker-entrypoint.…"   nginx               running             0.0.0.0:80->80/tcp, :::80->80/tcp
project_php_1     "docker-php-entrypoi…"   php                 running             9000/tcp

⑦project/source/index.phpを用意する。

<?php echo phpinfo(); ?>

ブラウザ(Google chromeなど)で http://localhost にアクセスして、次のような画面が表示されれば構築完了! phpinfo.png


その他

コンテナを終了する

docker compose down

再度この環境を構築するには、次のコマンドで構築できる。(docker-compose.ymlのファイルがあるディレクトリで実行する。)

docker compose up -d

これでPHPを使ってプログラミングができる。

次回は、今回構築した環境にmysql(データベース)を追加したものを投稿できればと思っています。