Une page de maintenance qui renvoie 200 dit aux moteurs que tout votre site est désormais une page annonçant « de retour bientôt » — et ils l'indexeront. La bonne réponse est un 503 avec un en-tête Retry-After, qui signifie indisponible temporairement, revenez plus tard — et cela ne coûte rien.

Nginx

server {
    # ...
    if (-f /var/www/site/maintenance.on) {
        return 503;
    }

    error_page 503 @maintenance;
    location @maintenance {
        root /var/www/site/public;
        rewrite ^ /maintenance.html break;
        add_header Retry-After 3600 always;
    }
}
sudo touch /var/www/site/maintenance.on     # on
sudo rm /var/www/site/maintenance.on        # off

Un interrupteur par fichier, cela veut dire aucun rechargement, aucun changement de configuration, et il peut être basculé depuis un script de déploiement.

Laissez-vous entrer

set $maint 0;
if (-f /var/www/site/maintenance.on) { set $maint 1; }
if ($remote_addr = 203.0.113.42)   { set $maint 0; }
if ($maint = 1) { return 503; }
Sans exception, vous ne pouvez pas tester le correctif que vous déployez, et le réflexe habituel est de couper le mode maintenance alors que le site est encore cassé. Inscrivez votre propre adresse avant d'en avoir besoin.

Ce que la page devrait dire

  • Que c'est prévu, et à quelle heure le site revient — une heure véritable, pas « sous peu ».
  • Un moyen de vous joindre qui ne dépende pas du site.
  • Aucune dépendance à l'application : un fichier statique avec du CSS en ligne.

Vérifiez

curl -sSI https://yourdomain.com/ | grep -E '^HTTP|retry-after'
# HTTP/2 503
# retry-after: 3600
Pour un déploiement qui prend quelques secondes, n'utilisez pas du tout le mode maintenance : construisez dans un nouveau répertoire et basculez un lien symbolique. Personne ne voit rien — voir Déployer par bascule atomique.