En aplicaciones Web escritas con .NET (tanto "clásico" como .NET Core o .NET 5) si están albergadas en Internet Information Server, una situación habitual es la que describe el título de este post. Vas a actualizar la aplicación, para lo cual copias todos sus archivos por encima de los que están en el servidor y, de repente, ¡moooooc! se produce un error que dice que no es posible copiar ciertas DLLs porque están en uso. Lo peor es que, en muchas ocasiones, tras producirse ese error se hace necesario reiniciar Internet Information Server o hacer un iisreset.exe porque la aplicación deja de funcionar.

El motivo es que la aplicación está en funcionamiento y por lo tanto haciendo uso de las DLLs que contienen el código de la misma, las cuales están ubicadas en la subcarpeta Bin de tu sitio web.

Para evitar el problema lo que deberías hacer es descargar la aplicación antes de intentar copiar las nuevas DLLs al sitio. Ello no implica resetear IIS, que detendría otros sitios web y aplicaciones que tuvieses en el servidor, ni tampoco detenerlo de modo que no responda. Se trata de algo más ligero y que además informa a los usuarios momentáneamente de que se está actualizando la aplicación.

El truco es muy sencillo y consiste en crear una página en la raíz de tu aplicación llamada app_offline.htm.

Esta página, con este nombre, se trata de manera especial por parte de ASP.NET o por parte del módulo ASP.NET Core para albergar en IIS esta tecnología. Al estar presente este archivo, de manera automática, la aplicación se descarga del dominio de aplicación, y por lo tanto las DLLs y cualquier otro archivo de la misma. Ademas se cerrarán todas las conexiones/peticiones que estuviesen abiertas en ese momento y todas las nuevas se redirigirán hacia ese archivo, de modo que se mostrará el contenido del mismo para cualquier petición que se reciba.

De este modo se elimina el problema del que hablábamos al principio.

Además, en la práctica ese archivo actuará como el mítico archivo de "En obras" de los de toda la vida, de modo que será lo único que se vea al acceder a la web desde cualquier lugar o solicitando cualquier página.

Por ejemplo, este es el aspecto del mío para este blog:

Página de actualización app_offline.htm que uso en JASoft.org

Que es muy sencillo, pero suficiente, ya que la mayor parte de las veces la parada es unos pocos segundos o un minuto, por lo que poca gente lo verá. No utilizo ningún gráfico ni ningún otro archivo, pero podría hacerlo al tratarse de archivos estáticos y por lo tanto no bloqueados.

Si te interesa lo puedes descargar desde aquí. Fíjate en que el que te descargarás se llama app_offline-OFF.htm, es decir, tiene un -OFF de más en el nombre. Si no fuese así y tuviese el nombre correcto, obviamente el blog no funcionaría porque lo estaría actualizando 😉

Evitar impacto en SEO mientras el sitio está en mantenimiento

Existe un factor muy importante a la hora de poner una página de "En mantenimiento" en un sitio web público: evitar que impacte en el posicionamiento del mismo.

Cuando el sitio está en mantenimiento si, por pura casualidad, la araña de Google o de algún otro buscador pasa por tu sitio justo cuando lo estás actualizando y por lo tanto solamente ve la página de "En actualización", debería ver un código de estatus HTTP diferente al normal (el 200, que indica que todo va bien). El motivo es que si viese un c´pdigo 200 pensaría que todo está normal e indexaría tan solo la página de mantenimiento borrando del mapa el resto del contenido 😱

En concreto lo que debería ver es el código de estado 503 que significa que el sitio web no está disponible temporalmente. Y ahí la palabra clave es "temporalmente". Cuando la araña ve esto debería hacer caso omiso del contenido de la página y simplemente intentar indexar el sitio más adelante, porque sabe que es una situación temporal y no permanente.

Por suerte en nuestro caso no tendremos que hacer nada especial ya que es el propio IIS/ASP.NET quién se encarga de devolver el código de estado apropiado para la página app_offline.htm:

La imagen muestra la pestaña Network de las herramientas del desarrollador con el estado 503 para la petición

Nuestros usuarios no ven esto, pero las arañas de los buscadores sí. De este modo evitamos que la no disponibilidad del sitio web en ese momento no suponga un problema para el posicionamiento del mismo. Si no lo hiciésemos de esta manera nuestro ranking podría sufrir problemas durante los siguientes días o semanas. Por eso es estupendo que sea el propio ASP.NET/IIS el que se encargue de hacerlo automáticamente por nosotros, sin que tengamos siquiera que acordarnos.

De todos modos (llámame paranoico) una cosa que hago para para evitar que algún buscador raro indexe por error la página de mantenimiento y que luego aparezca por ahí, es añadir una cabecera meta a la página para que no indexe su contenido ni siga cualquier enlace que le hayas podido poner:

<meta name="robots" content="noindex,nofollow">

Seguramente no vale para nada, pero al menos sí me sirve para que no se indexe ni siquiera cuando la tengo con el sufijo "-OFF" que comenté antes, que es como está ahora y por lo cual puedes descargarla desde el enlace anterior. Nunca está de más por si las moscas.

En resumen

Si tienes una aplicación ASP.NET o ASP.NET Core en producción y necesitas actualizarla, la manera correcta de hacerlo no es simplemente copiar por encima todos los archivos, aunque a veces te funcione. Lo suyo es descargar la aplicación de memoria para asegurarnos de que se han liberado todos los recursos que pudieran estar bloqueados, mostrar una página de mantenimiento, actualizar y volver a ponerla en línea.

Todo esto lo podemos conseguir con ASP.NET e IIS de manera automática con el uso de un único archivo especial que además evita problemas de posicionamiento en buscadores.

¡Espero que te resulte útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor

Escrito por un humano, no por una IA