Una página de mantenimiento que devuelve 200 les dice a los buscadores que tu sitio entero es ahora una página que pone «volvemos pronto», y la van a indexar. La respuesta correcta es un 503 con cabecera Retry-After, que significa no disponible temporalmente, vuelve luego, y no cuesta nada.

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 interruptor basado en un archivo significa sin recargas, sin cambios de configuración, y se puede accionar desde un script de despliegue.

Déjate entrar a ti

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; }
Sin una excepción no puedes probar el arreglo que estás desplegando, y la reacción habitual es apagar el modo mantenimiento con el sitio todavía roto. Pon tu propia dirección antes de necesitarla.

Qué debería decir la página

  • Que está previsto, y cuándo vuelve: una hora de verdad, no «en breve».
  • Una forma de contactar contigo que no dependa del sitio.
  • Sin depender de la aplicación: un archivo estático con el CSS dentro.

Compruébalo

curl -sSI https://yourdomain.com/ | grep -E '^HTTP|retry-after'
# HTTP/2 503
# retry-after: 3600
Para un despliegue que dura segundos, no uses el modo mantenimiento en absoluto: compila en un directorio nuevo y cambia un enlace simbólico. Nadie ve nada: consulta Desplegar con un cambio atómico.