こんにちは。よっしーです(^^)
今日は、dockerで構築した開発環境において、php-fomを導入した手順をご紹介します。
実行環境
この記事は、特定の開発環境を前提として書かれています。もし興味がある場合は、その開発環境を構築するための説明が書かれている記事を参考にしてください。該当記事は下記になります。
ただ、この記事で紹介している修正内容がたくさんあるので、その修正を反映した最新版のプログラムをダウンロードして、参照することをおすすめします。該当のプログラムの詳細については、下記のページで確認できます。
背景
Dockerを使って環境構築をする場合、複数のコンテナを使用することで、アプリケーションやサービスごとに独立した環境を作ることができます。その中で、PHPアプリケーションを実行する場合、Apache HTTP Serverを使用する方法と、PHP-FPM(FastCGI Process Manager)を使用する方法があります。
Apache HTTP Serverを使用する場合、PHPをモジュールとして組み込んで使用することが一般的です。一方、PHP-FPMを使用する場合、ApacheとPHPを別々に実行し、FastCGIプロトコルを介して通信することができます。今回は、この方法を採用する理由はいくつかあります。
まず、ApacheとPHPを分離することで、より柔軟性の高い設定が可能になります。たとえば、ApacheとPHPを別々にスケールさせることができます。また、異なるバージョンのApacheとPHPを使用する場合でも、問題なく動作させることができます。
さらに、PHP-FPMはApacheと比較して、より高速な処理が可能です。これは、ApacheがPHPをモジュールとして組み込んでいる場合に比べ、PHP-FPMがより軽量であるためです。また、PHP-FPMはプロセスの管理を行うことができるため、負荷が増加した場合にもより柔軟な対応が可能です。
以上のような理由から、PHP-FPMを使用して、ApacheとPHPを分離することが推奨されています。ただし、環境によってはApacheとPHPを一緒に使用することが適切な場合もありますので、その場合は適切な設定を行うことが重要です。
ディレクトリ構造
ディレクトリ構造は下記のようになっています。赤字の箇所が新規&更新、削除になります。
.
├── LICENSE
├── Makefile
├── README.md
└── app
├── apache-exporter
├── compose.yml
├── flyway
├── grafana
├── influxdb
├── k6
├── memcached
├── memcached-exporter
├── php-fpm
│ ├── CodeIgniter-3.1.13
│ ├── Dockerfile
│ ├── index.php
│ ├── info.php
│ └── xdebug.ini
├── mongo
├── mysql
├── mysqld-exporter
├── prometheus
├── schemaspy
├── web
│ ├── .htaccess
│ ├── Dockerfile
│ └── php-fpm.conf
└── xhgui
compose.yml
下記の赤字内容でファイル(compose.yml) 42 – 78 行目を更新します。
web:
build: ./web
container_name: web
platform: linux/x86_64
privileged: true
volumes:
- ./web/healthcheck.txt:/var/www/html/healthcheck.txt
- ./web/.htaccess:/var/www/html/.htaccess
- ./web/httpd.conf:/etc/httpd/conf/httpd.conf
- ./web/server-status.conf:/etc/httpd/conf.d/server-status.conf
- ./web/xhprof-html.conf:/etc/httpd/conf.modules.d/xhprof-html.conf
- ./web/php-fpm.conf:/etc/httpd/conf.modules.d/php-fpm.conf
ports:
- 8080:80
depends_on:
- php-fpm
networks:
- net
healthcheck:
test: "curl -f http://localhost/healthcheck.txt || exit 1"
start_period: 30s
retries: 3
timeout: 10s
interval: 10s
php-fpm:
build: ./php-fpm
container_name: php-fpm
volumes:
- ./php-fpm/CodeIgniter-3.1.13/application:/var/www/application
- ./php-fpm/CodeIgniter-3.1.13/system:/var/www/system
- ./php-fpm/index.php:/var/www/html/index.php
- ./php-fpm/info.php:/var/www/html/info.php
- ./php-fpm/xdebug.ini:/etc/opt/remi/php74/php.d/xdebug.ini
networks:
- net
php-fpm/Dockerfile
下記の内容で新規ファイル(php-fpm/Dockerfile) を作成します。
FROM php:7.4-fpm
# apt-get update & install
RUN apt-get update \
&& apt-get install -y \
git \
zip \
zlib1g-dev \
libmemcached-dev
# PHP
RUN docker-php-ext-install -j$(nproc) mysqli
# composer
COPY --from=composer /usr/bin/composer /usr/bin/composer
COPY ./CodeIgniter-3.1.13/composer.json /var/www/composer.json
RUN cd /var/www \
&& composer install
# xhprof
RUN cd /tmp \
&& git clone https://github.com/tideways/php-xhprof-extension \
&& cd /tmp/php-xhprof-extension \
&& phpize \
&& ./configure \
&& make \
&& make test \
&& make install
RUN mkdir -vp /var/log/xhprof \
&& chmod 777 /var/log/xhprof
RUN echo 'extension=tideways_xhprof.so' >> /usr/local/etc/php/conf.d/tideways.ini \
&& echo 'tideways.auto_prepend_library=0' >> /usr/local/etc/php/conf.d/tideways.ini
RUN cd /var/www/ \
&& git clone https://github.com/sters/xhprof-html.git ./xhprof-html \
&& cd ./xhprof-html \
&& sed -i "81c\$xhprof_runs_impl = new XHProfRuns_Default('\/var\/log\/xhprof');" callgraph.php
RUN pecl install memcached \
&& docker-php-ext-enable memcached
RUN pecl install xdebug-3.1.6
WORKDIR /var/www
CMD php-fpm
RUN chown www-data:www-data /var/www/
php-fpm/Dockerfile 以外
下記のファイルをwebから移動させる。
web/CodeIgniter-3.1.13 -> php-fpm/CodeIgniter-3.1.13
web/index.php -> php-fpm/index.php
web/info.php -> php-fpm/info.php
web/xdebug.ini -> php-fpm/xdebug.ini
web/Dockerfile
下記の内容でファイル(web/Dockerfile) を更新します。
FROM amazonlinux:2
# amazon-linux-extras install
RUN amazon-linux-extras install -y epel
# yum update & install
RUN yum update -y \
&& yum install -y \
systemd \
httpd
# httpd
RUN systemctl enable httpd
# init
CMD ["/sbin/init"]
web/.htaccess
下記の赤字内容でファイル(web/.htaccess) を更新します。
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/server-status
RewriteCond %{REQUEST_URI} !=/info.php
RewriteCond %{REQUEST_URI} !/index\.php
RewriteRule ^(.*)$ index.php/$1 [L]
web/php-fpm.conf
下記の内容で新規ファイル(web/php-fpm.conf) を作成します。
AddType text/html .php
DirectoryIndex index.php
<FilesMatch \.php(/.*)?$>
SetHandler "proxy:fcgi://php-fpm:9000"
</FilesMatch>
動作確認
下記のコマンドを実行して、サービスを起動します。
make setup
ブラウザで「hhttp://localhost:8080/Sample/indexWithCache」にアクセスして、下記のように表示されていれば成功です。
test
テスト2
てすと3
Total Results: 3
解説
php-fpmについて
PHP-FPM(FastCGI Process Manager)は、PHPをFastCGIプロトコルで実行するためのプロセス管理ツールです。PHP-FPMは、Apache HTTP ServerやNginxといったWebサーバーと組み合わせて使用することが一般的です。Webサーバーからのリクエストを受け取ったPHP-FPMは、FastCGIプロトコルを介してPHPプロセスにリクエストを転送し、PHPプロセスが処理した結果をWebサーバーに返します。
PHP-FPMは、以下のような特徴を持っています。
- プロセス管理機能:PHP-FPMは、プロセスのプールを管理することができます。プール内のプロセス数や、各プロセスのメモリ使用量、CPU使用量などを設定でき、負荷に応じて自動的にプロセスを追加・削除することができます。
- チューニング機能:PHP-FPMは、異なる種類のリクエストに対して、異なるプールを使用することができます。たとえば、CPU負荷の高いアプリケーションと、メモリ負荷の高いアプリケーションを分けることができます。
- ログ出力機能:PHP-FPMは、プロセスの起動・停止や、エラー・警告などのログを出力することができます。これにより、問題が発生した際に原因を特定することができます。
- セキュリティ機能:PHP-FPMは、UnixドメインソケットやTCPソケットを使用して、Webサーバーと通信することができます。これにより、WebサーバーとPHP-FPMの間に、ファイアウォールやリバースプロキシを配置することができ、セキュリティを強化することができます。
PHP-FPMは、高負荷なWebアプリケーションや、複数のWebサーバーを使用する場合に特に効果的です。ただし、PHP-FPMを使用する場合には、適切な設定が必要であり、設定を誤るとパフォーマンスが低下したり、セキュリティ上の問題が発生したりすることがあるため、注意が必要です。
おわりに
今日は、dockerで構築した開発環境にphp-fpmを導入し、apacheとphpサービスを分けました。これで、apacheのバージョンアップをしたり、nginxに変えたり、phpのバージョンアップだけしたりと、管理しやすくなったのかなと思います。あとは、移行時に問題ないかのテストケースを書いておくといいと思いましたので、いつか書いておきたいと想います。
今回使用したファイルは下記のGitHubにタグ付けしています。
もし、質問等あればコメントください。確認後、ご連絡いたします。随時、エンジニア案件も相談可能ですので、よろしくお願いいたします。
また明日お会いしましょう!
コメント