Debian11でPHP8をビルド、Apacheも
筆者は普段Debianを利用しているのですが、執筆時点では、通常のAPTのリポジトリでインストールできるバージョンは 7.4 です。
近年はPHPの8以上を要件とするライブラリも増えてきましたので、Debian11でPHP8をビルドしてみたいと思います。合わせてApacheサーバのビルドも必要になります。
Apacheのビルド
APTで build-essential インストールを終えているものとし、Apacheをビルドします。
Apacheから、httpd-2.4.54.tar.gz をダウンロードして展開します。
# cd /usr/local/src # wget https://dlcdn.apache.org/httpd/httpd-2.4.54.tar.gz # tar vzxf httpd-2.4.54.tar.gz # cd httpd-2.4.54 # ./configure --enable-so ... checking for APR... no
configureを実行すると、APRがないということです。INSTALLファイルを読むと、apr.apache.orgからダウンロードするようにとの事でした。
APRはプラットフォーム間の挙動差異を吸収してくれるツールのようです。configure -hで見てみても、これがない状態でビルドする方法はなさそうでした。
ダウンロードしたのち展開し、httpd-2.4.54ディレクトリにあるsrclibディレクトリの中に、バージョンを除去した形で移動させます。その後、--with-inculded-aprオプションをつけてconfigureを実行します。
# wget https://dlcdn.apache.org//apr/apr-1.7.0.tar.gz # wget https://dlcdn.apache.org//apr/apr-util-1.6.1.tar.gz # tar vzxf apr-1.7.0.tar.gz # tar vzxf apr-util-1.6.1.tar.gz # mv apr-1.7.0 httpd-2.4.54/srclib/apr # mv apr-util-1.6.1 httpd-2.4.54/srclib/apr-util # ./configure --enable-so --with-inculded-apr
PCREもが存在しないというエラーも出ました。PCREはPerl 5と同じ構文で正規表現を行うためのライブラリです。aptで「libpcre2-dev」をインストールしたところconfigureは通りましたが、ビルドでエラーになりました。PCRE2Project/pcre2から最新版をダウンロードしてビルドするのがいいと思いまいます。
make時に「 expat.h: そのようなファイルやディレクトリはありません 」というメッセージでエラーとなりました。こちらは「libexpat1-dev」をaptでインストールしたところ解消しました。。
デフォルトだとApacheバイナリ群は「/usr/local/apache2/」にインストールされます。設定ファイルはその中のconf/httpd.confとなっており、設定はすべてその中に記述します。APTからインストールした際のようなDebianのApache2の設定ディレクトリ群では設定をしないため、a2enmod等のコマンドは利用できません。
サーバーはbinディレクトリのapachectlから「 start 」や「 stop 」といった引数を渡してコントロールします。apachectlの他のコマンドについては公式ページに掲載されています。
公開するファイルの保存先であるhtdocsディレクトリも同じ場所に存在します。
コマンドを利用すれば起動はできますが、おそらくサービス(Systemd)として動かしたいと思います。これはAPT経由でインストールしたapacheサーバーのファイルを参考に次のようにしました。
apache2.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=https://httpd.apache.org/docs/2.4/
[Service]
Type=forking
Environment=APACHE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/local/apache2/bin/apachectl start
ExecStop=/usr/local/apache2/bin/apachectl stop
ExecReload=/usr/local/apach2/apachectl graceful
PrivateTmp=true
Restart=on-abort
[Install]
WantedBy=multi-user.target
このファイルを/etc/systemd/system/ディレクトリに配置します。その後「systemctl enable apache2」を実行して自動化させます。
デフォルト以外の場所にインストールした場合は、Execのパスに注意してください。
またAPTでインストールした際は、apacheはwww-dataというユーザー権限で動くのでその設定もします。
ユーザーを作成します。
次に、httpd.confのUserとGroupにwww-dataを設定します。
httpd.conf
# User daemon # Group daemon User www-data Group www-data
サービスを再起動させて状態を確認します。httpのプロセスのユーザーが設定したwww-dataになっているものがあれば正常です。一部のプロセスはrootになっています。
# ps aux | grep www-data root ... /usr/local/apache2/bin/httpd -k start www-data ... /usr/local/apache2/bin/httpd -k start ...
PHPのビルド
PHPをビルドします。まず公式のインストールガイドにあるように--with-apxs2=/usr/local/apache2/bin/apxs指定します。apacheをビルドしたのはこのためです。
ここでは、LaravelのPHP要件を想定して、Laravelに必要で、デフォルトで有効にならない次の拡張ライブラリを設定します。
- BCMath
--enable-bcmath
- cURL
--with-curl
- Mbstring
--enable-mbstring
- OpenSSL
--with-openssl
- PCRE
公式のWebのドキュメントにはデフォルトでソースにバンドルされているPCREが利用されるとの記述があったので、なにも指定しなかったところ「 Unable to start pcre module in Unknown on line 0 」というエラーに遭遇しました。そこでapacheインストール時にビルドしたPCREを利用するように「--with-external-pcre=[ライブラリのディレクトリ」と指定しています。
- PDO
PDO自体は有効になっていますが、MySQL(MariaDB)をPDOで使うなら、--with-pdo-mysql を指定する必要があります。Postgreの場合は--with-pdo-pgsqlを指定します。また PDO ではなく mysqli を利用するには --with-mysqli を指定します。利用する可能性があるならすべて設定することも可能です。
ここでは設定しませんが、他に必要になりそうなものは、gd(画像処理)などがあると思います。これらのオプションの詳細は「 configure -h 」から確認可能です。
MariadbやopenSSLの他必要なアプリをインストールしておきます。筆者の環境では他にpkg-configやlibxml2-dev、libssl-dev(openssl)、libsqlite3-dev、libcurl4-openssl-dev(curl)、libonig-dev(Oniguruma正規表現ライブラリ)、zlib1g-dev(圧縮ライブラリ)が必要になりました。
あと、デフォルトだとphp.iniを置く場所が/etcディレクトリではないようなので、これが気になるようなら、--with-config-file-path=/etc/ で保存先のディレクトリを指定しましょう。
# apt install mariadb-server openssl pkg-config ... # wget https://www.php.net/distributions/php-8.1.9.tar.gz # tar vzxf php-8.1.9.tar.gz # cd php-8.1.9.tar.gz # ./configure --with-apxs2=/usr/local/apache2/bin/apxs --enable-bcmath --with-curl --enable-mbstring --with-openssl --with-pdo-mysql --with-zlib --with-external-pcre=/usr/local/lib # make # make test # make install
make testを事項するように促されますので、実行します。おそらくいくつかは失敗するのではないかと思います。
これらの対処方法は@IT:「PHPテスト失敗の原因を追究する」が参考になります。
例えば次のようなエラーが出たとします。
この時ソースディレクトリにある「ext/opcache/tests/bug78014.phpt」に定義されているテストが実行されます。その内容から状況を判断します。
今回は、opcache関連のエラーがいくつか出ました。make testを管理者権限で実行したためだと判断しました。opcacheのコードの事前ロードではroot権限での実行が禁止されています。ユーザー権限でテストをすると該当のエラーは出ませんでした(代わりroot権限でテストした際には出ないエラーが出ましたが)。
PHPの設定
httpd.confにおけるPHPのLoadModuleのエントリーは--with-apxs2オプションをを付けてビルド・インストールした流れの中で自動的に加わっていると思います。それが出力されているのが確認できたら、.phpの拡張子をもつファイルをPHPとしてパースする設定の記述をします。
httpd.conf はデフォルトでは /usr/local/apache2/conf ディレクトリに存在します。
httpd.conf
...
# 既に存在していると思います
LoadModule php_module modules/libphp.so
...
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
...
PHPの設定ファイルはソースディレクトリからphp.ini-developmentまたはphp.ini-production、ファイルをコピー・リネームして配置します。デフォルトだと/usr/local/lib/php.iniに配置する決まりになっています。
別環境
環境を、apr-1.7.3、apr-util-1.6.3、httpd-2.4.56にしたところ、libexpat1-devをAPTでインストールした場合、ビルド中に「 undefined reference to `XML_SetElementHandler' 」が発生しました。
なので、libexpatもgitからダウンロードしてビルドします。
追加で git と autoconf 、libtool が必要になります。
# apt install git autoconf ... # git cline https://github.com/libexpat/libexpat.git ... # cd libexpat/expat ... # ./buildconf.sh ... # ./configure ... # make ... # make install ...
一度libexpat-devをインストールしてしまったら、アンインストールし、make install で新しいライブラリを作成した後、ldconfig を実行して再度./configureを実行する必要があると思います。
また、php.ini の配置場所がわかりづらいと思いますが、 php --ini とコマンドを入力することで表示されます。元のソースディレクトリに、php.ini-development(開発用) と php.ini-production(本番用)がありますので、コピーリネームしてベースとします。
インストール後、「 warning: remember to run 'libtool --finish /usr/local/src/php-8.2.4/libs' 」とメッセージが出ると思いますので、指示通り実行しようとすると「 コマンドが見つかりません 」と言われてしまうかもしれません。実行スクリプトの本体が、ビルドを実行したルートに(/usr/local/src) にありますので ./libtool としないといけません。
# ./libtool --finish /usr/local/src/php-8.2.4/libs
PHP8.2
PHP8.2から libmysqlclient での mysqli ビルドが利用できなくなりました。
従来 mysqli ライブラリがベースにするクライアントライブラリには libmysqlclient と mysqlnd の2種類がありました。バージョン5.4からmysqlnd がデフォルトとなっていますが、ビルド時のコンパイルオプションに「 --with-mysqli=/path/to/mysql_config 」とオプションに引数を渡すと libmysqlclient を利用する設定になっています。mysqlnd を使う場合は単に「 --with-mysqli 」としなければなりません。
そのためPHP8.2以降をビルドする際、古い設定「 --with-mysqli=/path/to/mysql_config 」を指定しようとするとエラーになります。
ちなみに、libmysqlclient と mysqlnd の違いですが、libmysqlclient は C言語を念頭に開発されたクライアントライブラリで mysqlnd(NDはNative Driverの略)はPHPを念頭に置いたライブラリです。
PDO や PDO-MySQL,mysqli,mysqlnd,libmysqlclient などのあたり混乱しがちなので整理すると次のようになります。
PHPでMySQLを利用したい場合の拡張ライブラリの選択肢は次の2つです。
- PDO MySQL
PDO(抽象化レイヤー)→PDO MySQL→mysqlnd(低レベルライブラリ)
- MySQLi
mysqli→mysqlnd(低レベルライブラリ)
バージョン8.2以前だと、mysqlnd 以外の低レベルライブラリの選択肢として libmysqlclient が存在します。
詳しくはPHP:「mysqliの概要」を参照してください。
No such file or directory
PHPからMySQLに接続しようとした際に、connectメソッドのあたりで「 No such file or directory 」がでるようなら、php.iniの次の点を確認すると解決するかもしれません。
- extension_dir の設定
Debianだったら、extension_dir="./" 部分がコメントアウトになっていないか確認します。(MySQLi使用時)
- extension の設定
extension = mysqli のコメントアウトが解除されているかを確認します。(MySQLi使用時)
- ソケットの場所の指定
mysqli.default_socket や pdo_mysql.default_socket が MySQL/MariaDB で設定しているソケットの出力場所か確認します。
参考にさせていただきましたサイトの皆様、ありがとうございました。