Dockerを使用してPHPのOPcacheを有効化する方法

JavaScriptを有効にしてください

前書き

PHPのパフォーマンスを向上させるための重要なツールの一つにOPcacheがあります。
OPcacheは、コンパイル済みのPHPスクリプトのバイトコードをメモリにキャッシュすることで、スクリプトの再実行時にコンパイルを省略し、実行速度を向上させます。
この記事では、Dockerを使用してPHPのOPcacheを有効化する方法を紹介します。

「そもそもOPCacheって何なの?」という方はこちらの記事 をご一読ください。

ステップ 1: Dockerfileの作成

Dockerfileを作成してPHP-FPMとOPcacheをセットアップします。
また、カスタムのphp.ini設定を適用するためのファイルも準備します。

php-fpm.Dockerfile
1
2
3
4
FROM php:8.3-fpm

# OPcacheを有効にする
RUN docker-php-ext-enable opcache

ステップ 2: OPcacheの設定ファイルを作成

custom-php.iniには、OPcacheの設定を含めます。例えば下記のように設定します。

custom-php.ini
1
2
3
4
5
6
7
8
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1

OPcacheの設定オプションの解説

custom-php.iniで設定した各項目の詳細について解説します。

基本設定

  • opcache.enable

    • 1に設定するとOPcacheが有効になります。
    • 0に設定すると無効になります。
  • opcache.memory_consumption

    • OPcacheが使用するメモリの最大量をメガバイト単位で指定します。
  • opcache.interned_strings_buffer

    • PHPが内部的に使用する文字列のためのメモリ領域のサイズをメガバイト単位で指定します。

パフォーマンス設定

  • opcache.max_accelerated_files

    • キャッシュできるPHPファイルの最大数を指定します。
  • opcache.validate_timestamps

    • 1に設定すると、PHPファイルが変更されたかどうかをチェックします。(開発環境では基本的にこちらを使用します)
    • 0に設定すると、変更チェックを行わず、パフォーマンスが向上します。(本番環境では基本的にこちらを使用します)
  • opcache.revalidate_freq

    • opcache.validate_timestamps=1の場合、PHPファイルの変更をチェックする頻度を秒単位で指定します。
    • opcache.revalidate_freq=60の場合、60秒ごとに更新することになります。

高度な設定

  • opcache.fast_shutdown
    • 1に設定すると、スクリプトの実行終了時のメモリ解放処理を最適化します。

これらの設定を適切に調整することで、アプリケーションのパフォーマンスを最適化し、エンドユーザーにより良い体験を提供することが可能になります。

ステップ 3: Nginxの設定

Nginxの設定ファイルdefault.confを作成し、PHPのリクエストをPHP-FPMに転送するように設定します。

default.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

ステップ 4: Docker Composeの設定

docker-compose.ymlファイルを作成して、NginxとPHP-FPMのコンテナを連携させます。

docker-compose.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: '3'

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8080:80"
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - ./html:/var/www/html
    depends_on:
      - php-fpm
    networks:
      - app-network

  php-fpm:
    build:
      context: .
      dockerfile: php-fpm.Dockerfile
    container_name: php-fpm
    volumes:
      - ./html:/var/www/html
      - ./custom-php.ini:/usr/local/etc/php/conf.d/custom-php.ini
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

この設定では、htmlディレクトリ内のファイルがNginxとPHP-FPMの両方で共有されます。

ステップ 5: デモ用PHPスクリプトの準備

このスクリプトは、opcache_get_status()関数を使用してOPcacheの現在の設定と状態を取得し、それを整形して表示します。
OPcacheが有効であれば、キャッシュされているスクリプトの情報やキャッシュのヒット率など、詳細な情報を確認することができます。

check.phpスクリプトはhtmlディレクトリに配置します。

check.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
// OPcacheが有効かどうかを確認
if (function_exists('opcache_get_status')) {
    $opcacheStatus = opcache_get_status(false);

    if ($opcacheStatus) {
        echo "<h1>OPcacheの状態</h1>";
        echo "<p>OPcacheが有効になっています。</p>";
        echo "<pre>";
        print_r($opcacheStatus);
        echo "</pre>";
    } else {
        echo "<p>OPcacheの状態を取得できません。OPcacheが有効になっていることを確認してください。</p>";
    }
} else {
    echo "<p>現在のPHPインストールではOPcacheが有効になっていません。</p>";
}

ステップ 6: 環境のビルドと起動

ここまでのステップでファイル構成は下記のようになっています。

bash
1
2
3
4
5
6
7
8
$ tree
.
├── custom-php.ini
├── default.conf
├── docker-compose.yml
├── html
│   └── check.php
└── php-fpm.Dockerfile

以下のコマンドを実行して、環境をビルドし、起動します。

bash
1
docker-compose up -d

ステップ 7: テストの実行

ブラウザからhttp://localhost:8080/check.php にアクセスします。
ブラウザに下記内容が表示されれば問題なく動作しています。

ブラウザの出力結果
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
OPcacheの状態
OPcacheが有効になっています。

