このブログは、ConoHa の VPS に自分で構築した WordPress で動いています。 構築したときの OS は Ubuntu 22.04 だったのですが、今回これを 24.04 にアップグレードしました。
いちばんの目的は、PHP のバージョンを上げることです。
なぜアップグレードしたのか:PHP 8.1 のサポート期間
Ubuntu 22.04 の apt で入る PHP は 8.1、24.04 で入る PHP は 8.3 です。
| Ubuntu 22.04 | Ubuntu 24.04 | |
|---|---|---|
| PHP のバージョン | 8.1 | 8.3 |
| Ubuntu の標準サポート | 2027年4月まで | 2029年4月まで |
PHP 8.1 は、PHP 本家のサポートが 2025 年末で終わっています。Ubuntu がセキュリティ修正を取り込み続けてくれてはいますが、それも 22.04 のサポートが続く間だけです。 一方、24.04 の PHP 8.3 なら、あと数年は安心して使えます。
きっかけは、以前仕事で対応した PHP の脆弱性でした(1本目の記事で少し書きました)。PHP のバージョンとサポート期間を意識するようになり、自分のサーバーも早めに上げておこうと思いました。仕事でも VPS の Ubuntu を 22 系から 24 系に上げる作業が発生しそうなので、その練習も兼ねています。
環境
- ConoHa VPS(メモリ 1GB)
- Ubuntu 22.04 → 24.04
- Apache + PHP(mod_php)+ MySQL 8.0
- WordPress(WP-CLI で構築)、テーマは Cocoon
- Let’s Encrypt で HTTPS 化済み
全体の流れ
- 今の状態を記録する
- WordPress のバックアップを取る
- 22.04 を最新にする
- ConoHa でイメージ保存(スナップショット)
- メンテナンス画面を出す
do-release-upgradeを実行- 再起動後の確認と修正
- 後片付け
作業時間は、アップグレード本体が 30 分くらい。ハマったところの対応を含めると、結局一晩またぐことになりました。
1. 今の状態を記録する
アップグレード後に「何が変わったか」を比べられるように、今の状態をファイルに書き出しておきます。
mkdir -p ~/pre-upgrade && cd ~/pre-upgradelsb_release -a > os.txtphp -v > php.txtphp -m > php-modules.txtsudo apache2ctl -M | sort > apache-modules.txtls /etc/php/8.1/apache2/conf.d/ > php-confd.txtdpkg -l > packages.txtsudo ufw status verbose > ufw.txtsudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication' > sshd.txtsudo certbot certificates > certs.txtsudo -u www-data wp core version --path=/var/www/wordpress > wp.txt
ちなみに最初、apache2ctl -M を sudo なしで実行したら「SSL 証明書のファイルがない」というエラーが出てドキッとしました。証明書は root しか読めない場所にあるので、一般ユーザーからは「ない」ように見えるだけでした。sudo を付けたら普通にモジュール一覧が取れました。
2. WordPress のバックアップを取る
スナップショットはサーバー丸ごと戻す用なので、それとは別に、DB と WordPress のファイルだけを取り出せる形でも残しておきます。
sudo mysqldump --single-transaction wordpress > ~/pre-upgrade/wordpress.sqlsudo tar czf ~/pre-upgrade/wp-files.tgz -C /var/www wordpress
これを scp で手元の Mac にもコピーしておきました。ConoHa 側で何かあっても、別のサーバーにブログだけ移せます。
3. 22.04 を最新にする
do-release-upgrade は、今の OS が最新になっていないと実行を断られます。
sudo apt update && sudo apt full-upgrade -ysudo apt autoremove -y
autoremove で、モデムや USB 関係などの VPS では使わないパッケージがたくさん消えました。アップグレードの前に減らしておくと、依存関係のトラブルや設定ファイルの質問が減るそうです。
4. イメージ保存(スナップショット)
ConoHa のコントロールパネルで、サーバーをシャットダウン → イメージ保存 → 起動しました。起動したままだと DB の書き込み途中の状態で保存されることがあるので、止めてから取ります。
ConoHa ではこれを「イメージ保存」と呼んでいますが、役割としては「この時点に戻せる保険」で、いわゆるスナップショットと同じものです。
5. メンテナンス画面を出す
アップグレード中は PHP が 8.1 から 8.3 に入れ替わるので、サイトが壊れて見える時間があります。そこで、メンテナンス画面を出すことにしました。
ポイントは、WordPress のメンテナンスモードではなく、Apache だけで出すことです。PHP が動かない間も表示できるからです。また、ステータスコード 503 を返すと、Google に「一時的な停止」だと伝わります。
sudo tee /etc/apache2/maintenance.conf <<'EOF'RewriteEngine OnRewriteCond /var/www/MAINTENANCE -fRewriteCond %{REMOTE_ADDR} !^(127\.0\.0\.1|::1)$RewriteCond %{REQUEST_URI} !=/maintenance.htmlRewriteRule ^ - [R=503,L]ErrorDocument 503 /maintenance.htmlEOF
これを HTTPS 側の VirtualHost で Include して、メンテ用の maintenance.html を WordPress のフォルダに置いています。 /var/www/MAINTENANCE というファイルがあるときだけメンテ画面になるので、切り替えは touch と rm だけです。サーバー自身(127.0.0.1)からのアクセスは通すので、メンテ中でもサーバー上の curl で中身を確認できます。
sudo touch /var/www/MAINTENANCE # メンテ ONsudo rm /var/www/MAINTENANCE # メンテ OFF
6. do-release-upgrade を実行
いよいよ本番です。SSH が切れたときの命綱として、ConoHa のコンソール(ブラウザから入れる画面)に事前にログインできるか試しておきました。
sudo do-release-upgrade
消えるパッケージは事前に確認する
「アップグレードを開始するか」の画面で d を押すと、削除・追加・更新されるパッケージの一覧が見られます。ここから先は止められないので、apache2、mysql-server、certbot などが削除の一覧に入っていないことを確認してから y を押しました。php8.1-... が消えて php8.3-... が入るのは予定どおりです。
設定ファイルの質問は「今のものを残す」
途中で何度か「設定ファイルを新しい版にしますか?」と聞かれました。sshd_config、時刻合わせの ntp.conf、cloud-init の cloud.cfg、起動まわりの grub です。
自分では触っていないファイルもあったのですが、ConoHa の初期設定が書き換えているので「変更あり」と判定されていたようです。新しい版にすると、ConoHa 向けの設定が消えてネットワークやコンソールがおかしくなる恐れがあるので、すべて今のものを残しました。迷ったら差分を表示して確認できます。
sshd_config の差分を見てみたら、ConoHa が最後に PasswordAuthentication yes を書き足していました。ただ、私は SSH をパスワード禁止にする設定を sshd_config.d/ の下の別ファイルに書いていて、そちらが先に読まれて優先されるので、実際にはパスワードでは入れない状態です。紛らわしいので、この行は後片付けで消しました。
ハマった①:アップグレード中に Apache が止まった
古いパッケージを削除するあたりで、こんなエラーが出ていました。
Syntax error on line 3 of /etc/apache2/mods-enabled/php8.1.load:Cannot load /usr/lib/apache2/modules/libphp8.1.so ... No such file or directory
PHP 8.1 が削除されたのに、Apache がまだ PHP 8.1 のモジュールを読み込もうとしてエラーになっています。これが、Apache + mod_php の環境で一番起きやすいトラブルだそうです。 途中で止めるほうが危ないので、そのまま最後まで進めて、再起動後に直すことにしました。
7. 再起動後:自宅から SSH できない
再起動して SSH でつなぎ直そうとしたら、
ssh: connect to host (サーバーのIP) port 22: Connection refused
と言われて入れません。
ハマった②:fail2ban に自宅の IP を BAN されていた
ConoHa のコンソールから入って調べると、サーバー側の SSH は正常に動いていました。 サーバーは SSH を待っているのに、自宅からは Connection refused。そこで別の回線から試したら、普通に入れました。自宅の IP だけが締め出されていたのです。
犯人は fail2ban でした。ログイン失敗が続いた IP を自動で BAN してくれる仕組みで、ConoHa の Ubuntu には最初から入っていました。
sudo fail2ban-client status sshd
Banned IP list を見ると、海外の IP にまじって自宅の IP が入っていました。
原因は Mac の SSH の動きです。Mac に鍵が複数あると、SSH は -i で指定した鍵の前に、ほかの鍵も順番に試すことがあります。サーバー側ではそれが「ログイン失敗」として数えられ、この日は何度もつなぎ直していたこともあって、BAN されてしまったようです。
別の回線から入って BAN を解除しました。
sudo fail2ban-client unban (自宅のIP)
再発防止に、Mac の ~/.ssh/config に IdentitiesOnly yes を書いて、指定した鍵しか使わないようにしました。
Host blog HostName (サーバーのIP) User (ユーザー名) IdentityFile ~/.ssh/(このサーバー用の鍵) IdentitiesOnly yes
これで ssh blog だけで入れるようになり、余計な鍵を試して BAN されることもなくなりました。
ちなみに BAN リストのほかの IP は、本物の攻撃でした。再起動してから短い時間の間に、SSH へのログイン失敗が 100 回以上記録されていました。fail2ban がちゃんと仕事をしていたわけですが、自分まで巻き込まれたのは予想外でした。
Apache の PHP を 8.1 → 8.3 に切り替える
やっと SSH で入れたので、止まっていた Apache を直します。
sudo a2dismod php8.1sudo a2enmod php8.3sudo apache2ctl configtestsudo systemctl restart apache2
Syntax OK が出て、Apache が PHP 8.3 で動き出しました。
アップロード上限を 8.3 側にも設定する
前の記事で「アップグレードしたら確認しよう」と書いていたアップロード上限です。予想どおり、/etc/php/8.1/ に置いた設定は 8.3 には引き継がれていなかったので、8.3 側に作り直しました。
sudo tee /etc/php/8.3/apache2/conf.d/99-upload.ini <<'EOF'upload_max_filesize = 64Mpost_max_size = 64MEOFsudo systemctl restart apache2
確認
lsb_release -dphp -v | head -1dpkg -l php8.3-common | tail -1systemctl is-active apache2 mysqlsudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication'sudo certbot renew --dry-runsudo -u www-data wp core verify-checksums --path=/var/www/wordpress
- OS:Ubuntu 24.04.5 LTS
- PHP:8.3.6
- Apache と MySQL:どちらも active
- SSH:root 禁止・パスワード禁止のまま
- 証明書の自動更新:リハーサル成功
- WordPress のファイル:改ざん・破損なし
メンテ画面を外して、ブラウザでトップページ、記事ページ、管理画面へのログイン、画像のアップロードまで確認して完了です。
PHP 8.3.6 は古くない?
php -v を見ると 8.3.6 と出ます。PHP 8.3 の最新版はもっと先まで出ているので、古いのでは?と思いました。
見るべきは、dpkg -l で出てくる後ろの部分です。
php8.3-common 8.3.6-0ubuntu0.24.04.13
Ubuntu は PHP 本体の番号を 8.3.6 のまま固定して、セキュリティ修正だけを取り込んでいます(バックポート)。修正のたびに、後ろの ubuntu0.24.04.13 の数字が増えていきます。 仕事で対応した脆弱性も、Ubuntu のセキュリティ情報のページで「24.04 の php8.3 は 8.3.6-0ubuntu0.24.04.13 で修正」とされていて、ちょうどこの版でした。
8. 後片付け
最後に、古いものを片付けました。
sudo apt autoremove -ydpkg -l | grep php8.1
php8.1-... が rc という状態で 13 個残っていました。rc は「本体は削除済み、設定ファイルだけ残っている」という意味だそうです。まとめて完全削除(purge)しました。
sudo apt purge -y $(dpkg -l | awk '/^rc/ && /php8\.1/ {print $2}')
それでも /etc/php/8.1 のフォルダが残りました。apt は自分が入れたファイルしか消さないので、私が手で作った 99-upload.ini が残っていたからです。中身がそれだけなのを確認して、フォルダごと消しました。
ほかにやったこと:
- サーバー上に置いたバックアップ(DB の中身入り)を削除(Mac にコピー済み)
- sshd_config に残っていた紛らわしい
PasswordAuthentication yesの行を削除 - 数日問題がなければ、ConoHa のアップグレード前イメージを削除する予定
まとめ
- PHP 8.1 から、サポート期間の長い 8.3 にするために Ubuntu を 22.04 → 24.04 にアップグレードした
- 事前の記録、アプリ単位のバックアップ、イメージ保存をしてから実行した
- Apache だけで出すメンテ画面(503)は、PHP が壊れている間も表示できて便利
- 設定ファイルの質問は、基本「今のものを残す」
- Apache + mod_php だと、アップグレード後に
a2dismod php8.1→a2enmod php8.3が必要 /etc/php/8.1/に置いた自分の設定は、8.3 側に作り直す- SSH が切れたときの命綱(ConoHa のコンソール)は、事前にログインできるか試しておく
- 鍵が複数ある Mac から何度もつなぎ直すと、fail2ban に BAN されることがある。
IdentitiesOnly yesで防げる
手順だけ見ればコマンドを何行か打つだけなのですが、実際にやってみると、Apache が止まったり、自分の防御策に自分が締め出されたりと、思わぬところでつまずきました。仕事で本番サーバーを上げる前に、自分のサーバーで一度経験できて本当によかったです。
同じように Ubuntu のアップグレードを考えている方の参考になればうれしいです。

