SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

Ubuntu 24.04 升級 26.04:VPS 安全流程

Ubuntu 24.04 要等 26.04.1 於 2026 年 8 月 27 日發布後才能升級。了解正確順序,以及 PHP、PostgreSQL、OpenSSH 等服務可能遇到的問題。

何時可以將 Ubuntu 24.04 升級至 26.04?

VPS 上的 Ubuntu 24.04 必須等到 26.04.1 point release 發布後才能升級,預定日期為 27 August 2026。在此之前,24.04 server 不會看到新版本,這是刻意的設計。Ubuntu 26.04 LTS (Resolute Raccoon) 已於 23 April 2026 發布,但 Canonical 只會在第一個 point release 發布後開放 LTS 到 LTS 的升級路徑,因為該版本會整合前幾個月發現的安裝與升級問題。

在 2026 年 8 月初於 24.04 主機執行檢查時,會看到以下結果:

sudo do-release-upgrade
Checking for a new Ubuntu release
No new release found.

這不是 server 發生故障。/etc/update-manager/release-upgrades 在 Ubuntu Server 上包含 Prompt=lts,表示該工具只會提供下一個 long term support release,而且必須等到其 .1 point release 存在後才會提供。若設定 Prompt=normal,工具會依序引導你升級至 24.10、25.04 和 25.10;這些 interim release 都已結束支援。請維持 lts 設定並等待。Canonical 的時程可能變動,因此如果預定日期過後仍沒有新版本,請再次檢查。

以下每個 command 都必須由你依照指定順序,在自己的 server 上執行。無法在正在升級的主機上預演 release upgrade。升級程序會替換 kernel 和 C library,並需要重新開機才能完成。

是否應該升級?

Ubuntu 24.04 會持續提供標準安全更新至 2029 年,因此正常運作的正式環境伺服器沒有升級期限。只有在需要 26.04 提供的元件時才升級,例如 PHP 8.5、PostgreSQL 18、MySQL 8.4 LTS、OpenSSH 10.2 或 7.0 kernel。「版本號變大了」不是修改服務客戶之伺服器的理由。

符合以下任一情況時,不要直接進行原地升級:

  • 你從未開啟供應商的主控台(VNC 或 serial)並透過它登入。若 SSH 失效,該主控台是重新存取伺服器的唯一方式;等到被鎖在外面才發現主控台無法使用,已經太遲。
  • 你無法承擔 1 小時的停機時間,且沒有 rollback。
  • 你的 stack 依賴尚未針對 resolute 發布套件的第三方 repository。
  • 這台伺服器是兩年前手動建置的,而且沒有人知道其中有哪些設定或元件。

通常更好的做法是建置全新的 26.04 VPS、安裝 stack 並還原資料,確認服務正常回應後再切換 DNS。保留舊伺服器運作,直到新伺服器通過驗證;發生問題時,只需修改 DNS,不必進行還原。若採用這種方式,請從新 VPS 的前 10 分鐘開始,正確建置新的伺服器。

步驟 1:建立可還原的備份

使用兩層備份,因為它們的失效方式不同。供應商的 snapshot 涵蓋整個磁碟,可在幾分鐘內還原,但建立 snapshot 時資料庫仍可能正在寫入,因此它只能達到當機一致性,而不是應用程式一致性。使用 restic,儲存於伺服器外部進行檔案層級備份,則可還原單一檔案,也能在帳戶遭鎖定時保留一份可用的副本。

先手動傾印資料庫。若不停止資料庫,dump 是唯一可在不停止服務的情況下信任的資料庫備份。

sudo -u postgres pg_dumpall | sudo tee /var/backups/pg-all.sql > /dev/null
sudo mysqldump --all-databases --single-transaction --routines | sudo tee /var/backups/mysql-all.sql > /dev/null
sudo tar czf /var/backups/etc-before-upgrade.tgz -C / etc
sudo chmod 600 /var/backups/pg-all.sql /var/backups/mysql-all.sql

--single-transaction 只會對 InnoDB 資料表建立一致的 dump。MyISAM 資料表需要先停止資料庫。/etc tarball 才是你實際會優先使用的備份,因為它包含升級過程即將要求你確認的所有設定檔。

從未還原過的備份只是猜測。在真正需要且面臨壓力之前,現在就先從備份中取出一個檔案。

先完整修補 24.04

