Migrer un site vers un nouveau serveur sans coupure
La plupart des tutoriels basculent le DNS puis demandent le certificat. C'est l'ordre qui fabrique la coupure, et avec un HSTS actif il fabrique un écran d'erreur sans bouton pour passer outre. Ici le certificat est obtenu et prouvé avant que le DNS ne bouge : la bascule se réduit à un seul enregistrement, réversible en cinq minutes.
Conventions et cadre d'intervention
Toutes les valeurs propres au site sont notées en placeholders : DOMAINE (le nom de domaine à migrer), IP_CIBLE (l'adresse du serveur de destination), IP_ACTUELLE (l'adresse qui sert le site aujourd'hui), DOCROOT (la racine du site sur la cible). Ne laissez jamais les valeurs réelles d'un client dans un script partagé.
Cette procédure couvre le déplacement d'un site existant vers un nouveau serveur Apache, avec changement d'hébergeur DNS si nécessaire, sans interruption visible pour les visiteurs ni pour la messagerie. Elle ne couvre pas la refonte du site : ce qui arrive sur la cible est ce qui tournait sur la source.
Trois règles en découlent :
- Le certificat existe avant le DNS. Contre-intuitif, mais c'est ce qui rend la coupure nulle. Le motif est au piège n°1.
- Jamais la délégation et le contenu en même temps. Un seul changement à la fois, chacun vérifiable isolément.
- Aucune étape n'est validée sur une absence d'erreur. On vérifie par une observation positive : une page qui répond, un mail réellement reçu, une empreinte identique.
A.Vue d'ensemble
| Phase | Ce qu'on y fait | Effet public |
|---|---|---|
| 00 Inventaire | Relever et geler l'état existant, trancher les quatre questions qui commandent la suite | aucun |
| 01 Serveur cible | Déployer, écrire les vhosts, monter une préversion, passer la recette complète | site invisible |
| 02 Zone DNS | Abaisser le TTL, et si besoin recréer la zone à l'identique ailleurs | aucun |
| 03 Certificat | Émettre le certificat par défi DNS, prouver le HTTPS sur la cible | aucun |
| 04 Bascule | Un seul enregistrement A modifié | 5 minutes, réversible |
| 05 Consolidation | Renouvellement automatique, sauvegardes, HSTS remonté | après 48 h stables |
Les quatre questions à trancher avant tout
Ces quatre réponses déterminent la forme que prendra la migration. Les obtenir prend dix minutes, les découvrir en cours de route coûte une soirée.
La messagerie professionnelle passe par ce domaine
Toute erreur coupe l'activité du client, sans aucun message d'erreur visible. La zone devient alors le sujet principal, le site le sujet secondaire. → Phase 02, route B
Registrar et hébergeur DNS sont souvent deux entités différentes
Le domaine est acheté à un endroit, les enregistrements répondent depuis un autre. Vérifiez les NS réels, pas ce que dit le client. → Route A si la zone est éditable, route B sinon
Il interdit l'ordre habituel
Si le site sert un Strict-Transport-Security de longue durée, basculer sans certificat valide sur la cible rend le site inaccessible aux visiteurs habituels, sans recours. → Phase 03 obligatoire avant la 04
* ?Il peut faire disparaître www en pleine procédure
Créer un jeton de validation sous www annule le joker sur ce nom. → Parade en phase 03.1, mécanisme au piège n°2
# HSTS : sur l'apex ET sur www, les deux peuvent differer curl -sI https://DOMAINE/ | grep -i strict-transport curl -sI https://www.DOMAINE/ | grep -i strict-transport # joker : si un sous-domaine invente repond, il y en a un dig +short A zzz-test-inexistant.DOMAINE
Inventaire et gel de l'état existant
Quand : avant toute chose. Bâcler cette phase est la première cause d'échec des migrations.
L'objectif est simple : ne rien découvrir en cours de route. Tout ce qui n'aura pas été relevé ici se manifestera après la bascule, au pire moment.
for T in A AAAA MX TXT NS CAA SOA; do echo "== $T"; dig +short $T DOMAINE @8.8.8.8 done dig +short TXT _dmarc.DOMAINE dig +short CNAME www.DOMAINE
# Resolve-DnsName affiche les TXT complets la ou nslookup les tronque
Resolve-DnsName DOMAINE -Type TXT -Server 8.8.8.8 | % { $_.Strings -join "" }
Sauvegarder la configuration du serveur cible
Le serveur de destination héberge souvent déjà des sites en production. Avant d'y écrire quoi que ce soit :
sudo tar -czf /var/backups/apache-avant-migration-$(date +%Y%m%d).tar.gz -C / etc/apache2 sudo apache2ctl -S > /var/backups/vhosts-avant-$(date +%Y%m%d).txt
Préparation du serveur cible
Quand : une fois l'inventaire figé. Le site est déployé et testé alors qu'il reste totalement invisible, le DNS pointant encore vers l'ancien hébergement.
Déployer les fichiers
Préférez une archive en flux à une copie fichier par fichier : c'est plus rapide, et le transfert est atomique.
tar -czf - -C /chemin/local . | ssh serveur 'tar -xzf - -C DOCROOT'
# des deux cotes, comparer l'empreinte du manifeste
find . -type f -exec md5sum {} \; | sort -k2 | md5sum
Écrire le vhost HTTP
<VirtualHost *:80>
ServerName DOMAINE
ServerAlias www.DOMAINE
DocumentRoot DOCROOT
<Directory DOCROOT>
AllowOverride All
Require all granted
</Directory>
# Laisse passer la validation du certificat sans reecriture.
<Directory DOCROOT/.well-known/acme-challenge>
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/DOMAINE-error.log
CustomLog ${APACHE_LOG_DIR}/DOMAINE-access.log combined
</VirtualHost>
Écrire le vhost HTTPS, sans l'activer
Écrivez-le maintenant, activez-le en phase 03. Il référence un certificat qui n'existe pas encore : l'activer ferait échouer le rechargement d'Apache, et donc tomber les autres sites du serveur.
<VirtualHost *:443>
ServerName DOMAINE
ServerAlias www.DOMAINE
DocumentRoot DOCROOT
<Directory DOCROOT>
AllowOverride All # le meme oubli ici casse tout au passage HTTPS
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/DOMAINE/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/DOMAINE/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
Monter une préversion
Deux méthodes, selon que vous devez la montrer au client ou non.
- Tunnel
- Port en écoute sur
127.0.0.1uniquement, atteint parssh -L. Personne d'autre ne peut y accéder, y compris les robots. - Filtre IP
- Port ouvert mais
Require ip VOTRE_IP. Montrable au client sans tunnel, à condition qu'il ait une adresse fixe.
Listen 127.0.0.1:8083
<VirtualHost 127.0.0.1:8083>
ServerName DOMAINE
DocumentRoot DOCROOT
<Directory DOCROOT>
AllowOverride All
Require all granted
</Directory>
# Evite que le .htaccess ne redirige vers le site actuel.
RequestHeader set X-Forwarded-Proto "https" early
Header always set X-Robots-Tag "noindex, nofollow"
</VirtualHost>
early est indispensable : sans lui, l'en-tête est posé après mod_rewrite, qui redirige alors la préversion vers le site en production. Voir piège n°9.Recette complète
Balayez toutes les URL, pas trois au hasard. Le sitemap fournit la liste, il suffit de la dérouler.
for u in $(grep -oE "<loc>[^<]+" DOCROOT/sitemap.xml | sed "s|<loc>||; s|https://DOMAINE||"); do
p=${u:-/}
c=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: DOMAINE" \
-H "X-Forwarded-Proto: https" "http://127.0.0.1$p")
[ "$c" = "200" ] || echo "ÉCHEC $c : $p"
done
Contrôlez aussi, à la main : une page inexistante (elle doit rendre un vrai 404), les feuilles de style et les scripts, les images, et les URL avec une barre oblique finale, qui sont la forme servie par la plupart des CMS. Voir piège n°10.
Préparation de la zone DNS
Quand : au moins 24 h avant la bascule, le temps que le TTL abaissé se propage. Aucun effet public à ce stade.
Deux routes, selon que vous avez ou non accès à l'interface qui gère la zone active.
Route A : la zone actuelle est éditable
A, en phase 04. MX, SPF et jetons de vérification restent intacts par construction : ils ne sont jamais touchés.Une seule action ici : abaisser le TTL de l'enregistrement A à 300 secondes, au moins 24 h avant la bascule (ou la durée du TTL actuel s'il est plus court). Sans cela, un retour arrière mettrait autant de temps à se propager que l'ancien TTL, et le filet ne servirait à rien.
Route B : il faut changer d'hébergeur DNS
Cas fréquent : le client n'a pas les accès à l'interface actuelle, ou la zone est chez un prestataire injoignable.
Procédez en trois temps découplés, jamais en un seul geste.
B1. Rendre la zone de destination identique à la zone active
Recréez enregistrement par enregistrement, en gardant l'adresse A actuelle (IP_ACTUELLE). Oui, c'est contre-intuitif : à ce stade on reproduit l'existant, on ne migre rien.
- Tous les MX, avec leurs priorités exactes. Il en manque presque toujours un.
- Le SPF, qui est fréquemment celui de l'hébergeur DNS et non celui de la messagerie réellement utilisée. C'est l'erreur la plus discrète et la plus coûteuse : elle ne se voit pas, elle se constate le jour où les destinataires ne reçoivent plus rien.
- Les jetons de vérification (
google-site-verificationet consorts) : les perdre casse silencieusement les outils du client. - Supprimez les entrées incohérentes avec la messagerie réelle :
CNAMEversmail,imap,pop3,smtp,autoconfig,autodiscover, enregistrementsSRV. S'ils pointent vers un service que le client n'utilise pas, ils configureront ses logiciels de messagerie sur le mauvais serveur. - Abaissez le TTL du
Aà300.
B2. Vérifier avant de basculer
Interrogez directement les serveurs de la zone préparée, même si elle n'est pas encore active. C'est possible, et c'est le seul contrôle qui vaille.
dig +short MX DOMAINE @serveur-dns-destination dig +short TXT DOMAINE @serveur-dns-destination dig +short A DOMAINE @serveur-dns-destination
Comparez au relevé de la phase 00. Tant que les deux zones ne sont pas équivalentes, ne basculez pas la délégation.
B3. Basculer la délégation
Changez les serveurs DNS chez le registrar. Comme les deux zones répondent la même chose, rien ne change de visible. La propagation prend de quelques minutes à 24 h, pendant lesquelles une partie du monde interroge l'ancienne zone et l'autre la nouvelle, sans conséquence puisqu'elles sont identiques.
dig +short NS DOMAINE @8.8.8.8 # les nouveaux serveurs dig +short MX DOMAINE @8.8.8.8 # INCHANGE
Certificat HTTPS, avant toute bascule
Quand : avant de toucher au DNS. C'est cette inversion de l'ordre habituel qui rend la coupure nulle.
Le DNS pointe encore vers l'ancien hébergement : le certificat s'obtient donc par défi DNS-01, le seul qui n'exige pas que le domaine pointe déjà vers le serveur.
* et aucun enregistrement www explicite, créez d'abord un www explicite reproduisant le comportement actuel. Sinon la création du jeton de validation fera disparaître www du DNS en pleine procédure. Voir piège n°2.sudo certbot certonly --manual --preferred-challenges dns \ --cert-name DOMAINE -d DOMAINE -d www.DOMAINE
certonly--apache : cet installateur réécrit les fichiers de vhost et peut toucher à ceux des autres sites hébergés. Voir piège n°7.Certbot demande deux enregistrements TXT sur deux noms distincts : _acme-challenge.DOMAINE et _acme-challenge.www.DOMAINE. Avant d'appuyer sur Entrée, vérifiez que la valeur est réellement publiée. Le quota est de cinq échecs par heure : la vérification coûte dix secondes, l'échec coûte un créneau.
dig +short TXT _acme-challenge.DOMAINE @8.8.8.8
Activer le HTTPS et le prouver, DNS toujours sur l'ancien serveur
sudo a2ensite zz-DOMAINE-ssl
sudo apache2ctl configtest && sudo systemctl reload apache2
Voici le test décisif : il force la résolution vers la cible sans toucher au DNS public.
R="--resolve DOMAINE:443:IP_CIBLE --resolve www.DOMAINE:443:IP_CIBLE" curl -sI $R https://DOMAINE/ # doit repondre 200 curl -sI $R https://www.DOMAINE/ # doit rediriger vers l'apex echo | openssl s_client -connect IP_CIBLE:443 -servername DOMAINE 2>/dev/null \ | openssl x509 -noout -subject -dates
--resolve. Un seul échec interdit de passer à la phase 04.Côté poste de travail, l'équivalent consiste à ajouter une ligne au fichier hosts : vous naviguez alors réellement sur le nouveau site, dans un vrai navigateur, avant que quiconque ne le voie.
La bascule
Quand : une fois toutes les URL vérifiées en HTTPS réel sur la cible. L'opération dure cinq minutes et reste réversible.
Elle se réduit à une seule modification : l'enregistrement A.
| Action | Valeur |
|---|---|
| Supprimer | IP_ACTUELLE |
| Ajouter | IP_CIBLE, TTL 300 |
www est un CNAME vers l'apex, il suit automatiquement : c'est exactement le comportement souhaité.dig +short A DOMAINE @8.8.8.8 # IP_CIBLE dig +short A DOMAINE @1.1.1.1 # IP_CIBLE dig +short MX DOMAINE @8.8.8.8 # INCHANGE curl -sI https://DOMAINE/ | head -1 # 200 curl -s https://DOMAINE/ | grep -oiE "<title>[^<]*</title>"
Puis la question que l'on oublie : les autres sites du serveur répondent-ils toujours ?
IP_ACTUELLE sur l'enregistrement A : effectif en cinq minutes grâce au TTL abaissé. Ne supprimez pas l'ancien hébergement avant plusieurs jours de stabilité, c'est votre filet.Consolidation
Quand : dans la foulée de la bascule pour le certificat, après 48 h stables pour le reste.
Immédiatement : rendre le certificat renouvelable
--manual n'est jamais renouvelé et expire en silence au bout de 90 jours, quand plus personne ne surveille. Maintenant que le DNS pointe vers la cible, reconvertissez-le.sudo certbot certonly --webroot -w DOCROOT --cert-name DOMAINE \
-d DOMAINE -d www.DOMAINE \
--deploy-hook "systemctl reload apache2" --non-interactive --force-renewal
# PROUVER que la conversion a pris
sudo grep -E "^authenticator|^renew_hook" /etc/letsencrypt/renewal/DOMAINE.conf
sudo certbot renew --dry-run
Le --dry-run est aussi le seul contrôle qui prouve que l'ajout de ce site n'a pas cassé le renouvellement des autres certificats du serveur.
Sous 48 h, après stabilité confirmée
- Remonter le HSTS s'il avait été abaissé, à
31536000, sansincludeSubDomains(le certificat ne couvre que deux noms) et sanspreload(engagement quasi irréversible). - Mettre en place la sauvegarde du nouveau site, et la vérifier par une restauration réelle. Une sauvegarde non testée ne compte pas.
- Supprimer les enregistrements
_acme-challenge, devenus inutiles.
Après quelques jours
- Fermer l'ancien hébergement, une fois seulement que le filet n'est plus nécessaire.
- Déclarer le site aux outils pour webmasters et soumettre le sitemap.
- Prévenir le client que la reprise du référencement demande 4 à 8 semaines, avec un creux transitoire. Annoncé, c'est une étape ; découvert, c'est un échec.
Les pièges et leurs parades
Chacun a été rencontré en conditions réelles. Aucun ne produit de message d'erreur explicite, et c'est précisément ce qui les rend coûteux.
| Symptôme | Cause réelle | Parade | Gravité |
|---|---|---|---|
| Écran d'erreur TLS sans bouton pour passer outre, chez les habitués seulement | Le HSTS de l'ancien site oblige le navigateur au HTTPS, la cible n'a pas encore de certificat | Obtenir et prouver le certificat avant de toucher au DNS. Abaisser le HSTS à max-age=300 pendant la migration. | racine |
www cesse de résoudre en pleine procédure de certificat | Le joker * couvrait www ; créer _acme-challenge.www fait naître le nœud et annule le joker | Créer un www explicite avant tout jeton de validation. | bloquant |
| Le site marche en HTTP et casse à l'instant du passage HTTPS : accueil correct, tout le reste en 404 | AllowOverride absent du vhost :443, le .htaccess est ignoré en silence | AllowOverride All dans chacun des deux vhosts. Jamais dans le bloc global. | bloquant |
| Aucun. Tout répond normalement | Le nouveau vhost est devenu serveur par défaut : tout trafic sans nom d'hôte connu atterrit chez lui, et son certificat est présenté aux inconnus | Préfixer le fichier (zz-), puis vérifier avec apache2ctl -S. | discret |
| Après changement de serveurs DNS, le site tombe et les mails partent en indésirables | Zone dormante de l'hébergeur, créée à l'achat du domaine : SPF maison, MX incomplets, A de parking | La route B en trois temps. Comparer ligne à ligne avant de déléguer. | bloquant |
| Le site devient inaccessible 90 jours après la migration | Certificat obtenu en --manual, ignoré par le renouvellement automatique | Reconvertir en --webroot dès la bascule faite, et prouver par certbot renew --dry-run. | bloquant |
| Des vhosts modifiés que personne n'a touchés, parfois ceux d'autres sites | certbot --apache réécrit la configuration et injecte ses propres redirections | N'utiliser que certonly. Certbot n'écrit alors que dans /etc/letsencrypt. | piège |
ERR_TOO_MANY_REDIRECTS, site totalement inaccessible | Derrière un proxy ou sur un mutualisé, %{HTTPS} vaut off même en HTTPS | Tester aussi X-Forwarded-Proto et X-Forwarded-SSL dans la règle. | bloquant |
| La préversion redirige vers le site en production au lieu de s'afficher | RequestHeader set s'applique après mod_rewrite | Ajouter le mot-clé early. | piège |
| Certaines pages s'affichent sans aucune mise en forme, surtout depuis les moteurs | Chemins relatifs plus barre oblique finale : le navigateur résout les ressources depuis un répertoire différent | Rediriger en 301 vers la forme sans barre finale. | piège |
| Une procédure appliquée à la lettre casse le site | Elle repérait une directive par son numéro de ligne, et le fichier a changé | Repérer par le contenu (grep -n), et contrôler l'équilibre des blocs après édition. | piège |
| Le trafic de recherche s'effondre et ne revient pas | La structure des adresses a changé, chaque ancienne URL indexée est une 404 | Relever les anciennes adresses et écrire une 301 par page, points d'entrée techniques du CMS compris. | durable |
Piège n°1, en détail pourquoi le HSTS impose l'ordre entier
L'ancien site servait Strict-Transport-Security: max-age=31536000. Tout navigateur ayant visité le site retient l'obligation de HTTPS pendant un an. Si la cible n'a pas de certificat valide au moment de la bascule, il refuse la connexion, sans proposer de passer outre.
Le diagnostic est très difficile parce que les nouveaux visiteurs, eux, ne voient rien d'anormal : le site est « en ligne » pour tout le monde sauf pour les habitués, c'est-à-dire exactement pour les clients du client.
La parade tient en deux gestes : obtenir et prouver le certificat avant de toucher au DNS (phase 03), et abaisser le HSTS à max-age=300 pendant l'opération pour que le retour arrière reste possible.
Piège n°2, en détail closest encloser, ou comment un joker cesse de s'appliquer
Si la zone contient *.DOMAINE et aucun nœud www explicite, alors www.DOMAINE est une réponse du joker. En créant _acme-challenge.www.DOMAINE, vous faites naître le nœud intermédiaire www. Par la règle du closest encloser (RFC 4592), le joker cesse alors de s'appliquer à ce nom, et www renvoie NODATA.
Autrement dit, la procédure de certificat détruit le nom qu'elle cherchait à certifier. La parade est de créer un www explicite avant tout jeton de validation, reproduisant à l'identique le comportement actuel.
Piège n°8, en détail la règle de redirection HTTPS qui tient derrière un proxy
La règle classique RewriteCond %{HTTPS} off ne fonctionne que si le serveur termine lui-même le TLS. Derrière un répartiteur de charge, ou sur un mutualisé, %{HTTPS} vaut off même quand le visiteur est en HTTPS : la règle redirige à l'infini.
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteCond %{HTTP:X-Forwarded-SSL} !=on
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Pièges n°10 et n°11, en détail barre oblique finale, et édition sûre d'un .htaccess
Les URL des CMS se terminent presque toujours par une barre oblique. Si les pages référencent leurs ressources en relatif et que le site accepte les deux formes, le navigateur résout les chemins depuis un répertoire différent et n'obtient que des 404 : la page s'affiche, nue.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]
Quant aux procédures qui disent « modifier la ligne 71 », ce sont des bombes à retardement : le fichier évolue. Repérez par le contenu, et contrôlez l'intégrité après édition.
grep -n "Strict-Transport-Security" .htaccess sed -i 's|ancienne valeur|nouvelle valeur|' .htaccess [ "$(grep -c '<IfModule' .htaccess)" = "$(grep -c '</IfModule>' .htaccess)" ] \ && echo "OK" || echo "BLOC NON FERMÉ : Apache renverra 500 sur tout le site"
Aide-mémoire
Trois listes, à trois moments. Chaque ligne se valide par une observation positive, jamais par l'absence d'erreur.
Avant de commencer porte 1
- Zone DNS complète relevée et consignée dans un fichier daté
- Présence de MX identifiée, donc messagerie en jeu ou non
- HSTS de l'ancien site vérifié sur l'apex et sur
www - Présence d'un joker DNS vérifiée
- Accès à la gestion de la zone confirmé (route A ou route B)
- Configuration du serveur cible sauvegardée
- Vhost par défaut actuel relevé
Avant de basculer porte 2, la seule irréversible en apparence
- Toutes les URL du sitemap répondent 200 en HTTPS réel (
--resolve) - Certificat émis, couvrant l'apex et
www - Vhost
:443actif,AllowOverride Allprésent dans les deux vhosts - Vhost par défaut inchangé
- Redirections des anciennes URL testées
- Page 404 fonctionnelle
- TTL de l'enregistrement
Aà 300 depuis plus longtemps que l'ancien TTL - Autres sites du serveur toujours en ligne
- Ancien hébergement toujours actif, c'est le filet
Après la bascule porte 3
- Résolution vérifiée sur au moins trois résolveurs publics
- MX inchangés et mail de test réellement reçu
- Site en 200, contenu vérifié visuellement
- Certificat converti en renouvellement automatique
certbot renew --dry-runréussi pour tous les certificats du serveur- Autres sites du serveur toujours en ligne
- Sauvegarde du nouveau site en place et testée par restauration
- HSTS remonté après 48 h stables
- Client prévenu du délai de reprise du référencement
Commandes de référence
dig +short A DOMAINE @8.8.8.8 dig +short MX DOMAINE @serveur-autoritaire # interroge une zone meme inactive dig +noall +answer A www.DOMAINE @serveur # revele si la reponse vient d'un joker
curl -sI --resolve DOMAINE:443:IP_CIBLE https://DOMAINE/ echo | openssl s_client -connect IP_CIBLE:443 -servername DOMAINE 2>/dev/null \ | openssl x509 -noout -subject -dates
sudo apache2ctl configtest # TOUJOURS avant un rechargement sudo apache2ctl -S # vhosts et serveur par defaut sudo systemctl reload apache2 # ne coupe pas les connexions en cours sudo certbot certificates sudo certbot renew --dry-run sudo grep -E "^authenticator" /etc/letsencrypt/renewal/DOMAINE.conf
rm -rf un point de montage : utilisez rmdir, qui refuse de supprimer un répertoire non vide. Le refus est le garde-fou. Ne jamais chown ni chmod un point de montage actif : la modification traverse le montage et s'applique aux fichiers réels, cassant les droits du site source.Je peux la jouer pour vous
Cette procédure est publiée telle qu'elle est appliquée en intervention réelle. Si vous préférez la déléguer, ou si votre cas sort du cadre décrit ici, écrivez-moi : je reprends la migration de bout en bout, boîtes et postes compris.
Une migration ou une reprise technique à faire ?
Décrivez votre situation, je vous dis ce qui est faisable, en combien de temps et à quel prix.