Howto Migration Debian 12 (Bookworm) vers Debian 13 (Trixie)

Release Notes : https://www.debian.org/releases/trixie/release-notes/

Debian Bookworm

Dans les changements notables de la distribution, on note :

  • Apache : 2.4.X → 2.4.Y (suivi des versions amont)
  • Serveur DNS BIND : 9.18 → 9.20
  • Cryptsetup : 2.6.1 → 2.7.5
  • Dovecot MTA : 2.3.19 → 2.4.1
  • GCC : 12.2 → 14.2
  • GnuPG : 2.2.40 → 2.4.7
  • Bibliothèque C GNU : 2.36 → 2.41
  • Image du noyau Linux : Série 6.1 → série 6.12
  • MariaDB : 10.11 → 11.8
  • Nginx : 1.22 → 1.26
  • OpenJDK : 17 → 21
  • OpenSSH : 9.2p1 → 10.0p1
  • Perl : 5.36 → 5.40
  • PHP : 8.2 → 8.4
  • Postfix MTA : 3.7 → 3.10
  • PostgreSQL : 15 → 17
  • Python 3 : 3.11.2 → 3.13.5
  • Samba : 4.17 → 4.22
  • Tomcat : 10.1.X → 10.1.Y et 11.0.Z (suivi des versions amont)
  • Vim : 9.0 → 9.1
  • LibreOffice : 7.4 → 25.2
  • Scribus : 1.5.8 → 1.6.3
  • NodeJS : au moins 20 (dépôt NodeSource)

Actions préalables

Nous conseillons quelques actions qui aideront en cas de problème.

Si le script Evolix dump-server-state est disponible, exécutez le avant la mise à jour :

# dump-server-state --verbose --force --dump-dir /home/backup/bookworm-$(date +%s) --all

Sinon, vous pouvez faire certaines opérations manuellement

Sauvegarder localement certaines ressources (dans /home/backup/bookworm par exemple)

# cat before-upgrade.sh

cd /etc
git add .
git commit -am "Commit balai avant upgrade en Trixie"
backup_dir="bookworm-$(date +%s)"
mkdir -p ${backup_dir}
cd ${backup_dir}
cp -r /etc ./
mkdir -p var/lib/apt
cp -r /var/lib/dpkg ./var/lib/
cp -r /var/lib/apt/extended_states ./var/lib/apt/
dpkg --get-selections "*" > ./current_packages.txt
uptime > uptime.txt
ps auwx > ps.out
pstree -pan > pstree.out
ss -tanpul > listen.out
if [ -f /root/.mysql_history ]; then cp -a /root/.mysql_history /root/.mysql_history.bak; fi

Mise à jour du système