do-release-upgrade 不會在套件狀態損壞的系統上執行,而未完成修補的 24.04 會讓後續每個錯誤都更難判讀。

sudo apt update
sudo apt full-upgrade
sudo apt --purge autoremove
sudo dpkg --audit
apt-mark showhold

dpkg --audit 沒有輸出表示沒有套件處於半設定狀態。apt-mark showhold 沒有輸出表示沒有套件被鎖定在會阻擋升級的版本。使用 sudo apt-mark unhold 加上套件名稱,解除其中列出的鎖定;或確認該鎖定有其原因,然後停在這裡。

如果 kernel 已變更,請重新開機。這樣升級時,機器執行的程式碼才會與系統認為目前正在執行的版本一致。

[ -f /var/run/reboot-required ] && sudo reboot

接著檢查磁碟空間。升級程式會先下載完整的新套件集,再開始安裝。空間不足時,會中止並顯示發生問題的檔案系統。

df -h / /boot

/ 可用空間低於約 5 GB 時,通常會在這裡失敗。/boot 小於 300 MB 時,稍後在安裝 kernel 期間會因 No space left on device 而失敗。通常是舊 kernel 導致此問題,sudo apt --purge autoremove 可清除這些舊版本。

開始前還要先停止一項工作:如果 自動安全性更新 在升級期間執行,會鎖定 dpkg,讓版本升級程式因 Could not get lock /var/lib/dpkg/lock-frontend 而停止。先執行 sudo systemctl stop unattended-upgrades,完成後再重新啟動升級程式。

步驟 3:檢查第三方套件庫與釘選套件

do-release-upgrade 會停用所有不是 Ubuntu 套件庫的 apt 來源,因為為 noble 建置的套件可能會使 resolute 系統失效。之後,它會重新啟用可辨識的來源,並將其餘來源保留為註解狀態。在工具替你決定之前,先了解系統目前包含哪些來源與套件。

ls /etc/apt/sources.list.d/
grep -rhE '^(deb |Types:|URIs:|Suites:)' /etc/apt/sources.list.d/
ubuntu-security-status --thirdparty
ls /etc/apt/preferences.d/

Ubuntu 24.04 在該目錄中使用兩種格式:舊式單行 .list 檔案,以及包含 Types:Suites: 欄位的 deb822 .sources 檔案。升級時,這兩種格式都會被停用。ubuntu-security-status --thirdparty 會列出沒有任何 Ubuntu 封存庫提供的已安裝套件,這能如實呈現你額外安裝的套件數量。/etc/apt/preferences.d/ 中的任何項目都是 pin,而針對 noble 撰寫的 pin 會在新版本中持續選用舊套件。

對每個第三方套件庫,請先確認供應商已針對新的 codename 發布套件,再開始升級。Docker 的 suites 列於 https://download.docker.com/linux/ubuntu/dists/,其他供應商也會提供相同的目錄。若來源指向不存在的 suite,升級後第一次執行 apt update 時會出現以下訊息:

E: The repository 'https://download.docker.com/linux/ubuntu resolute Release' does not have a Release file.

在供應商發布套件前,請維持該來源停用。將 codename 修改為供應商確實建置過的版本,才不會安裝連結至錯誤系統函式庫的套件。

步驟 4:在 tmux 中執行升級,不要使用一般的 SSH shell

如果在一般登入 shell 中執行 do-release-upgrade 時連線中斷,該程序會收到 SIGHUP,並在解開套件的過程中途停止。這會讓 dpkg 處於半設定狀態,伺服器也可能因此失去可用的網路堆疊,導致無法重新連線。請改在終端機多工器中執行,這樣即使用戶端中斷,程序仍會在伺服器上繼續執行。

sudo apt install -y tmux
tmux new -s upgrade

在該工作階段中:

sudo ufw allow 1022/tcp
sudo do-release-upgrade

升級程式會先在變更任何內容前,於 1022 埠啟動第二個 SSH daemon,並顯示相關訊息:

To make recovery in case of failure easier, an additional sshd will be started on port '1022'. If anything goes wrong with the running ssh you can still connect to the additional one.

它不會替你在防火牆中開啟該埠,因為未經詢問就修改防火牆規則可能造成意外。開始前,請自行開啟 1022;完成 sudo ufw delete allow 1022/tcp 後再關閉該埠。請注意,服務供應商可能會在控制面板中另行執行第二層防火牆,且該防火牆位於伺服器之外。

