Debian releases a new stable version roughly every two years. Debian 13 “trixie” was released in August 2025, and Debian 12 “bookworm” is supported until mid-2026, with LTS support after that. Debian upgrades don’t use a special tool. You point apt at the new release and upgrade, carefully, in two stages. This guide follows the official release-notes procedure in a server-friendly way.
The same method works for other steps (11 → 12). Always upgrade one release at a time.
1. Prepare
Back up databases, /etc, web roots and app data to another server. See database backup automation.
Check the current version and update fully:
cat /etc/debian_version
sudo apt update
sudo apt full-upgrade
sudo apt autoremove --purge
sudo reboot
Check disk space (df -h / /boot). An upgrade needs a few GB.
Find non-Debian packages and repositories:
ls /etc/apt/sources.list.d/
apt list '?narrow(?installed, ?not(?origin(Debian)))' 2>/dev/null
Third-party repositories (Docker, PostgreSQL PGDG, sury PHP, Node) need trixie support. Check each vendor before switching them over, or disable them temporarily.
Remove held packages, or understand why they’re held: apt-mark showhold.
Read the release notes, especially “Issues to be aware of”. They list changed defaults and removed packages.
2. Switch apt sources to trixie
Debian 12 typically uses /etc/apt/sources.list. Debian 13 prefers the deb822 format in /etc/apt/sources.list.d/debian.sources, but both work. The simplest approach:
sudo cp -a /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's/bookworm/trixie/g' /etc/apt/sources.list
sudo sed -i 's/bookworm/trixie/g' /etc/apt/sources.list.d/*.list 2>/dev/null # only for repos that support trixie
The result should look like this:
deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware
Use trixie, not stable. Otherwise the server would jump to the next release automatically one day.
3. Upgrade in two stages (inside tmux)
tmux new -s upgrade
sudo apt update
Minimal upgrade first. It upgrades packages without removing or adding any, which reduces the risk of a broken state:
sudo apt upgrade --without-new-pkgs
Then the full upgrade:
sudo apt full-upgrade
During the upgrade:
- Config file prompts: press D to view the diff, and keep your version (N) unless you want the new defaults. The new file is saved as
*.dpkg-dist. - Service restart prompts: yes.
- Read the package removal list before confirming. Look for anything important.
If the connection drops, reattach with tmux attach -t upgrade. See tmux.
4. Reboot and check
sudo reboot
cat /etc/debian_version # 13.x
uname -r
systemctl --failed
sudo journalctl -p err -b
Test every service:
sudo nginx -t
systemctl status nginx php*-fpm mariadb postgresql
curl -I https://example.com
Common follow-ups:
- PHP: the new default version means a new FPM socket path and new extension packages. Update
fastcgi_pass. See PHP-FPM tuning. - PostgreSQL: the new major version is installed alongside, and your data remains on the old cluster. Migrate with
pg_upgradecluster, then remove the old cluster. See upgrade PostgreSQL. - Python: virtualenvs need rebuilding against the new Python. See Python venv.
- Network interface names or config: usually unchanged on VPSes, but check
ip abefore relying on remote access after future reboots. - rsyslog: fresh Debian installs don’t include it. Upgraded systems keep it. See rsyslog.
5. Clean up
sudo apt autoremove --purge
sudo apt clean
find /etc -name '*.dpkg-dist' -o -name '*.dpkg-old' # review config diffs
apt list '?obsolete' 2>/dev/null # packages no longer in Debian
Purge obsolete packages after checking that you don’t need them.
Troubleshooting
Broken dependencies after a failed step:
sudo dpkg --configure -a
sudo apt -f install
sudo apt full-upgrade
Repository … changed its 'Suite' value — run sudo apt update --allow-releaseinfo-change.
Third-party repository errors (no trixie Release file) — disable that .list file until the vendor supports trixie. See apt update errors.
No boot after the upgrade — open the VNC console, choose the old kernel in GRUB’s advanced menu, and check /etc/fstab and network config. See Linux rescue mode.
Quick reference
| Step | Command |
|---|---|
| Version | cat /etc/debian_version |
| Prepare | apt update && apt full-upgrade && reboot |
| Switch sources | sed -i 's/bookworm/trixie/g' /etc/apt/sources.list |
| Minimal | apt upgrade --without-new-pkgs |
| Full | apt full-upgrade |
| Clean | apt autoremove --purge |
Related: upgrade Ubuntu and Ubuntu vs Debian for servers.