Upgrading Debian 10 (Buster) to Debian 11 (Bullseye)
I am a big fan of Debian in the server environment, mainly due to its great record in stability, security and other important aspects like having a huge number of tutorials and guides available online. Since the release of Debian 11 (codenamed Bullseye), I've been thinking about upgrading to the latest version. I will start on one of my VPS servers to test how is everything working. There are number of tutorials online explaining the exact same thing. Feel free to follow which you find the best, this is mainly for my documentation.
Summary
- Backup your system – You never know what can go wrong, be prepared.
- Edit apt's sources.list – In order to fetch and intall packages meant for Debian 11, we need to change a some lines in the /etc/apt/sources.list file.
- Update software repos – Make apt aware of the changes you've made in sources.list and upgrade existing packages.
- Upgrade the system itself – After upgrading packages, you can upgrade the system as well.
Backup your system
Unless you actually have a testing environment, where loss of files won't cause even a minimal headache, please backup your data. In most cases, it is OK to at least backup all configuration files for any services running on the server. You can always rebuild the server using them in case something bad happens. Always have an presice upgrade plan when upgrading production servers, including plans B and C and D, depenging on the criticality of the service you are running. I am upgrading a server with two services only I use, so I can afford a very simple "backup" – cat all config files into terminal and copy them to notepad on my workstation, that's it. You can also setup something fancier like rsnapshot or restic.
Prepare for the changes
Check system version
There are numerous ways (from basic to most fancy) to check what version and distribution you are running, try running couple of these:
lsb_release -a
If you don't have that installed like me, try on of the other options. Simply cat /etc/debian_version or /etc/os-release. The latter will give you more detailed information.
$ cat /etc/debian_version
10.10
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
You should also probably know about the uname command, combined with the -a (--all) prints some system information.
$ uname -a
Linux hostname 5.4.0-74-generic #83~18.04.1-Ubuntu SMP Tue May 11 16:01:00 UTC 2021 x86_64 GNU/Linux
If you run this command on a vanilla Debian 10 distribution, you will most likely see kernel version 4.19, which is the version Debian 10 shipped with. For some reason, my VPS provider is using a newer kernel and somehow managed to throw Ubuntu into the mix, even though the system clearly runs on Debian, based on the multiple command outputs above.
Update and upgrade existing software
It is recommended before installing any new packages or performing a large update such as this one to update and upgrade the existing system.
First of all, update apt repositories. Unless you are using Nginx from their official repository instead from the Debian one, you won't see the lines containing nginx.
$ sudo apt update
Get:1 https://nginx.org/packages/mainline/debian buster InRelease [3,607 B]
Hit:2 http://deb.debian.org/debian buster InRelease
Hit:3 http://security.debian.org/debian-security buster/updates InRelease
Hit:4 http://deb.debian.org/debian buster-backports InRelease
Get:5 https://nginx.org/packages/mainline/debian buster/nginx amd64 Packages [49.9 kB]
Fetched 53.5 kB in 1s (47.0 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
Upgrade existing packages with apt upgrade.
$ sudo apt upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
nginx
1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 880 kB of archives.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 https://nginx.org/packages/mainline/debian buster/nginx amd64 nginx amd64 1.21.3-1~buster [880 kB]
Fetched 880 kB in 11s (83.5 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
(Reading database ... 42829 files and directories currently installed.)
Preparing to unpack .../nginx_1.21.3-1~buster_amd64.deb ...
Unpacking nginx (1.21.3-1~buster) over (1.21.2-1~buster) ...
Setting up nginx (1.21.3-1~buster) ...
Processing triggers for systemd (241-7~deb10u8) ...
As you can see I had a pending upgrade of Nginx from 1.21.2 to 1.21.3. In production, always check before upgrading individual packages in case there is a major change that might break your system.
$ sudo apt dist-upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
If you want to know the difference between apt upgrade and apt dist-upgrade, read this paragraph from apt's man page:
"dist-upgrade in addition to performing the function of upgrade, also intelligently handles changing dependencies with new versions of packages; apt-get has a "smart" conflict resolution system, and it will attempt to upgrade the most important packages at the expense of less important ones if necessary. So, dist-upgrade command may remove some packages. The /etc/apt/sources.list file contains a list of locations from which to retrieve desired package files. See also apt_preferences(5) for a mechanism for overriding the general settings for individual packages."
Clean any leftovers using the following commands:
$ sudo apt autoremove
Reading package lists... Done
Building dependency tree
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
$ sudo apt autoclean
Reading package lists... Done
Building dependency tree
Reading state information... Done
Again, to learn why we are running these commands, read this from the man page:
- clean: clean clears out the local repository of retrieved package files. It removes everything but the lock file from /var/cache/apt/archives/ and /var/cache/apt/archives/partial/. When APT is used as a dselect(1) method, clean is run automatically. Those who do not use dselect will likely want to run apt-get clean from time to time to free up disk space.
- autoclean: Like clean, autoclean clears out the local repository of retrieved package files. The difference is that it only removes package files that can no longer be downloaded, and are largely useless. This allows a cache to be maintained over a long period without it growing out of control. The configuration option APT::Clean-Installed will prevent installed packages from being erased if it is set to off.
- autoremove: is used to remove packages that were automatically installed to satisfy dependencies for some package and that are no longer needed.
Update software repos
Before making any changes to the /etc/apt/sources.list file, back it up in a different directory. Do the same for anything in the /etc/apt/sources.list.d folder. This will copy the file to your home directory under the name sources.list.bak
$ cp /etc/apt/sources.list ~/sources.list.bak
Use your favorite editor or sed to replace all "buster" references with "bullseye", without quotes of course.