如果連線仍然中斷,請重新登入並執行 tmux attach -t upgrade。你離線期間,升級程序仍會持續執行。

步驟 5:審慎回答設定檔提示

dpkg 只會針對你或指令碼修改過的檔案顯示提示。因此,每個提示都代表你曾刻意編輯過的檔案。按下 Enter 讓提示消失,可能會讓強化過的伺服器在不知不覺間恢復成預設設定。

Configuration file '/etc/ssh/sshd_config'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** sshd_config (Y/I/N/O/D/Z) [default=N] ?

每次都先按 D。查看變更內容,然後使用 N 保留你的版本。預設選項已經是 N,這是安全的選擇,因為你的檔案目前能正常運作,而套件提供的檔案從未在這台機器上執行過。

保留你的檔案會有代價:你不會取得新的預設設定。等系統恢復運作後,再於沒有時間壓力時進行比對與整合。

sudo find /etc -name '*.dpkg-dist' -o -name '*.dpkg-new'

每個列出的檔案都是維護者版本,並儲存在你的檔案旁邊。逐一比較差異,將重要設定複製過來。其中有兩個檔案需要特別仔細處理:/etc/ssh/sshd_config,因為選錯會終止你的工作階段;以及網頁伺服器設定檔,因為選錯會使網站停止運作。

升級程序也會透過 needrestart 詢問要重新啟動哪些服務。接受完整清單。若 daemon 仍使用已從磁碟刪除的共享函式庫檔案,之後可能在某個請求到達時當機,而你當時可能沒有監控系統。

步驟 6:重新開機,然後檢查機器

sudo reboot

機器重新啟動後:

lsb_release -a
uname -r
systemctl --failed
journalctl -p err -b --no-pager | head -50
sudo apt update && sudo apt full-upgrade
sudo apt --purge autoremove

lsb_release -a 應回報 Release: 26.04Codename: resoluteuname -r 應顯示 7.0 核心。systemctl --failed 應列出 0 個單元;若列出任何項目,請優先處理這些項目。最後的 apt update 會取得發行映像檔建立後發布的更新。

PostgreSQL 16 到 18:悄悄停留在原地的 cluster

Ubuntu 24.04 隨附 PostgreSQL 16,26.04 隨附 PostgreSQL 18。升級程序會在 PostgreSQL 16 旁安裝 PostgreSQL 18,但不會搬移資料。Debian 的 postgresql-common layer 會在下一個可用的連接埠上,為新 major version 建立新的空 cluster,因此 PostgreSQL 16 會繼續使用連接埠 5432 與所有資料,而 PostgreSQL 18 則停留在連接埠 5433,且內容為空。應用程式會繼續連線到連接埠 5432,看不出任何異常,因此許多人直到數月後才發現問題。

pg_lsclusters

列出兩個 cluster 表示尚未完成 migration。請在可以停止應用程式時執行:

sudo pg_dropcluster --stop 18 main
sudo pg_upgradecluster 16 main
pg_lsclusters
sudo -u postgres vacuumdb --all --analyze-only

先刪除空的 PostgreSQL 18 cluster,因為 pg_upgradecluster 不會寫入已存在的 target cluster。預設方法會將 PostgreSQL 16 傾印後重新載入 PostgreSQL 18,因此需要約等同於資料庫大小的可用磁碟空間。-m upgrade 則使用 pg_upgrade,處理大型資料庫時速度快得多。完成後,查看 Port 欄位:新的 cluster 會接管連接埠 5432,而舊的 cluster 會維持停止狀態。請自行執行 analyze pass,因為新載入的 cluster 沒有統計資料,初次查詢會很慢。

讓應用程式使用新的 cluster 執行幾天進行測試。確認無誤後,再移除舊的 cluster:

sudo pg_dropcluster 16 main
sudo apt purge postgresql-16

舊 cluster 的 data directory 是最快速的 rollback 手段。不要在 upgrade day 刪除它。

MySQL 8.0 至 8.4:遭移除的選項會導致伺服器停止

26.04 會將 MySQL 從 8.0 升級至 8.4 LTS,其中有兩項變更可能導致伺服器出問題。

