Debian 12 Bookworm Upgrade Report
I’ve updated the Reiterate server to the latest Debian release (bookworm). Here’s a report of everything I had to do.
Overall, Debian 12 is a fantastic release, the latest in a string of excellent updates. I’ve been running this server on Debian since Day One, and I’ve never regretted it.
As I’ve written before, I’m now using Ansible to configure
and document my server setup. One of the reasons for that was so that I could upgrade my server cleanly. Typically,
if you have a desktop running Debian, you’ll upgrade it using
apt-get dist-upgrade which does the upgrade “in place,”
that is, you keep everything else in your system that isn’t part of the OS. That’s convenient and it’s the option most
people choose, but I like starting from scratch, for three reasons.
It avoids the accumulation of cruft. When you keep upgrading in place over and over, it’s like painting your house a different color every year, just slapping a new coat on top. It works for a while but eventually you need to strip everything down to the bare wood and start fresh.
It keeps me in touch with every part of my server. If I simply upgraded in place every could years, I’d forget some of the details and wind up in a situation where I had certain files in the system and I didn’t know why. By rebuilding from scratch I force myself to examine each and every part of the system.
It documents my system setup. My Ansible playbook serves as a document of everything my system needs to run. I know it is a complete and sufficient recipe because I can use it to rebuild the server from scratch.
However, upgrading is not as simple as replacing “debian11” with “debian12” in my playbook. There’s always a few details that need to be fixed up, some things that don’t quite work the same way and need to be adjusted. Here’s a report of everything I needed to clean up after my Debian 12 upgrade.
Python interpreters are now externally-managed
In Debian 12, you can no longer use pip to install packages system-wide. You have to create a virtual environment, and install the packages there. This makes sense from a system management viewpoint, since you can easily break your system by installing packages into the global library space.
I was using pip to install isso, which manages my blog comments. I already had an isso user account, which I was using to keep things nice and neat, putting the comments database and config files in that user directory. I didn’t really need to do that but I felt it was “best practice.” Now that I needed to install the python modules outside of the system directories, having the account already set up seemed perspicacious.
First, I needed to get the proper packages installed to do the virtual environment installed. On the old Debian 11
install I was using
python-dev but that failed with:
Package python-dev is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
That’s a very odd name for a package. I guess starting with Debian 12, python2 is officially deprecated and everything
is forced to be python3. This package just makes a link so that any script referring to
The next error was
The virtual environment was not created successfully because ensurepip is not
available. On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.
apt install python3.11-venv
Which is the new package I needed to actually do the virtual environment install.
Next, I had issues with Ansible. Ansible is finicky about privilege escalation. I wanted to install this in my isso
directory as the isso user, but Ansible doesn’t like becoming users other than root. I tried every combination of
ansible_become_user, but I was unable to get Ansible to do this directly. I ended up
doing the venv install as root, and then
chown-ing everything over to isso. It’s kind of hacky but it works
and I was too frustrated to try and find a cleaner solution.
The main website is Rails-based, which requires Ruby of course. I happened to be on ruby version 3.1.3, which is
no longer supported anywhere, so I decided to upgrade to the current stable version 3.2.2. I use
rvm to manage my
ruby installs, which… it works, but it seems like there hasn’t been a lot of development work on it lately? I checked
around and it doesn’t seem like there’s any good, well-supported ruby version managers out there right now.
Rvm doesn’t have any binaries pre-compiled (they’re behind on this, there’s some support for Debian 11. I offered to
help compile some binaries but never got a response back). I had to compile ruby from source, and that meant I had
to install some additional packages:
libffi. After all that, I successfully got the latest
Puma is the application server that sits between nginx and my Rails app. Trying to start up puma gave me an error:
libssl.so.1.1: cannot open shared object file: No such file or directory - /home/deploy/production/vendor/bundle/ruby/3.2.0/gems/puma-6.0.2/lib/puma/puma_http11.so
It took me a while to figure out, puma-6.0 has a dependency on libssl-1.1, which is no longer in Debian 12. The current libssl is 3.0, so I needed up upgrade to puma-6.3 which has the proper libssl dependency.
Goaccess is a small utility I use to parse my web logs and give me statistics. I was calling it with an
ignore-referer flag, but the version of goaccess in bookworm changed that to
ignore-referrer. I had to
update my wrapper script which was erroring becuase of that.
That original misspelling should be a warning to every standard developer that details matter.
I use [fail2ban] to block script kiddies. The new version in Debian 12 was now logging warnings:
WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
I fixed that by adding a section in
allowipv6 = auto
PAM sshd user_readenv
There’s a bug in the sshd PAM config that was spamming warnings in my log files that look like:
pam_env(sshd:session): deprecated reading of user environment enabled
Reading through the bug report, it seems harmless to fix it by removing the
user_readenv flag in
so I did that.
sudo flag file
Sudo is now adding a file
.sudo_as_admin_successful in my home dir. Dotfile litter is one of my pet peeves, so I
disabled this by adding a block into my sudoers.d config file:
# Disable ~/.sudo_as_admin_successful file
And that was everything! Well, everything Debian-related. The server has been up and running on Debian 12 for several days now and I’m not seeing any new errors or warnings. Thanks again to everyone on the Debian team for putting out quality releases!