今日は、トイレの他にもう一つうまく行った。先日、思わぬ問題が見付かって仕切り直しにした、PHPのバージョンアップである。問題は、最新版PHPをインストールするためのPPA(公式パッケージ以外のソフトを手軽にインストールできる非公式パッケージ)に、PHP以外の余計なパッケージ(→ PPAのページ下部の一覧を参照)が沢山入っていたことだった※。そのPPA(以下、ondrejのPPA)を使うのは一般的なようだが、セキュリティ上のリスクが高いように思えるので避けたかった。

※今考えると、余計に思えたものはいずれかのPHPのモジュールが依存するものなのかも知れない(だから、全部のPHPモジュールをインストールした時には余計なものがなくなるのではないか)。そうならなおさら、自分が使うモジュールに必要なものだけをインストール・更新対象にしたい。

それで、今日までは、OS(Linux Mint)を更新してそれ(公式パッケージ)に含まれるPHPに更新することを考えていたのだが、良く考えたら、最新のOSに含まれるPHPは最新ではないため、すぐにサポート期間が切れてしまうことに気付いた。以下にその関係を示す。

Linux MintとPHPのサポート期間の関係

  • Linux Mint (→ 参照)
    • 18.3(現在使っている版): 2021/4まで
    • 19.1(最新版): 2023/4まで
  • PHP (→ 参照)
    • 7.2(Linux Mint 19.1(Ubuntu 16 LTS)のパッケージで入るもの): 2020/11末まで
    • 7.3(最新版): 2021/12頭まで

OSをLinux Mint 19.1に更新するとPHPは(最新の1つ前の)7.2にできるが、それは来年終わり頃にサポート期間切れになってしまうので、また今回のような状況になる。しかも、それがOSの期限切れまでに何度も起こるので、そのたびに必要もないのにOSを更新することになって無駄だ。それで、代わりの案を考えたら、以下の2とおりになった。

  1. ondrejのPPAの中のPHPだけを抜き出して使う。
  2. 自分でPHPをビルドしてインストールする。

2の自分でビルドするのはさまざまな問題や手間がありそうなので、却下した。1の、PPAからPHPだけを抜き出して使う方法を考えたところ、以下のいくつかの方法が浮かんだ。

  1. OSの設定を調整して、ondrejのPPA中のPHP以外のものを無効にして、PHPだけがインストールできるようにする。 (→ 参考1, 参考2)
  2. ondrejのPPAからPHPだけを抜き出した、「自分のPPA」を作る。 (→ 参考1, 参考2)
  3. ondrejのPPAのサイトからPHPのパッケージファイル(deb)だけをダウンロードして、インストールする。その処理を自動化する。

1番目はPinning(aptの設定ファイル中にPinという設定を記述する)でできそうだが、間違えると、前回のように厄介なことになりそうだ。2番目は、抜き出すだけでなく、抜き出したものをパッケージにするための情報を再度作成する必要があって面倒そうだ。3番目は一見簡単で、やればできるのだが、自動処理するにはOSのパッケージのインストールの仕組みを自分で作るようなものなので、間違いやトラブルのリスクが増えそうだ。

結局、1番目(Pinning)を採用することにした。試行錯誤でシステムを壊さないように、仮想環境で試した。すると、意外にうまく行った。以下のような手順で設定すれば良い。

  1. ondrejのPPAをOSに追加する。
  2. aptの設定ファイルを修正する。(→ /etc/apt/preferences.d/ondrej-php.pref)
  3. PHP 7.3のインストールに必要な依存モジュールを調べて、上記設定ファイルに追加する。
  4. 余計なパッケージがインストール対象になっていないか確認する。

1は、検索するとすぐに出て来る方法で、例えば以下である。

sudo sh -c "export LC_ALL=C.UTF-8; \
add-apt-repository ppa:ondrej/php"

2は、参考ページを参考にして、以下のようにした。

/etc/apt/preferences.d/ondrej-php.pref:

# ondrejのPPA中の全パッケージを無効にする。
Package: *
Pin: release o=LP-PPA-ondrej-php
Pin-Priority: -1

# ondrejのPPAのPHP7.3のパッケージを有効にする。
Package: php7.3*
Pin: release o=LP-PPA-ondrej-php
# 公式パッケージがない時だけ、ondrejのPPAのパッケージを使う。

Pin-Priority: 400

# ondrejのPPAのPHP7.3が依存するパッケージだけを有効にする(下線部は自分が使うPHPのモジュールによって変わる)。
Package: libargon2* libpcre2* libsodium2* libssl1*
Pin: release o=LP-PPA-ondrej-php
# 他にパッケージがない時だけ、ondrejのPPAのパッケージを使う。

Pin-Priority: 50

なお、上のPin指定の"o="に指定する名前(提供者名)は、1の後に以下のコマンドを実行すれば確認できる。

apt-cache policy | grep -i php | grep "o="

3の追加パッケージを調べるには、必要なPHPのモジュールをaptitudeに指定して、インストールをシミュレートするモード(-sを指定)で実行する。以下にコマンドの例を示す。

sudo aptitude -s install php7.3 \
php7.3-{common,cli,cgi,curl,mbstring,wddx,\
xml,xmlreader,xmlwriter,xsl,opcache,json,\
readline,exif,posix}

上のコマンドを実行すると、依存するパッケージlibargon2-0, libpcre2-8-0, libsodium23, libssl1.1が不足していると出るので、ondrej-php.prefの3番目のPackage指定に追加する(下線部。指定にはワイルドカードが使用可能)。

4の、余計なパッケージがインストール対象でないか確認するには、apt-cacheコマンドやアップデートマネージャーを用いる。以下にapt-cacheコマンドでの確認の例を示す。

apt-cache policy | grep -i php | grep -v sury
apt-cache policy | grep -vi php | grep sury

1番目はPPAの説明が出ればOK、2番目は追加した依存パッケージのみ出ればOKである。

実際のPHPのインストールは、3のコマンドに-sを指定せずに実行すれば良い(私はインストールの前に現在のPHPをアンインストールした)。インストール後に、PHPのバージョン(php -v)やモジュール(php -m)を調べて、想定どおりならOKである。その後、既存のプログラムの動作確認や調整などを行う。

書くと長くなったが、意外に簡単にPHP 7.3に更新することができた。作業時間(事前検討などは含まず)は30分程度だった。これで、再来年の頭までは(大きな問題がない限り、)今のOSでも行けそうだ。

PS. OSをバージョンアップする際は、設定ファイルのPackageで追加したモジュール(libargon2など)はおそらくOSに含まれているだろうから、バージョンアップの前に設定を調整(php7.3*だけにする)した方が良さそうだ(バージョンアップ後でも大丈夫だと思う)。 ← その後、PHP7.3や依存モジュールのPin-Priorityを下げることで、仮に公式パッケージが出た場合やOSのバージョンアップ後には公式のものを優先させる設定にした。

(1/5 6:21 ondrej-php.prefの設定を改良)

  •   0
  •   0

コメントを書く

名前    

メール 

URL