首先,mysqld 的設定檔若包含新版已移除的選項,就會拒絕啟動。default_authentication_plugin 是常見選項,因為許多較舊的指南都要求設定它。服務會啟動失敗,而 journalctl -u mysql -n 50 會直接指出未知的變數。從 /etc/mysql/mysql.conf.d/ 下的檔案中刪除該行,然後執行 sudo systemctl start mysql

其次,mysql_native_password 外掛程式在 8.4 中不再預設啟用,因此仍使用該外掛程式的帳戶完全無法登入。請在仍使用 8.0 時檢查:

sudo mysql -e "SELECT user, host, plugin FROM mysql.user;"

在升級前,先移轉所有顯示 mysql_native_password 的帳戶,然後更新應用程式設定中的密碼:

ALTER USER 'appuser'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'a new password';

如果用戶端函式庫版本過舊,無法使用 caching_sha2_password,可以在 8.4 中於 [mysqld] 下加入 mysql_native_password=ON,重新啟用舊外掛程式。這只能作為過渡方案,並應設定終止使用的期限,因為該外掛程式最終將完全淘汰。

PHP 8.3 到 8.5:您的 vhost 指向已不存在的 socket

24.04 提供 PHP 8.3,26.04 提供 PHP 8.5。套件會安裝到含版本號的路徑,且不會改寫您的網頁伺服器設定。某個 nginx vhost 中的 fastcgi_pass unix:/run/php/php8.3-fpm.sock; 現在指向沒有任何程序建立的 socket,因此所有 PHP 請求都會回傳 502,nginx error log 會顯示:

connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)

將它指向新的 socket,測試設定後重新載入:

sudo sed -i 's/php8.3-fpm.sock/php8.5-fpm.sock/' /etc/nginx/sites-available/example.com
sudo nginx -t
sudo systemctl reload nginx

若在 Apache 上使用 mod_php,症狀會不同:Apache 完全無法啟動,而 sudo apache2ctl -t 會回報無法載入 libphp8.3.so,因為該檔案不存在。已啟用的模組是指向已移除套件的符號連結。

sudo a2dismod php8.3
sudo a2enmod php8.5
sudo systemctl restart apache2

如果您是依照 Ubuntu 24.04 上的 LAMP stack 建置伺服器,這兩個路徑都值得檢查,因為該指南會留下含版本號的模組名稱和 socket。

您的 php.ini 調校設定也不會自動沿用。memory_limitupload_max_filesize 及其他設定都位於 /etc/php/8.3/,新的目錄樹會從預設值開始。比較這兩個檔案,然後手動複製設定值。若直接將整個舊檔案覆寫到新檔案,會把 8.3 的預設值帶入 8.5 安裝。接著執行 php -m 並進行比較:以 php8.3-redis 安裝的 extension 需要其 php8.5- 套件;如果該 extension 來自 PPA,升級程式會停用該來源,extension 也會直接消失。

憑證需要另外檢查一次。升級後執行 sudo certbot renew --dry-run。這會測試完整的續期流程,包括網頁伺服器重新載入 hook,但不會變更目前使用中的憑證。如果 hook 呼叫了服務名稱或已變更的 binary,這裡就會立即失敗,而不是在 60 天後無聲無息地失敗。在 nginx 上使用 Let's Encrypt 搭配 Certbot 說明這些 hook 應有的形式。

SSH:終止目前工作階段的故障

sshd_config 提示字元是最容易讓人失去存取權的地方。回答 Y 會安裝維護者提供的檔案,並捨棄你的 PermitRootLoginPasswordAuthenticationAllowUsersPort 以及其他自行加入的每一行設定。如果防火牆只允許自訂埠,而套件提供的設定在 22 埠監聽,下一次連線就會遭到拒絕;你目前所在的工作階段也會成為最後一個可用的工作階段。

