古いphpx.x-imagickをImageMagick7に対応させる【CompressX】

ここ数年はWrodpressで記事を書くことや最低限のアップデートはするにせよ、根元の環境的な部分はあまり触ってきませんでした。以前にCompressXについて紹介したのですが、しばらく使っているとアップデートが入り色々変わっていました。

久しぶりに管理画面にアクセスすると、AVIFファイルにチェックが入れていたのですが、そのチェックが外れていました。

以前の記事の画像では間違いなくチェックを入れていたはず…

何かアップデートのタイミングで外れてしまったのだろうと、AVIFにチェックを入れようとしたところ、ImageMagick6.x系には既知の不具合が存在するため、AVIFは有効にしないことをおすすめしますという表示が出ました。

ImageMagickとはなんぞやという方もいると思うのですが、ウェブアプリケーションで処理する際に使われる画像変換のソフトですね。php標準ではGDというものがありますが、これはAVIFに対応しておらず、AVIFに対応する場合はImageMagickを使用する必要があります。これのバージョンがどうも駄目のようです。

色々調べてみると、ImageMagick6.xが著しく古いバージョンかというとそうでもないようで、最新は7で自分の環境だとaptで降ってこないようでした。

というわけで、ImageMagick 7に移行してAVIFに対応させてみましょう。CSMはWordpress、今回はPHPは8.1の環境です。

目次

現在のバージョンを確認する

ひとまず現在のバージョンを確認してみましょう。Wordpressではサイトヘルスから確認することができます。

(画像)

CompressXに限ってはもしここのバージョンが適切なものでは無かったら警告してくれるようになっていますが、ひとまず現状のバージョンが何かぐらいは確認しておきましょう。何か躓いた際にはヒントになったりします。

画像は更新後のものになっていますが、自分の環境だと6.9.16で表示されていたので、確かに警告で会った通りバグがあるとされているバージョンのようです。

更新してしまった後ですが…

ImageMagickとphpx.x-imagickの関係

このあたりも最初は意味が分からないと思うので簡単に紹介します。この話の中ではImageMagickとImagickとphox.x-imagick(xにはバージョンが入ります。例. php8.3-imagick)という言葉が存在します。

ImageMagickはコンソールアプリケーションとしても使えるコマンドです。ImagickはImageMagickをたたくインターフェイスのことを指しており、phpx.x-imagickパッケージ名でありphpからimagickをたたくためのものです。

Imagickというのはphp内部で実行する、new Imagick()で生成されるオブジェクトからきている呼び方みたいなものです。なので記事などで紹介されるときは、Imagickと書いてあったり、ImageMagickと書いてあったり、はたまたパッケージ名でphpx.x-imagickと書いてありややこしいです。

今回はImageMagick 7にしようという話になっているので、php内部の処理についてはほぼ関係ないので、登場人物としてはImageMagickと対応するphpx.x-imagickの二つです。

phpx.x-imagickはImageMagickの関係は
(WordPressプラグインなどからの呼び出し)->phpx.x-imagick->ImageMagick
という感じで呼び出されている構図になっています。ImageMagickを呼び出すのがphpx.x-imagickの仕事です。

CompressXのメッセージを読むとphpx.x-imagickについて何か書かれているのではなく、ImageMagickのバージョンに対して書かれています。なのでImageMagickを置き換えるだけで動きそうな気がしてきますが、実際にはそこまで簡単な話ではありません。

結局phpx.x-imagickというパッケージがビルドされる際にImagickの呼び出し方を決めてしまっているので、使い方や場所、ファイル名などが古いImageMagickを参照するようにできています。

細かいことを書くと、shared object(.so)ファイルの呼び出し先が異なるようにできています。対応していないバージョンはlibMagickWand-6.soを参照するようになっているので、libMagickWand-7.soを用意、それをphpx.x-imagickが参照する必要が出ます。

なので、最終的にやる必要があるのは、ImageMagickの更新と、それに合ったphpx.x-imagickの作成ということになります。

ImageMagick関係のビルド

まず初めに依存関係にあるパッケージを消去することから始めます。往々にして、古いパッケージが悪さをするので、競合しないように最初から葬っておきます。

sudo apt remove --purge imagemagick imagemagick-6-common libmagickwand-6.q16-6 php8.1-imagick
sudo apt autoremove

次にビルドに必要なパッケージを入れます。

sudo apt update
sudo apt install -y build-essential libheif-dev libwebp-dev libjpeg-dev libpng-dev libfreetype6-dev libtool pkg-config

