有馬総一郎のブログ

(彼氏の事情)

2026年04月25日 19:29:25 JST - 7 minute read - Linux

Ubuntu Serverを24.04 にアップグレードする (`/boot`容量不足、`nginx`パッケージ競合など)

自宅サーバーのUbuntu 22.04をそろそろ24.04にアップグレードしようと思い立った。今まで割とすんなりアップグレード出来たのに、今回は何度か中断してしまった…

事前準備

まずシステムを最新化してからバックアップを取る。ログとキャッシュは容量が大きいので除外した。今思えばdockerのイメージも除外しておけば良かった。

sudo apt update && sudo apt upgrade -y && sudo apt dist-upgrade -y

sudo tar -czf /mnt/middle/etc_home_var_$(date +%Y%m%d).tar.gz \
  --exclude=/var/log \
  --exclude=/var/cache \
  /etc /home /var

念のため、現在インストールされているパッケージの一覧もバックアップしておく。

dpkg --get-selections | grep -v deinstall > ~/package-list-backup.txt

次に、アップグレード中に邪魔しそうなものを片付ける。WireGuardは使わなくなっていたので削除し、DockerはユーザーサービスとしてDockerを停止する。外部ストレージ(/mnt/hdd1/mnt/xfs/mnt/middle)は全部アンマウントしておく。

# WireGuard停止・削除
sudo systemctl stop wg-quick@wg0
sudo systemctl disable wg-quick@wg0
sudo apt remove wireguard wireguard-tools
sudo apt autoremove
sudo rm -rf /etc/wireguard/

# Dockerを停止
systemctl --user stop docker
systemctl --user disable docker

# 外部ストレージをすべてアンマウント
sudo umount /mnt/hdd1 /mnt/xfs /mnt/middle

/etc/fstabの外部ストレージのエントリ(/mnt/hdd1/mnt/middle/mnt/xfs)もコメントアウトしておく。アップグレード後の再起動が終わったら戻す。

最後に、リポジトリ設定を確認する。/etc/apt/sources.list.d/docker.listについて、Claudeが自動置換されないのでnobleに変更しておけといっていたが、アップグレード後にすれば良い。そうしないと、OSアップグレードで再実行するときにアップデートしておくものが残っていると実行できなくなる。

byobuで実行する必要はなかった

sudo do-release-upgradeを実行する時は、セッションが切れても大丈夫なようにbyobuを起動してから実行した。しかし、実はdo-release-upgrade自体がscreenを内部で自動起動してセッションを保護してくれるため、byobuでの実行不要だった。

ログにも re-exec inside screen: '['screen', '-e', '\\0\\0', '-c', 'screenrc', '-S', 'ubuntu-release-upgrade-screen-window', '/tmp/ubuntu-release-upgrader-i_2szg_4/noble', '--mode=server', '--frontend=DistUpgradeViewText']'と記録されており、SSH接続が切れてもアップグレードが中断されない仕組みが最初から備わっていた。

アップグレード失敗後であってもbyobuセッションの中にいたため、再度byobuを起動しようとして「セッションがネストしますよ」と警告が出た。tmux list-sessionsで確認しても別な操作は不要で、そのままsudo do-release-upgradeを再実行すれば良かった。

/boot の空き容量が足りない

実行してみると早速エラーが出て止まった。

アップグレードには '/boot' に空き領域が 258 M 必要です

df -h /bootで見ると空き186Mdpkg -l | grep linux-imageを叩くと、4.15系カーネルがrcステータスのまま大量に残っていた。設定ファイルだけ残った状態なので、一括で掃除する。そして、rcステータスのカーネルを一括削除した。

dpkg -l | grep '^rc.*linux-image' | awk '{print $2}' | xargs sudo dpkg --purge

# 古いカーネルイメージを削除(使用中の5.15.0-176は残す)
sudo apt remove --purge linux-image-5.15.0-174-generic
sudo apt autoremove --purge

これで/bootの空きが186Mから312Mに回復した。

do-release-upgradeを再実行すると、今度はaptdpkgが別のプロセスにロックされているというエラーが出た。念のため、裏でパッケージ操作を邪魔しそうなunattended-upgradesも止めておくことにする。

sudo systemctl stop unattended-upgrades
sudo systemctl disable unattended-upgrades

nginxのパッケージ競合

続けて以下のエラーも出た。

'/usr/sbin/nginx' を上書きしようとしています。これはパッケージ nginx-core 1.23.2-1+ubuntu20.04.1+deb.sury.org+1 にも存在します

以前sury.orgのサードパーティリポジトリからインストールしたnginxが残っていたのが原因だ。完全に削除してから入れ直す。

sudo apt remove --purge nginx nginx-core nginx-common libnginx-mod-stream-geoip libnginx-mod-http-geoip
sudo apt update
sudo apt install nginx

これで、解消するかと思いきや…直らなかった。sudo apt --fix-broken installで解消されて一気にアップグレードが進んだ。