請在升級前先預防這個問題。Ubuntu 24.04 的 /etc/ssh/sshd_config 會從 Include /etc/ssh/sshd_config.d/*.conf 開始,而 OpenSSH 對每項設定都採用第一個讀到的值,因此在檔案開頭載入的 drop-in 設定會覆寫後方的設定。將你的設定移到 dpkg 不擁有的檔案中:

sudo tee /etc/ssh/sshd_config.d/99-local.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
AllowUsers deploy
EOF
sudo chmod 644 /etc/ssh/sshd_config.d/99-local.conf
sudo sshd -t && sudo systemctl restart ssh

/etc/ssh/sshd_config 中不再有任何由你管理的設定後,該提示就不再重要:無論選擇哪個回答,都會保留你的設定,因為設定位於另一個檔案中。

自訂埠還需要再檢查一次,因為實際設定位置可能與預期不同:

systemctl is-enabled ssh.socket

如果輸出 enabled,表示 systemd 管理監聽埠,而 sshd_config 中的 Port 設定會被忽略。自 22.10 起,Ubuntu 便已對 sshd 使用 socket activation,這就是修改 Port 2222 後看似沒有作用的原因。請改在 socket unit 上設定,使用 sudo systemctl edit ssh.socket

[Socket]
ListenStream=
ListenStream=2222

空白的 ListenStream= 是必要的。它會清除繼承的值;若缺少此設定,socket 也會在 22 埠上監聽,而不只是在 2222 埠上監聽。使用 sudo systemctl daemon-reload && sudo systemctl restart ssh.socket 套用設定。

升級完成後,在關閉目前工作階段前:

sudo sshd -t
sudo systemctl status ssh.socket --no-pager
sudo ss -lntp | grep -E ':(22|2222)'

接著在自己的電腦上開啟第二個終端機,重新登入。第二個終端機中的可用 shell 是唯一有效的驗證方式。在確認前,請保持第一個工作階段開啟。VPS 上的 SSH 強化設定 說明了值得保留在該 drop-in 檔案中的設定。

如果現在已經太晚,服務商提供的 Web 主控台可讓你使用完全不透過 SSH 的登入方式。登入主控台後修正設定,執行 sudo sshd -t,再重新啟動服務。這正是你應在升級前測試主控台存取,而不是等到升級期間才測試的原因。

FAQ

為什麼在 Ubuntu 24.04 上執行 do-release-upgrade 會顯示「No new release found」?

因為在 Ubuntu Server 上,/etc/update-manager/release-upgrades 包含 Prompt=lts;這項設定只會在下一個長期支援版本的第一個 point release 發行後提供升級選項。Ubuntu 26.04 LTS 已於 23 April 2026 發行,26.04.1 預定於 27 August 2026 發行。在此之前,24.04 伺服器不會偵測到新版本。請維持原設定,不要切換至 Prompt=normal,否則系統會改經由 interim releases 升級。

我必須重新開機才能完成升級嗎?

是。升級程序會安裝新的 kernel、新的 C library 和新的 init system;執行中的系統在重新開機前仍會使用舊版本。do-release-upgrade 會在結尾要求重新開機。若讓機器繼續執行到「稍後」,系統就會同時使用兩個版本的元件。重新啟動後,請檢查 uname -r 以確認新的 kernel,並檢查 systemctl --failed 以找出未能恢復執行的服務。

我應該直接升級,還是建立全新的 26.04 伺服器?

可行時,請建立全新的伺服器。新的 VPS 可讓你在舊伺服器仍持續提供網路流量時,安裝服務堆疊、還原資料並測試所有功能。因此,回復方式只需變更 DNS,不必從備份還原。若伺服器包含難以搬移的狀態資料、供應商按機器計費,或你已有 snapshot 且確認可使用主控台,則可直接升級。直接升級的流程已相當成熟,但在執行期間,這是一條單向路徑。

如果升級期間 SSH 連線中斷,會發生什麼事?

在一般 login shell 中,程序會收到 SIGHUP 並於中途結束,導致 dpkg 只完成部分設定。請在 tmuxscreen 中啟動升級程序,這樣程序就能持續執行;重新連線後,再執行 tmux attach -t upgrade 以接續升級程序。升級程式也會在 port 1022 啟動備用 SSH daemon,作為第二個連線方式。但它不會替該 port 開啟防火牆規則,因此請先自行允許 1022,完成後再關閉該規則。

升級後,我的 PHP 網站回傳 502。哪裡出問題?

PHP FPM socket 的路徑會隨版本變更。Ubuntu 24.04 執行 PHP 8.3,26.04 執行 PHP 8.5,因此 /run/php/php8.3-fpm.sock 已不存在,但你的 nginx vhost 仍指定該路徑。nginx error log 會顯示 connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)。請將 fastcgi_pass 更新為 8.5 socket,執行 sudo nginx -t,然後重新載入 nginx。若 Apache 使用 mod_php,對應的修正方式是執行 sudo a2dismod php8.3,接著執行 sudo a2enmod php8.5 並重新啟動服務。