Update Debian 11 to Debian 12 (bookworm)

In June 2023 Debian 12 was released. We have tested the new distribution and already in productive use. Here is a short description of how the update from version 11 to 12 works.

Attention: It is absolutely necessary to make a complete backup of the server before the update. During a distro update, errors can occur for a variety of reasons, leaving the system in a state that is no longer usable. We do not take any responsibility for this.

1. check the current version:

$ lsb_release -a

# returns
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye

2. update all installed packages

To be on the safe side, all non-default packages should be uninstalled. After the update they can be reinstalled if they are supported by Debian 12. The result of this check could look like the following:

$ sudo apt list '?narrow(?installed, ?not(?origin(Debian)))'
containerd.io/bullseye,now 1.6.21-1 amd64 [installed]
docker-ce-cli/bullseye,now 5:24.0.2-1~debian.11~bullseye amd64 [installed]
docker-ce/bullseye,now 5:24.0.2-1~debian.11~bullseye amd64 [installed]
hc-utils/now 0.0.4-1 all [installed,local]
rsnapshot/now 1.4.4-1 all [installed,local]

Also, packages in "hold" status can cause problems during the update. These can be listed as follows:

# show packages in hold status
$ sudo apt-mark showhold | more

# uninstall packages in hold status
$ sudo apt-mark unhold package_name

More information can be found e.g. here

Now the system has to be updated to the latest version:

$ sudo apt update
$ sudo apt upgrade
$ sudo apt full-upgrade
$ sudo apt --purge autoremove

# reboot
$ sudo systemctl reboot

3. update the Debian sources

To start the update process, the sources-list files have to be modified. These can be found in /etc/apt/sources.list and /etc/apt/sources.list.d/*.list.

In all these files "bullseye" must be replaced with "bookworm". Example

# Before
deb http://deb.debian.org/debian bullseye main
deb http://deb.debian.org/debian bullseye-updates main
deb http://deb.debian.org/debian-security/ bullseye-security main

# After
deb http://deb.debian.org/debian bookworm main
deb http://deb.debian.org/debian bookworm-updates main
deb http://deb.debian.org/debian-security/ bookworm-security main 

Now the package-lists can be updated:

$ sudo apt update

4. system upgrade

$ sudo apt upgrade --without-new-pkgs

When running this upgrade, various (configuration) files will ask if the locally modified variant should be replaced by a new one. This has to be checked on a case-by-case basis. For example, we have modified the sshd configuration on all systems and it asks here if the local /etc/ssh/sshd_config file should be replaced by a new one (with default settings).

5. upgrade Debian 11 to Debian 12

Now the final upgrade process can be started. Again you will be asked if you want to use the local or the new version.

$ sudo apt full-upgrade

# before rebooting, then check if the sshd config is valid
$ sudo sshd -t

# now reboot into Debian 12
$ sudo systemctl reboot

6. check the new system version

$ lsb_release -a

No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 12 (bookworm)
Release: 12
Codename: bookworm

7. troubleshooting

If 'apt-get update' is called after installation, the following message may appear:

N: Repository 'Debian bookworm' changed its 'non-free component' value from 'non-free' to 'non-free non-free-firmware'.
N: More information about this can be found online in the Release notes at: https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.html#non-free-split

The message can be disabled as follows:

$ su -c 'echo "APT::Get::Update::SourceListWarnings::NonFreeFirmware \"false\";" > /etc/apt/apt.conf.d/no-bookworm-firmware.conf'

8. miscellaneous

Docker

Depending on how Docker was previously installed, it may make sense to reinstall Docker for Debian 12. This is done as follows (see also https://docs.docker.com/engine/install/debian/):

# Run the following command to uninstall all conflicting packages
$ for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

# Update the apt package index and install packages to allow apt to use a repository over HTTPS:
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg

# Add Docker's official GPG key:
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Use the following command to set up the repository
$ echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Update the apt package index
$ sudo apt-get update

# Install Docker Engine, containerd, and Docker Compose (latest versions).
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Verify that the Docker Engine installation is successful by running the hello-world image
$ sudo docker run hello-world
prev Security: Fix Weak Key Exchange Algorithm in SSH
next Update Debian 11 to Debian 12 (bookworm)