最新のソースを用意し、必要な機能だけを有効にしてビルドします。今回はGUI上で使わないのでそれ関係やX11あたりを無効にします。

mkdir && cd /tmp
wget https://www.imagemagick.org/download/ImageMagick.tar.gz
tar xzvf ImageMagick.tar.gz
cd ImageMagick-7.xx
//↑展開時のディレクトリに合わせてください

./configure --with-heic=yes --with-webp=yes --without-x --without-perl --with-modules
make -j$(nproc)
sudo make install

sudo ldconfig /usr/local/lib

make installのときにprefixが聞かれますが、通常はこれは何も入力せずEnterでOKです。何か設定しているひとだけ入力してください。

これでImageMagick 7自体はビルドできましたが、php側が対応できないので、phpx.x-imagickを対応させていきます。以下でphp関係で必要なパッケージを入れます。(例はphp8.1なのでこれですが、適宜バージョンは環境に合わせて読み替えてください)

sudo apt install -y php8.1-dev php-pear

以下のコマンドで、phpx.x-imagickをビルドできます。

sudo pecl uninstall imagick
sudo pecl install imagick
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx

peclだと自動で展開されるはずですが、念のため各サービスを再起動しておきます。

これでできたかのように思うのですが、一度Wordpressのサイトヘルスを見てください。ステータスタブのどこかに「オプションのモジュール imagick がインストールされていないか、無効化されています。」と出ていると、他にも設定する必要があります。以下の操作をします。

sudo nano /etc/php/8.1/fpm/conf.d/20-imagick.ini

このファイルを新規作成か内容を追加します。このファイルには以下のような文言をいれます。

extension=imagick.so

保存したらfpmを再起動します。例ではphp8.1-fpmにしてます。

sudo systemctl restart php8.1-fpm

これでサイトヘルスからバージョンが参照でき、現段階だとVer7.xが表示されていれば問題ありません。

ちなみに、この操作をする意味ですが、通常のphpx.x-imagickを入れると勝手に設定がされるのですが、今回はセルフビルドのため自分で設定しないと、imafgickを正しく参照できないためです。

最後は不要なパッケージなどは消しておきましょう。自分の環境だとストレージもさして余裕がないので。少しでも不要なファイルは消します。

sudo apt remove -y build-essential php8.1-dev php-pear
sudo apt autoremove -y
//ImageMagickのソースコードやそれを展開したフォルダも全て削除してOK

ここまでくればCompressXの方も確認すると、推奨しないというエラーも出なくなっているためAVIFにもチェックが入れられるようになっていると思います。あとは実際に変更してみてOOMなどが起きなければ大丈夫です。

AVIFも安心して有効化できる

ImageMagickの設定を変更する

このあたりは以前の環境などによるのですが、ImageMagickの設定を変更した方が良い場合があります。特にマシンスペックが低い場合です。まずは最初の方に出した以下の画像のImagickソースリミットを見てください。

Imagickソースリミット…

ここのソースリミットを見るとおそらくデフォルト値で物理スペックの限界まで使おうとしていますね。これだと設定によってはOut of Memory (OOM)でサーバがフリーズしてしまいます。そもそもここらへんの設定が甘かったせいでCompressXを使うとOOMでサーバがとまっていたのでここら辺はきっちり設定した方がいいでしょう。というかなぜデフォルトはメモリ食い設定なのでしょう…

今回のように手動で設定した場合は、通常以下の部分に設定ファイルがあります。

/usr/local/etc/ImageMagick-7/policy.xml

マシンスペックによりますが、ここを適切な値に調整しましょう。メモリ1GBのマシンなら、こんなもんかなという値を入れてみました。

<policymap>
  <policy domain="resource" name="memory" value="256MiB"/>
  
  <policy domain="resource" name="map" value="512MiB"/>
  
  <policy domain="resource" name="area" value="128MB"/>
  
  <policy domain="resource" name="disk" value="1GiB"/>
 
  <policy domain="resource" name="thread" value="1"/>
</policymap>

保存したらphp-fpmを再起動すると設定が反映されます。

sudo systemctl restart php8.1-fpm

これでImageMagick本体の設定も終わりです。

まとめ

ImageMagickとphpx.x-imagickの更新をしてみました。個人的にモジュール単位での更新をしたことがなかったので、良い経験になりました。これでCompressXもフルスペックで使えるようになったので、さらにサイトスコア(もはや気にしていない)が良くなること間違いなしです。

以上です。お読みいただきありがとうございました。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です