Éditer les dépôts dans /etc/apt/sources.list et /etc/apt/sources.list.d/*.list pour remplacer bookworm par trixie.

# find /etc/apt/sources.list /etc/apt/sources.list.d/*.list /etc/apt/sources.list.d/*.sources -type f -exec sed --follow-symlinks --in-place 's/bookworm/trixie/g' {} +

Résultat dans les fichiers sources.list conseillés.

S’il y a des backports… les désactiver car en général ils ne sont plus nécessaires !

Puis mettre à jour le cache APT avec la commande :

# apt update

Commencer par télécharger l’ensemble des paquets qui devront être installés (afin de limiter le temps effectif d’installation).

# apt full-upgrade --download-only

Attention, si il y a des instances LXC, il faut les stopper avant la mise à niveau !

Faire ensuite une mise à niveau sans nouveaux paquets, pour appliquer les mises à jour triviales :

# apt upgrade --without-new-pkgs

Faire ensuite une mise à niveau avec nouveaux paquets mais sans désinstallations :

# apt upgrade --with-new-pkgs

TODO: à vérifier

Attention, si MySQL/MariaDB est installé, il faut stopper les instances supplémentaires car non gérées lors de la mise à jour (et cela va casser avec There is a MySQL server running, but we failed in our attempts to stop it) :

# mysqld_multi stop

Ensuite, appliquer les mises à jour non triviales (nécessitant des changements de paquets dépendants, des suppressions…) afin d’avoir un œil plus précis sur ce qui sera fait, avant de valider :

# apt full-upgrade

Puis lancer le nettoyage des vieux paquets en lisant attentivement la liste… en cas de doute, réinstaller le paquet !

# apt autoremove

Nettoyage supplémentaire (et facultatif)

Certains paquets ne sont pas supprimés par apt autoremove alors qu’ils ne sont plus dans les dépôts Debian. Lister et supprimer ces paquets avec les commandes suivantes, attention aux dépendances :

apt list '~o'
apt remove '~o'

Note : c’est le cas avec les paquets php8.2-* mais attention il faut d’abord migrer la configuration, cf note plus bas

Enfin, il faut redémarrer sur le nouveau noyau Linux installé :

# reboot

PHP

U12-13.U001 : Migrer configurations et paquets vers PHP 8.4

Il faut forcer le passage à PHP 8.4 :

# apt remove libapache2-mod-php8.2 && a2enmod php8.4 && /etc/init.d/apache2 restart

Puis nettoyer les anciens paquets php8.2-* et réinstaller les paquets PHP 8.4 correspondants.

Il faut également reprendre les directives de configuration de PHP 8.2 et les reporter en PHP 8.4 : memory_limit, max_*, etc.

ImageMagick + SVG

Si vous avez besoin de la partie SVG dans ImageMagick (pour Nextcloud, par exemple), il faut installer des paquets supplémentaires :

# apt install php-imagick imagemagick libmagickcore-7.q16-10-extra

PostgreSQL

U12-13.U002 : Forcer le changement de version de PostgreSQL

WIP : à vérifier que cela s’applique dans le cas d’utilisation de la version des dépôts Debian et PGDG

La version détaillée de cette procédure est disponible sur Howto PostgreSQL section mise à jour en adaptant les versions.

S’assurer que la bonne version de PostgreSQL est installée :

# dpkg -l | grep postgresql

Lister les clusters existants :

# pg_lsclusters
Ver Cluster Port Status Owner    Data directory               Log file
15  main    5432 online postgres /var/lib/postgresql/15/main  /var/log/postgresql/postgresql-15-main.log
17  main    5433 online postgres /var/lib/postgresql/17/main  /var/log/postgresql/postgresql-17-main.log

Ici on a main/15 en production et qui écoute sur le port 5432, et la nouvelle instance main/17 sur le port 5433 est vide.

Faites une sauvegarde complète de l’instance de production main/15.

Vérifier que le cluster main/17 contient seulement les bases de données par défaut et n’est pas en production :

# sudo -u postgres -- psql -l -p 5433  # bien utiliser le port du cluster main/17

                                  Liste des bases de données
    Nom    | Propriétaire | Encodage | Collationnement | Type caract. |    Droits d'accès
-----------+--------------+----------+-----------------+--------------+-----------------------
 postgres  | postgres     | UTF8     | fr_FR.UTF-8     | fr_FR.UTF-8  |
 template0 | postgres     | UTF8     | fr_FR.UTF-8     | fr_FR.UTF-8  | =c/postgres          +
           |              |          |                 |              | postgres=CTc/postgres
 template1 | postgres     | UTF8     | fr_FR.UTF-8     | fr_FR.UTF-8  | =c/postgres          +
           |              |          |                 |              | postgres=CTc/postgres

On peut aussi comparer les tailles de /var/lib/postgresql/15 et /var/lib/postgresql/17.

ATTENTION de ne pas détruire le cluster qui a les données de production !

Si l’instance main/17 est bien vide on peut la supprimer ainsi :

# pg_dropcluster 17 main

Pour la suite, il est conseillé de suivre Howto PostgreSQL section mise à jour en adaptant les versions.

Voici un résumé des commandes dans notre exemple d’une migration de PostgreSQL 15 vers 17 :

# pg_upgradecluster -v 17 15 main -m link --no-start
# du -sch /var/lib/postgresql/17/main
# df -h /var/lib/postgresql
# pg_dropcluster 15 main
# cp -a /etc/postgresql/15/main/conf.d/zz-evolinux.conf /etc/postgresql/17/main/conf.d/zz-evolinux.conf
# systemctl start postgresql@17-main
# pg_lsclusters
Ver Cluster Port Status Owner    Data directory               Log file
15  main    5433 down   postgres /var/lib/postgresql/15/main  /var/log/postgresql/postgresql-15-main.log
17  main    5432 online postgres /var/lib/postgresql/17/main  /var/log/postgresql/postgresql-17-main.log

MariaDB / MySQL

mysql_upgrade

Normalement, le script postupgrade du paquet joue le script mysql_upgrade pour mettre a jour les tables, vues… suite à un upgrade majeur. Cependant, si le datadir est volumineux, il le saute (c’est visible dans les logs MySQL) et il faut le faire à la main :

# mysql_upgrade

S’il y a plusieurs instances, il faut l’exécuter pour chacune avec le port en argument : mysql_upgrade -p $port

Postfix

Lire https://www.postfix.org/COMPATIBILITY_README.html et en fonction des options utilisées dans /etc/postfix/main.cf il faut envisager d’ajouter ou mettre à jour l’option suivante das /etc/postfix/main.cf :

compatibility_level=3.10

Bind

Si Bind est chrooté, il faut mettre à jour son chroot : https://wiki.evolix.org/HowtoBind#chroot

NodeJS

Pour rappel, nous utilisons les packages NodeSource, donc il est important de bien configurer la source NodeSource avec une version au minimum 20 et s’assurer d’avoir un package NodeSource et non debian.org :

# dpkg -l nodejs
ii  nodejs         20.xx.xx-1nodesource1 amd64        Node.js event-based server-side javascript engine

Apache

TLS 1.0 et TLS 1.1 désactivés par défaut

En Debian 13, Apache n’a plus TLS 1.0 et TLS 1.1 actifs par defaut, cf #943415

Nginx

http2 ne s’active plus dans le listen mais avec http2 on; :

[warn] 2947091#2947091: the "listen ... http2" directive is deprecated, use the "http2" directive instead in /etc/nginx/...