Hier soir, j’ai mis à jour le serveur : nous sommes passés de Debian 7.8 Wheezy à Debian 8.0 Jessie.
Globalement, la migration s’est plutôt bien passée. Le serveur a connu environ dix minutes d’interruption, principalement le temps de comprendre les changements introduits par Apache 2.4 et de corriger quelques détails dans la configuration de Postfix.
Voici donc un retour d’expérience sur cette mise à jour, avec les commandes utilisées, les points de vigilance, les erreurs rencontrées et les corrections appliquées.
Petite précision utile : Debian 8 Jessie est aujourd’hui une ancienne version. Cet article garde donc surtout une valeur d’archive technique. Pour un serveur actuel, il faut évidemment viser une version Debian maintenue, avec des dépôts de sécurité actifs. Debian indique que la version stable actuelle est Debian 13 Trixie. Versions Debian
Avant de commencer : sauvegardes et plan de retour
Avant une mise à jour majeure de Debian, la première étape ne consiste pas à modifier sources.list. La première étape consiste à vérifier que les sauvegardes sont exploitables.
Dans l’idéal, il faut disposer de :
- une sauvegarde complète des fichiers web ;
- un dump récent des bases de données ;
- une copie de
/etc; - une copie des configurations Apache, PHP, Postfix et cron ;
- un accès console hors SSH, par exemple via l’interface de l’hébergeur ;
- un plan de retour en arrière si le serveur ne redémarre pas correctement.
Une mise à jour majeure peut modifier le noyau, les services, les fichiers de configuration, les versions de PHP, les modules Apache ou les paquets système. Autant éviter de découvrir au milieu de la nuit que “sauvegarde” voulait dire “un vieux zip quelque part”.
Sur un serveur web, je conseille aussi de noter l’état des services avant l’opération :
service apache2 status
service mysql status
service postfix status
apache2 -v
php -v
mysql --version
postconf -n
Cela permet de comparer plus facilement l’avant et l’après.
Vérifier l’état du système avant la migration
Avant de changer de version Debian, j’ai commencé par vérifier qu’aucun paquet n’était cassé ou à moitié installé :
dpkg --audit
On vérifie aussi les paquets placés en attente :
dpkg --get-selections | grep 'hold'Code language: JavaScript (javascript)
Si des paquets sont retenus, il vaut mieux comprendre pourquoi avant de lancer une mise à niveau complète. Un paquet bloqué peut empêcher une dépendance importante de se mettre à jour.
On peut aussi vérifier les paquets installés depuis des dépôts tiers :
apt-cache policy
grep -R "^[^#]" /etc/apt/sources.list /etc/apt/sources.list.d/Code language: PHP (php)
Les notes de publication Debian recommandent de retirer ou désactiver les paquets tiers lorsque cela améliore la fiabilité de la mise à niveau. C’est particulièrement pertinent si le serveur utilise des dépôts externes pour PHP, Apache, MariaDB, Nginx, Node.js ou des outils de sécurité. Notes de publication Debian Jessie
Mettre à jour les dépôts APT
On édite ensuite le fichier des sources APT :
nano /etc/apt/sources.listCode language: PHP (php)
L’idée est de remplacer les occurrences de wheezy par jessie. À l’époque, ma configuration ressemblait à ceci :
# Debian Jessie.
deb http://mirror.ovh.net/debian/ jessie main contrib non-free
deb-src http://mirror.ovh.net/debian/ jessie main contrib non-free
# Sécurité.
deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free
# Backports.
deb http://ftp.debian.org/debian/ jessie-backports mainCode language: PHP (php)
J’éviterais d’utiliser stable dans sources.list sur un serveur. C’est pratique en apparence, mais dangereux : le jour où Debian change de stable, votre serveur peut se retrouver orienté vers une nouvelle version majeure sans que ce soit explicite. Un nom de code comme jessie, stretch, bookworm ou trixie rend l’intention beaucoup plus claire.
Dans le cas précis de Jessie, Debian précisait que les mises à niveau directes depuis des versions antérieures à Debian 7 Wheezy n’étaient pas prises en charge. Il fallait donc partir d’un système Wheezy à jour avant de migrer vers Jessie. Notes de publication Debian Jessie
Simuler la mise à niveau
Avant de lancer la vraie mise à jour, on peut simuler l’opération pour voir l’ampleur des changements :
apt-get update
apt-get -o APT::Get::Trivial-Only=true dist-upgradeCode language: PHP (php)
Dans mon cas, le résultat indiquait :
439 upgraded, 192 newly installed, 5 to remove and 1 not upgraded.
Need to get 275 MB of archives.
After this operation, 259 MB of additional disk space will be used.
E: Trivial Only specified but this is not a trivial operation.Code language: JavaScript (javascript)
Ce message n’est pas une erreur inquiétante. Il indique simplement que l’opération n’est pas “triviale”, donc qu’APT refuse de l’exécuter avec cette option de simulation restrictive.
Avant de continuer, on vérifie aussi l’espace disque :
df -h
du -sh /var/cache/apt/archives 2>/dev/nullCode language: JavaScript (javascript)
Une mise à niveau majeure télécharge beaucoup de paquets et peut nécessiter de l’espace supplémentaire. Ce n’est pas le moment de découvrir que /var est plein à 99 %.
Lancer la mise à niveau vers Debian Jessie
Une fois les sauvegardes faites et les dépôts mis à jour, on lance la première phase :
apt-get update
apt-get upgradeCode language: JavaScript (javascript)
APT affiche alors les paquets qui seront mis à jour, installés ou supprimés. Pendant l’opération, il peut poser des questions sur les fichiers de configuration modifiés localement.
Sur un serveur personnalisé, je fais très attention à ces questions. Garder automatiquement l’ancien fichier peut empêcher un service de profiter d’une nouvelle configuration attendue. Remplacer automatiquement le fichier peut écraser une configuration critique. Bref : lire, comparer, décider. Oui, c’est le moment sérieux.
Ensuite, on lance la mise à niveau complète :
apt-get dist-upgradeCode language: JavaScript (javascript)
dist-upgrade autorise APT à installer de nouveaux paquets et à en supprimer si nécessaire pour résoudre les dépendances. C’est indispensable lors d’un changement de version Debian.
Après la mise à niveau, un redémarrage est souvent nécessaire, notamment si le noyau a été mis à jour :
reboot
Vérifier la version après redémarrage
Après redémarrage, on vérifie que le serveur tourne bien sous Jessie :
cat /etc/debian_version
lsb_release -a 2>/dev/null || cat /etc/os-release
uname -aCode language: JavaScript (javascript)
Puis on contrôle les services essentiels :
service apache2 status
service mysql status
service postfix status
tail -n 100 /var/log/syslog
tail -n 100 /var/log/apache2/error.log
tail -n 100 /var/log/mail.logCode language: JavaScript (javascript)
Dans mon cas, le site web répondait avec une erreur 403. Direction Apache.
Apache 2.4 : les changements qui cassent tout joliment
Avec Debian Jessie, Apache passe en version 2.4. Ce changement introduit plusieurs modifications importantes, notamment dans les fichiers de configuration et les directives de contrôle d’accès.
C’est le principal point qui m’a causé une interruption de service.
Les fichiers de sites doivent porter l’extension .conf
Sous Apache 2.4 avec Debian, les fichiers de configuration des virtual hosts dans /etc/apache2/sites-available sont généralement attendus avec l’extension .conf.
On peut vérifier les sites disponibles :
ls -l /etc/apache2/sites-available/
ls -l /etc/apache2/sites-enabled/
Si un fichier s’appelle par exemple example.com, on peut le renommer :
mv /etc/apache2/sites-available/example.com /etc/apache2/sites-available/example.com.conf
Puis l’activer :
a2ensite example.com.confCode language: CSS (css)
La commande a2ensite active un site en créant un lien symbolique dans /etc/apache2/sites-enabled. Manpage Debian : a2ensite
On teste ensuite la configuration Apache :
apache2ctl configtest
Ou :
apache2ctl -t
Si le test retourne Syntax OK, on peut recharger Apache :
service apache2 reload
Changer les directives de contrôle d’accès
Apache 2.4 remplace les anciennes directives Order, Allow et Deny par la logique Require.
Pour tout bloquer, on utilisait auparavant :
# Apache 2.2.
Order deny,allow
Deny from allCode language: CSS (css)
Avec Apache 2.4, on écrit :
# Apache 2.4.
Require all deniedCode language: PHP (php)
Pour tout autoriser, on utilisait auparavant :
# Apache 2.2.
Order allow,deny
Allow from allCode language: CSS (css)
Avec Apache 2.4, on écrit :
# Apache 2.4.
Require all grantedCode language: PHP (php)
La documentation officielle Apache indique que le contrôle d’accès par hôte, IP ou variable utilise désormais les directives Require, par exemple Require all granted ou Require all denied. Documentation Apache 2.4 : contrôle d’accès
Dans un virtual host classique, on peut donc avoir :
<Directory /home/www/example.com/public_html>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>Code language: HTML, XML (xml)
Sans cette directive, Apache peut refuser l’accès au répertoire et renvoyer une erreur 403. Ce fut précisément mon cas. Délicieux petit accueil après migration.
Désactiver mod_spdy
Autre problème rencontré : mod_spdy était incompatible avec ma nouvelle version d’Apache.
Apache refusait de démarrer avec une erreur de ce type :
apache2: Syntax error on line 140 of /etc/apache2/apache2.conf:
Syntax error on line 1 of /etc/apache2/mods-enabled/spdy.load:
Cannot load /usr/lib/apache2/modules/mod_spdy.so into server:
/usr/lib/apache2/modules/mod_spdy.so: undefined symbol: ap_log_cerrorCode language: JavaScript (javascript)
La solution immédiate consiste à désactiver le module :
a2dismod spdy
Puis à tester la configuration :
apache2ctl configtest
Et à redémarrer Apache :
service apache2 restart
À l’époque, SPDY était encore utilisé pour améliorer les performances HTTP. Aujourd’hui, il a été remplacé dans les usages modernes par HTTP/2 et HTTP/3. Pour un serveur actuel, on ne chercherait évidemment pas à conserver mod_spdy.
Corriger mod_security2
Au redémarrage d’Apache, mod_security2 a également posé problème :
apache2: Syntax error on line 141 of /etc/apache2/apache2.conf:
Syntax error on line 9 of /etc/apache2/mods-enabled/security2.conf:
No matches for the wildcard '*.conf' in '/etc/modsecurity',
failing (use IncludeOptional if required)Code language: PHP (php)
Dans mon cas, il suffisait de renommer le fichier recommandé en fichier actif :
mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
Ou avec l’expansion Bash :
mv /etc/modsecurity/modsecurity.conf{-recommended,}
Puis on active le module :
a2enmod security2
Et on redémarre Apache après vérification :
apache2ctl configtest
service apache2 restart
Sur une configuration plus moderne, on privilégierait souvent IncludeOptional lorsque des fichiers peuvent être absents. Mais dans ce cas précis, créer le fichier attendu suffisait.
Erreur 403 sur le sous-domaine statique
Après la migration, mon sous-domaine dédié aux images et ressources statiques renvoyait une erreur 403.
Le problème venait d’une directive Directory mal placée dans la configuration Apache. Je l’avais définie à l’intérieur du bloc VirtualHost. En la déplaçant en dehors, Apache a de nouveau appliqué correctement les règles d’accès au répertoire concerné.
Exemple de structure plus claire :
<VirtualHost *:80>
ServerName static.example.com
DocumentRoot /home/www/static.example.com/public_html
ErrorLog ${APACHE_LOG_DIR}/static-error.log
CustomLog ${APACHE_LOG_DIR}/static-access.log combined
</VirtualHost>
<Directory /home/www/static.example.com/public_html>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>Code language: PHP (php)
Après modification :
apache2ctl configtest
service apache2 reload
Pour diagnostiquer une 403 Apache, les commandes les plus utiles restent :
tail -f /var/log/apache2/error.log
namei -l /home/www/static.example.com/public_html
apache2ctl -SCode language: JavaScript (javascript)
namei -l est particulièrement pratique pour vérifier les permissions de chaque répertoire du chemin. Une permission manquante sur un dossier parent suffit à produire une erreur 403.
Postfix : mails bloqués après la migration
Après Apache, j’ai remarqué que les mails n’arrivaient plus correctement avec Postfix.
Un tour dans les logs a montré des directives en double dans /etc/postfix/main.cf :
send-mail: warning: /etc/postfix/main.cf, line 150:
overriding earlier entry: smtpd_tls_key_file=$smtpd_tls_cert_file
send-mail: warning: /etc/postfix/main.cf, line 151:
overriding earlier entry: smtpd_tls_cert_file=/etc/ssl/postfix.pemCode language: JavaScript (javascript)
Ce type d’avertissement signifie qu’un paramètre est défini plusieurs fois. Postfix lit le fichier et la dernière valeur remplace la précédente. Ce n’est pas toujours fatal, mais cela rend la configuration ambiguë et peut provoquer un comportement inattendu.
Pour inspecter la configuration active, on utilise :
postconf -n
Pour tester la configuration :
postfix check
Ensuite, il suffit de supprimer les doublons dans :
nano /etc/postfix/main.cf
Puis de redémarrer Postfix :
service postfix restart
Enfin, on surveille les logs :
tail -f /var/log/mail.logCode language: JavaScript (javascript)
Après une migration système, je vérifie toujours l’envoi et la réception avec un vrai message de test. Un service peut être “running” et pourtant mal délivrer les mails. Postfix a le chic pour rester poli pendant qu’il boude.
Nettoyer les anciens paquets
Une fois le serveur stable, on peut nettoyer les paquets devenus inutiles :
apt-get autoremove
apt-get autocleanCode language: JavaScript (javascript)
Je préfère ne pas lancer ces commandes trop tôt. D’abord, on vérifie que le serveur web, les bases de données, les mails, les tâches cron et les sauvegardes fonctionnent. Ensuite seulement, on nettoie.
Checklist après migration
Après une mise à niveau Debian, je vérifie généralement les points suivants :
- le serveur redémarre correctement ;
- SSH fonctionne encore ;
- Apache démarre sans erreur ;
- les virtual hosts répondent correctement ;
- les certificats SSL sont toujours valides ;
- PHP exécute bien les sites ;
- MySQL ou MariaDB démarre correctement ;
- Postfix envoie et reçoit les mails ;
- les tâches cron s’exécutent ;
- les sauvegardes tournent encore ;
- les logs ne montrent pas d’erreur bloquante ;
- les permissions des répertoires web sont intactes.
Quelques commandes utiles :
apache2ctl -t
apache2ctl -S
service apache2 status
service mysql status
service postfix status
tail -n 100 /var/log/apache2/error.log
tail -n 100 /var/log/mail.log
tail -n 100 /var/log/syslog
df -h
free -mCode language: JavaScript (javascript)
Ce que je ferais différemment aujourd’hui
Avec le recul, cette migration s’est bien passée, mais je procéderais aujourd’hui avec une méthode un peu plus stricte.
Je commencerais par cloner le serveur ou créer un snapshot, puis je testerais la mise à niveau sur une instance temporaire. Ensuite, je noterais les modifications de configuration nécessaires, notamment pour Apache 2.4, PHP et Postfix. Enfin, je planifierais la migration réelle avec une fenêtre de maintenance claire.
Pour un serveur web en production, le luxe n’est pas d’aller vite. Le luxe, c’est de savoir exactement quoi faire quand quelque chose casse.
Mémo rapide
# Vérifier l’état des paquets.
dpkg --audit
dpkg --get-selections | grep 'hold'
# Modifier les dépôts.
nano /etc/apt/sources.list
# Mettre à jour les dépôts.
apt-get update
# Simuler une mise à niveau non triviale.
apt-get -o APT::Get::Trivial-Only=true dist-upgrade
# Lancer la mise à niveau.
apt-get upgrade
apt-get dist-upgrade
# Redémarrer si nécessaire.
reboot
# Vérifier Debian.
cat /etc/debian_version
# Tester Apache.
apache2ctl configtest
apache2ctl -S
# Corriger les modules.
a2dismod spdy
a2enmod security2
# Redémarrer Apache.
service apache2 restart
# Vérifier Postfix.
postconf -n
postfix check
service postfix restart
# Logs utiles.
tail -f /var/log/apache2/error.log
tail -f /var/log/mail.log
tail -f /var/log/syslogCode language: PHP (php)
Conclusion
La mise à jour de Debian 7 Wheezy vers Debian 8 Jessie s’est globalement bien passée, avec une courte interruption de service.
Les principaux problèmes venaient d’Apache 2.4 : extension .conf attendue pour les sites, nouvelles directives Require, module SPDY incompatible, configuration ModSecurity incomplète et erreur 403 sur un sous-domaine statique.
Postfix a également demandé un petit nettoyage à cause de directives dupliquées dans main.cf.
Au final, rien d’insurmontable, mais cette migration rappelle une règle simple : une mise à niveau de distribution ne se limite jamais à “changer les dépôts et appuyer sur Entrée”. Les paquets changent, les services changent, les fichiers de configuration changent, et le serveur vous le rappelle avec un sens de l’humour très personnel.
Besoin d’un partenaire fiable pour votre projet WordPress/WooCommerce ? Je mets mon expertise à votre service pour des résultats concrets.
