Skip to content

Upgrading Debian 11 to Debian 12 (bookworm)

Christophe TREMBLAY-GUILLOUX
Christophe TREMBLAY-GUILLOUXLinux systems engineer

Upgrading Debian 11 to Debian 12 is usually not complicated if you already have a clean, fully mastered Debian 11 installation. In this note (which I use myself) we go through the main migration steps.

Every command is run as root, through the server's KVM console or over SSH. No pointless sudo, become root.

1. What's new in Debian 12 that matters for a VPS?

Section titled “1. What's new in Debian 12 that matters for a VPS?”

Here is the list of important packages for a VPS that will be upgraded if installed:

PackageDebian 11Debian 12
Apache2.4.542.4.57
Dovecot2.3.132.3.19
Exim4.944.96
GnuPG2.2.272.2.40
libc2.312.36
Linux5.106.1
MariaDB10.510.11
Nginx1.181.22
OpenLDAP2.4.572.5.13
OpenSSH8.4p19.2p1
Perl5.325.36
PHP7.48.2
Postfix3.53.7
PostgreSQL1315
Python 33.9.23.11.2
systemd247252

1.2/ Replacement of the NTP package with NTPsec

Section titled “1.2/ Replacement of the NTP package with NTPsec”

NTP is a protocol used to keep the server's clock in sync.

If you already have the ntp package, it will be replaced by ntpsec, a security-hardened derivative of the ntp package.

If you have no ntp daemon or equivalent, the systemd-timesyncd package will be installed.

1.3/ Replacement of Puppet 5 with Puppet 7

Section titled “1.3/ Replacement of Puppet 5 with Puppet 7”

Warning: do not upgrade servers running a Puppet agent older than version 7 before upgrading the server that hosts the puppetmaster.

Always upgrade the puppetmaster before all other servers.

1.4/ Replacement (not enforced) of rsyslog with systemd-journald

Section titled “1.4/ Replacement (not enforced) of rsyslog with systemd-journald”

This is the unpleasant part for old-timers.

It's a good time to consider dropping rsyslog in favour of systemd-journald and its binary journals, which many of the tools you probably use can't read.

After migrating to Debian 12, you can remove rsyslog with these commands:

bash
apt-mark auto rsyslog
apt autoremove

To read the binary journals, instead of using tail (a small tear in the eye), you'll need:

bash
journalctl -ef

If you keep rsyslog anyway (at least for a while), all logs will still be written by default to a single file, /var/log/syslog (the alternative files can be removed).

1.5/ Python3: change for installing external packages

Section titled “1.5/ Python3: change for installing external packages”

By default, it is no longer allowed to install Python packages that are not packaged by Debian.

It is possible to bypass this restriction, but it is not advised.

External packages must now be installed in isolated Python environments, using pipx or a virtual environment (python -m venv).

Before upgrading, your server must be backed up off site, in another datacenter. And I also advise keeping a copy with an independent host and a copy at home.

An upgrade can go wrong, destroy data, or leave the server unbootable: databases must be dumped to SQL before any file backup, and take a snapshot as well if it's a virtual machine. Set aside time to repair in case of trouble, and be able to reboot in rescue mode.

Your server is normally already up to date, since you are conscientious. If not, it absolutely has to be before you start:

bash
apt update
apt upgrade
reboot # if needed

A new repository section appears. On a server, in theory it won't be needed, but it's possible to include it: non-free-firmware.

In /etc/apt/sources.list or /etc/apt/sources.list.d/*, replace bullseye with bookworm:

deb http://deb.debian.org/debian bookworm main contrib non-free non-free-firmware
deb http://deb.debian.org/debian bookworm-updates main contrib non-free non-free-firmware
deb http://security.debian.org bookworm-security main contrib non-free non-free-firmware

IMPORTANT: the name to use is deb.debian.org, which automatically points to the nearest mirror.

Or move into the directory and replace bullseye with bookworm in a single command:

bash
sed -i 's/bullseye/bookworm/g' *.list

2.2/ Update the list of available packages

Section titled “2.2/ Update the list of available packages”
bash
apt update

This step upgrades the system packages that neither add new dependencies on new packages nor remove any:

bash
apt -o Apt::Get::Assume-Yes=true -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade --without-new-pkgs

2.4/ Check disk space before the full upgrade

Section titled “2.4/ Check disk space before the full upgrade”

I advise cleaning up disk space and checking available space before the full upgrade:

bash
apt clean
apt --purge autoremove
apt -o APT::Get::Trivial-Only=true full-upgrade
[ ... ]
XXX upgraded, XXX newly installed, XXX to remove and XXX not upgraded.
Need to get xx.xMB of archives.
After this operation, AAAMB of additional disk space will be used.

If there is not enough room, this message appears:

E: You don't have enough free space in /var/cache/apt/archives/.
bash
apt -o Apt::Get::Assume-Yes=true -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" full-upgrade
apt --purge autoremove

If all went well:

bash
reboot

If anything went wrong, analyse the situation before rebooting. If you'd rather not handle this yourself, ask for a quote.