アップグレード前に設定を確認・修正

アップグレードが進むとSambaのsmb.conf、ネットワーク設定のsysctl.confなどのリリースメンテナンスとの差分確認が発生する。差分を確認したら、メモしておき、リリースメンテナンスのままインストールして、後で変更点を手動で追加していった。

SSHのsshd_configだけは、下手に修正するとリモート接続できなくなる可能性がある。

-#Port 22
+Port 12345

-#PermitRootLogin prohibit-password
+PermitRootLogin no

一旦はそのままにしようと思ったが、ポートの変更、rootログインの禁止の修正分だけなので、マージ機能で綺麗に反映することができた。

アップグレード完了

これで一気に最後までいくかと思いきや、/etc/locale.aliasのインストールでいきなり中断。

新バージョンの設定ファイル /etc/locale.alias をインストールしています ...
Generating locales (this might take a while)...
  en_AG.UTF-8... done
  ・・・中略・・・
  ja_JP.UTF-8... done
Generation complete.
libc-dev-bin (2.39-0ubuntu8.7) を設定しています ...
libc6-dev:amd64 (2.39-0ubuntu8.7) を設定しています ...
man-db (2.10.2-1) のトリガを処理しています ...
未解決のクラッシュレポートはありません。詳しくは --help を試してみてください。

アップグレードをインストールできません

アップグレードを中断しました。システムが不安定な状態の可能性があります。今からリカバリーを実行します。(dpkg --configure -a)

中断原因は分からなかったが、中断された直後の自動リカバリー(dpkg --configure -a)も失敗していた。

E:Could not get lock /var/lib/dpkg/lock. It is held by process 2018306 (dpkg), W:Be aware that removing the lock file is not a solution and may break your system., E:管理用ディレクトリ (/var/lib/dpkg/) をロックできません。これを使う別のプロセスが動いていませんか?

既にunattended-upgradesは止めていたため、Geminiに言わせると、恐らくアップグレード処理自体が異常終了した際にdpkgのロックを掴んだまま(ゾンビプロセス化して)残ってしまい、自分自身のリカバリー処理をブロックしてしまったのだろう。

アップグレードの中断、リカバリー処理もブロックされたとはいえ、lsb_release -aで確認するとUbuntu 24.04.4 LTSになっていた。

そのままsudo apt upgradesudo apt autoremovesudo apt dist-upgradeを実行すると、問題なく全てのパッケージが更新された。最後にsudo rebootをして再起動する。

再起動後の後片付け

再起動後はまずsystemctl --failedで問題のあるサービスを確認。postfixが動いていたが使っていないので無効化した。

systemctl --failed
sudo systemctl disable --now postfix

/etc/fstabの外部ストレージを有効化して、再マウント。

sudo systemctl daemon-reload
sudo mount -a

次にDockerを有効化・起動し、各サービスを順番に立ち上げた。

systemctl --user enable docker.service
systemctl --user start docker
systemctl --user restart immich.service
systemctl --user restart seafile.service

Nginx Proxy Managerが起動しない

npmのサービスを起動しようとしたが、コンテナがDNS解決をループして起動できなかった。npmはリバースプロキシとしてimmich、seafileなどのコンテナに接続するため、これらが揃っていないとDNS解決に失敗してループしてしまう。

immichとseafileはsystemdユーザーサービスとして管理しているので先に立ち上げていたのだが、Dockerのcomposeで管理しているコンテナ群がまだ上がっていなかった。このcomposeコンテナはDockerサービス起動時に自動で立ち上がる想定で、個別にsystemdサービスを登録していなかったため、揃っていないことに気付くのが遅れた。

docker compose up -d

これでcompose側のコンテナが揃い、npmも正常に起動した。

リポジトリをnobleに更新して仕上げ

Sambaの文字コード設定(dos charset = CP932 / unix charset = UTF-8)、そして共有フォルダ設定を追記してアップグレード前状態に戻す。続けて外部リポジトリのコードネームをnobleに更新し、諸々の後片付けをして完了とした。

grep -h "^deb" /etc/apt/sources.list.d/*.list  # jammy が残っているリポジトリを確認

sudo sed -i 's/jammy/noble/' /etc/apt/sources.list.d/cloudflared.list
sudo sed -i 's/jammy/noble/' /etc/apt/sources.list.d/docker.list
sudo apt update && sudo apt upgrade

sudo rm /etc/apt/sources.list.d/*.distUpgrade
sudo apt dist-upgrade
sudo apt autopurge

sudo systemctl enable unattended-upgrades
sudo systemctl start unattended-upgrades

できれば不要なパッケージとか削除しておきたいが、もう手動インストールパッケージ(apt-mark showmanual)が396件あるの、どうしたものか?

Ubuntu 16.04からアップグレードしてきたが、今回は、中断が3回とトラブルが多かったが、大きなエラーはなくアップグレードできたので良かった。