Array
(
    [opcache_enabled] => 1
    [cache_full] => 
    [restart_pending] => 
    [restart_in_progress] => 
    [memory_usage] => Array
        (
            [used_memory] => 9169096
            [free_memory] => 125048632
            [wasted_memory] => 0
            [current_wasted_percentage] => 0
        )

    [interned_strings_usage] => Array
        (
            [buffer_size] => 8388608
            [used_memory] => 2363368
            [free_memory] => 6025240
            [number_of_strings] => 5629
        )

    [opcache_statistics] => Array
        (
            [num_cached_scripts] => 1
            [num_cached_keys] => 1
            [max_cached_keys] => 16229
            [hits] => 1
            [start_time] => 1737270194
            [last_restart_time] => 0
            [oom_restarts] => 0
            [hash_restarts] => 0
            [manual_restarts] => 0
            [misses] => 1
            [blacklist_misses] => 0
            [blacklist_miss_ratio] => 0
            [opcache_hit_rate] => 50
        )

    [jit] => Array
        (
            [enabled] => 
            [on] => 
            [kind] => 5
            [opt_level] => 4
            [opt_flags] => 6
            [buffer_size] => 0
            [buffer_free] => 0
        )

)

ステップ 8: custom-php.iniを変更してみよう

opcacheが有効になっていることが確認できたので、今度はcustom-php.iniを変更してopcacheを無効にしてみましょう。
下記のようにopcache.enableを0に設定するだけです。

custom-php.ini
1
2
3
4
5
6
7
8
[opcache]
opcache.enable=0
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1

custom-php.iniを変更したら下記コマンドで再実行して変更を反映させます。

bash
1
$ docker-compose restart php-fpm

下記だとダウンタイムなしで、設定ファイルを読み込むことができます。

bash
1
$ docker kill --signal=USR2 php-fpm

上記コマンドについて簡単に解説すると、killコマンドはプロセスを終了させるだけでなく、シグナルを送ることによって様々な動作を実行させることができます。
USR2はユーザー定義シグナルと呼ばれるもので、アプリケーションによって動作が異なります。
php-fpmではgraceful reload of all workers + reload of fpm conf/binaryという動作になり、
日本語訳では「全てのワーカープロセスを優雅に再起動(現在のリクエストが完了するまで待つ)し、FPM設定ファイルやバイナリを再読み込みする。」となります。

本番環境で動作している際に上記シグナルを送ることによってダウンタイム無しで設定ファイルの再読み込みができます。

ちなみにdocker killはコンテナに対してkillコマンドを実行しており、実際にコンテナに入って実行する際は下記のコマンドになります。

bash
1
2
$ docker exec -it php-fpm bash
$ kill -USR2 1

こちらでも同様に設定ファイルの再読み込みが可能です。

反映完了後、ブラウザでhttp://localhost:8080/check.php に再度アクセスすると下記の出力になります。

ブラウザの出力結果
1
OPcacheの状態を取得できません。OPcacheが有効になっていることを確認してください。

ちゃんと設定が反映されていますね。

これで設定ファイルを変更し、すぐに動作を確認できる状態になりました。ぜひ、さまざまな変更を試して動作を確認してみてください。

opcache-guiをインストールする

ここまででopcacheの有効化に関して解説は終わりですが、opcacheを使っていると、今どのくらいのメモリを使用しているのか確認したい時があります。
そういった場合にopcache-guiをインストールしておくととても便利です。

opcache-guiは、PHPのOPcacheの状態を視覚的に確認できるウェブインターフェースです。
opcache-guiを使用すると、キャッシュの状態やパフォーマンス、設定などを簡単に確認できます。

opcache-guiの主な機能

キャッシュされたスクリプトの一覧表示

どのPHPファイルがOPcacheによってキャッシュされているかを確認できます。

キャッシュの使用状況

使用中のメモリ量、キャッシュされたスクリプトの数、キャッシュヒット率(キャッシュが効いている度合い)など、キャッシュの効率を示す指標を確認できます。

キャッシュの設定値

OPcacheの設定値を確認できます。
これには、メモリ消費量の上限やキャッシュするスクリプトの最大数などが含まれます。

キャッシュのクリア

ウェブインターフェースから直接、キャッシュをクリアすることができます。
これは、キャッシュされたデータをリセットしたい場合に便利です。

opcache-guiの利用方法

GitHub からindex.phpファイルをダウンロードし、ウェブサーバーにアップロードします。その後、ブラウザからそのファイルにアクセスすることで、opcache-guiを使用できます。

具体的には先ほど作成したhtmlフォルダにダウンロードしたindex.phpを配置するだけで完了です。

bash
1
2
3
4
5
6
7
8
9
$ tree
.
├── custom-php.ini
├── default.conf
├── docker-compose.yml
├── html
│   ├── check.php
│   └── index.php
└── php-fpm.Dockerfile

ブラウザからhttp://localhost:8080/index.php にアクセスすると下記画面が表示されます。
opcache-gui

もしThe Zend OPcache extension is installed but not activeと表示されたらopcache.enable=0となっているはずなのでopcache.enable=1に設定後、設定ファイルを再読み込みしてからもう一度試してください。

まとめ

この記事では、Dockerを活用してPHPのOPcacheを設定し、その効果を検証する方法をステップバイステップで解説しました。
OPcacheはPHPスクリプトの実行速度を大幅に向上させることができる強力なツールであり、コンパイル済みのバイトコードをメモリにキャッシュすることで、スクリプトの再実行時のコンパイル時間を削減します。
このプロセスを通じて、アプリケーションのパフォーマンスを最適化し、エンドユーザーによりスムーズな体験を提供することが可能になります。


スポンサーリンク

共有

もふもふ
著者
もふもふ
プログラマ。汎用系→ゲームエンジニア→Webエンジニア→QAエンジニア