Desconectar aplicaciones web con Web Deploy

por Jason Lee

En este tema se describe cómo desconectar una aplicación web mientras dure una implementación automatizada mediante la Herramienta de implementación web (Web Deploy) de Internet Information Services (IIS). Los usuarios que navegan a la aplicación web se redirigen a un archivo App_offline.htm hasta que se completa la implementación.

Este tema forma parte de una serie de tutoriales basados en los requisitos de implementación empresarial de una empresa ficticia denominada Fabrikam, Inc. En esta serie de tutoriales se utiliza una solución de ejemplo (Contact Manager) para representar una aplicación web con un nivel de complejidad realista, que incluye una aplicación ASP.NET MVC 3, un servicio Windows Communication Foundation (WCF) y un proyecto de base de datos.

El método de implementación que constituye el núcleo de estos tutoriales se basa en el enfoque del archivo de proyecto dividido descrito en Descripción del archivo del proyecto, en el que el proceso de compilación está controlado por dos archivos de proyecto: uno que contiene las instrucciones de compilación que se aplican a todos los entornos de destino y otro que contiene los ajustes de compilación e implementación específicos del entorno. En tiempo de compilación, el archivo del proyecto específico del entorno se combina en el archivo del proyecto independiente del entorno para formar un conjunto completo de instrucciones de compilación.

Resumen de las tareas

En muchos escenarios, querrá desconectar una aplicación web mientras realiza cambios en componentes relacionados, como bases de datos o servicios web. Normalmente, en IIS y ASP.NET, puede hacerlo si coloca un archivo denominado App_offline.htm en la carpeta raíz del sitio web o la aplicación web de IIS. App_offline.htm es un archivo HTML estándar y normalmente contendrá un mensaje sencillo que informa al usuario de que el sitio no está disponible temporalmente debido al mantenimiento. Aunque el archivo App_offline.htm existe en la carpeta raíz del sitio web, IIS redirigirá automáticamente las solicitudes al archivo. Cuando haya terminado de realizar actualizaciones, quite el archivo App_offline.htm y el sitio web reanudará el servicio de solicitudes como de costumbre.

Al usar Web Deploy para realizar implementaciones automatizadas o de un solo paso en un entorno de destino, es posible que quiera incorporar y quitar el archivo App_offline.htm en el proceso de implementación. Para ello, debe completar estas tareas generales:

  • En el archivo del proyecto de Microsoft Build Engine (MSBuild) que use para controlar el proceso de implementación, cree un destino de MSBuild que copie un archivo App_offline.htm en el servidor de destino antes de que comiencen las tareas de implementación.
  • Agregue otro destino de MSBuild que quite el archivo App_offline.htm del servidor de destino cuando se completen todas las tareas de implementación.
  • En el proyecto de aplicación web, cree un archivo .wpp.targets que garantice que se agregue un archivo App_offline.htm al paquete de implementación cuando se invoque Web Deploy.

En este tema se explica cómo realizar estos procedimientos. En las tareas y tutoriales de este tema se supone que ya ha creado una solución que contiene al menos un proyecto de aplicación web y que usa un archivo del proyecto personalizado para controlar el proceso de implementación como se describe en Implementación web en la empresa. Como alternativa, puede usar la solución de ejemplo Contact Manager para seguir los ejemplos del tema.

Adición de un archivo App_Offline a un proyecto de aplicación web

La primera tarea que necesita completar es agregar un archivo App_offline al proyecto de aplicación web:

  • Para evitar que el archivo interfiera con el proceso de desarrollo (no quiere que la aplicación esté permanentemente sin conexión) debe asignarle un nombre distinto de App_offline.htm. Por ejemplo, podría asignar el nombre App_offline-template.htm al archivo.
  • Para evitar que el archivo se implemente tal y como está, debe establecer la acción de compilación en Ninguno.

Para agregar un archivo App_offline a un proyecto de aplicación web

  1. Abra la solución en Visual Studio 2010.

  2. En la ventana Explorador de soluciones, haga clic con el botón derecho en proyecto de aplicación web, seleccione Agregar y, después, haga clic en Nuevo elemento.

  3. En el cuadro de diálogo Agregar nuevo elemento, seleccione Página HTML.

  4. En el cuadro Nombre, escriba App_offline-template.htm y, después, haga clic en Agregar.

    In the Name box, type App_offline-template.htm, and then click Add.

  5. Agregue código HTML simple para informar a los usuarios de que la aplicación no está disponible y, después, guarde el archivo. No incluya ninguna etiqueta del lado servidor (por ejemplo, las etiquetas con el prefijo "asp:").

    Add some simple H T M L to inform users that the application is unavailable, and then save the file.

  6. En la ventana Explorador de soluciones, haga clic con el botón derecho en el archivo nuevo y, después, haga clic en Propiedades.

  7. En la ventana Propiedades, en la fila Acción de compilación, seleccione Ninguno.

    In the Properties window, in the Build Action row, select None.

Implementación y eliminación de un archivo App_Offline

El siguiente paso consiste en modificar la lógica de implementación para copiar el archivo en el servidor de destino al principio del proceso de implementación y quitarlo al final.

Nota:

En el siguiente procedimiento se supone que usa un archivo del proyecto de MSBuild personalizado para controlar el proceso de implementación, como se ha descrito en Descripción del archivo del proyecto. Si va a realizar la implementación directamente desde Visual Studio, deberá usar otro enfoque. Sayed Ibrahim Hashimi describe uno de estos enfoques en Procedimiento para desconectar la aplicación web durante la publicación.

Para implementar un archivo App_offline en un sitio web de IIS de destino, debe invocar MSDeploy.exe mediante el proveedor contentPath de Web Deploy. El proveedor contentPath admite rutas de acceso de directorio físico y rutas de acceso de sitio web o aplicación de IIS, lo que hace que sea la opción ideal para sincronizar un archivo entre una carpeta de proyecto de Visual Studio y una aplicación web de IIS. Para implementar el archivo, el comando MSDeploy debe ser similar al siguiente:

msdeploy.exe –verb:sync
             -source:contentPath="[Project folder]\App_offline.template.htm"
             -dest:contentPath="[IIS application path]/App_offline.htm",
              computerName="[Destination web server]"

Para quitar el archivo del sitio de destino al final del proceso de implementación, el comando MSDeploy debe ser similar al siguiente:

msdeploy.exe –verb:delete
             -dest:contentPath="[IIS application path]/App_offline.htm",
              computerName="[Destination web server]"

Para automatizar estos comandos como parte de un proceso de compilación e implementación, debe integrarlos en el archivo del proyecto de MSBuild personalizado. En el procedimiento siguiente se describe cómo hacerlo.

Para implementar y eliminar un archivo App_offline

  1. En Visual Studio 2010, abra el archivo del proyecto de MSBuild que controla el proceso de implementación. En la solución de ejemploContact Manager, es el archivo Publish.proj.

  2. En el elemento Project raíz, cree un elemento PropertyGroup a fin de almacenar variables para la implementación de App_offline:

    <PropertyGroup>
      <AppOfflineTemplateFilename   
        Condition=" '$(AppOfflineTemplateFilename)'=='' ">
          app_offline-template.htm
      </AppOfflineTemplateFilename>
      <AppOfflineSourcePath 
        Condition=" '$(AppOfflineSourcePath)'==''">
          $(SourceRoot)ContactManager.Mvc\$(AppOfflineTemplateFilename)
      </AppOfflineSourcePath>
    </PropertyGroup>
    
  3. La propiedad SourceRoot se define en otra parte del archivo Publish.proj. Indica la ubicación de la carpeta raíz del contenido de origen en relación con la ruta de acceso actual, es decir, con respecto a la ubicación del archivo Publish.proj.

  4. El proveedor contentPath no aceptará rutas de acceso de archivo relativas, por lo que debe obtener una ruta de acceso absoluta al archivo de origen para poder implementarlo. Puede usar la tarea ConvertToAbsolutePath para hacerlo.

  5. Agregue un nuevo elemento Target denominado GetAppOfflineAbsolutePath. Dentro de este destino, use la tarea ConvertToAbsolutePath para obtener una ruta de acceso absoluta al archivo App_offline-template en la carpeta del proyecto.

    <Target Name="GetAppOfflineAbsolutePath" BeforeTargets="DeployAppOffline">
      <ConvertToAbsolutePath Paths="$(AppOfflineSourcePath)">
        <Output TaskParameter="AbsolutePaths"       
                PropertyName="AppOfflineAbsoluteSourcePath" />
      </ConvertToAbsolutePath>
    </Target>
    
  6. Este destino toma la ruta de acceso relativa al archivo App_offline-template en la carpeta del proyecto y la guarda en una nueva propiedad como una ruta de acceso de archivo absoluta. El atributo BeforeTargets especifica que quiere que este destino se ejecute antes del destino DeployAppOffline, que creará en el paso siguiente.

  7. Agregue un nuevo destino denominado DeployAppOffline. Dentro de este destino, invoque el comando MSDeploy.exe que implementa el archivo App_offline en el servidor web de destino.

    <Target Name="DeployAppOffline" 
            Condition=" '$(EnableAppOffline'!='false' ">
      <PropertyGroup> 
        <_Cmd>"$(MSDeployPath)\msdeploy.exe" -verb:sync 
               -source:contentPath="$(AppOfflineAbsoluteSourcePath)" 
               -dest:contentPath="$(ContactManagerIisPath)/App_offline.htm",
                computerName="$(MSDeployComputerName)"
        </_Cmd>
      </PropertyGroup>
      <Exec Command="$(_Cmd)"/> 
    </Target>
    
  8. En este ejemplo, la propiedad ContactManagerIisPath se define en otra parte del archivo del proyecto. Simplemente es una ruta de acceso de la aplicación de IIS, con el formato [Nombre del sitio web de IIS]/[Nombre de la aplicación]. La inclusión de una condición en el destino permite a los usuarios activar o desactivar la implementación de App_offline mediante el cambio de un valor de propiedad o si proporcionan un parámetro de línea de comandos.

  9. Agregue un nuevo destino denominado DeleteAppOffline. Dentro de este destino, invoque el comando MSDeploy.exe que quita el archivo App_offline del servidor web de destino.

    <Target Name="DeleteAppOffline" 
            Condition=" '$(EnableAppOffline'!='false' ">
      <PropertyGroup> 
        <_Cmd>"$(MSDeployPath)\msdeploy.exe" -verb:delete 
               -dest:contentPath="$(ContactManagerIisPath)/App_offline.htm",
                computerName="$(MSDeployComputerName)"
        </_Cmd>
      </PropertyGroup>
      <Exec Command="$(_Cmd)"/> 
    </Target>
    
  10. La tarea final consiste en invocar estos nuevos destinos en los puntos adecuados durante la ejecución del archivo del proyecto. Puede hacerlo de varias maneras. Por ejemplo, en el archivo Publish.proj, la propiedad FullPublishDependsOn especifica una lista de destinos que se deben ejecutar en orden cuando se invoca el destino predeterminado FullPublish.

  11. Modifique el archivo del proyecto de MSBuild para invocar los destinos DeployAppOffline y DeleteAppOffline en los puntos adecuados del proceso de publicación.

    <PropertyGroup>
      <FullPublishDependsOn>
        Clean;
        BuildProjects; 
        DeployAppOffline;
        GatherPackagesForPublishing;
        PublishDbPackages;
        DeployTestDBPermissions;
        PublishWebPackages;
        DeleteAppOffline;
      </FullPublishDependsOn> 
    </PropertyGroup>
    <Target Name="FullPublish" DependsOnTargets="$(FullPublishDependsOn)" />
    

Al ejecutar el archivo del proyecto de MSBuild personalizado, el archivo App_offline se implementará en el servidor inmediatamente después de una compilación correcta. Después, se eliminará del servidor una vez que se completen todas las tareas de implementación.

Adición de un archivo App_Offline a paquetes de implementación

En función de cómo configure la implementación, cualquier contenido existente en la aplicación web IIS de destino (como el archivo App_offline.htm) se puede eliminar automáticamente al implementar un paquete web en el destino. Para asegurarse de que el archivo App_offline.htm permanece en su lugar durante la implementación, debe incluirlo en el propio paquete de implementación web, además de implementar el archivo directamente al principio del proceso de implementación.

  • Si ha seguido las tareas anteriores de este tema, habrá agregado el archivo App_offline.htm al proyecto de aplicación web con otro nombre de archivo (se ha usado App_offline-template.htm) y habrá establecido la acción de compilación en Ninguno. Estos cambios son necesarios para evitar que el archivo interfiera con el desarrollo y la depuración. Como resultado, debe personalizar el proceso de empaquetado para asegurarse de que el archivo App_offline.htm se incluye en el paquete de implementación web.

La canalización de publicación web (WPP) usa una lista de elementos denominada FilesForPackagingFromProject para crear una lista de archivos que se deben incluir en el paquete de implementación web. Puede personalizar el contenido de los paquetes web si agrega elementos propios a esta lista. Para ello, debe completar estos pasos generales:

  1. Cree un archivo del proyecto personalizado denominado [nombre del proyecto].wpp.targets en la misma carpeta que el archivo del proyecto.

    Nota:

    El archivo .wpp.targets debe ir en la misma carpeta que el archivo del proyecto de aplicación web (por ejemplo, ContactManager.Mvc.csproj), no en la misma carpeta que cualquier archivo del proyecto personalizado que use para controlar el proceso de compilación e implementación.

  2. En el archivo .wpp.targets, cree un destino de MSBuild que se ejecute antes del destino CopyAllFilesToSingleFolderForPackage. Es el destino de WPP que crea una lista de elementos que se van a incluir en el paquete.

  3. En el nuevo destino, cree un elemento ItemGroup.

  4. En el elemento ItemGroup, agregue un elemento FilesForPackagingFromProject y especifique el archivo App_offline.htm.

El archivo .wpp.targets debe ser similar al siguiente:

<Project ToolsVersion="4.0" 
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="AddAppOfflineToPackage"
          BeforeTargets="CopyAllFilesToSingleFolderForPackage">
    <ItemGroup>   
      <FilesForPackagingFromProject Include="App_offline-template.htm">
        <DestinationRelativePath>App_offline.htm</DestinationRelativePath>
    </FilesForPackagingFromProject>
  </ItemGroup>
  </Target>
</Project>

Estos son los puntos clave en los que debe fijarse en este ejemplo:

  • El atributo BeforeTargets inserta este destino en WPP y especifica que se debe ejecutar inmediatamente antes del destino CopyAllFilesToSingleFolderForPackage.
  • El elemento FilesForPackagingFromProject usa el valor de metadatos DestinationRelativePath para cambiar el nombre del archivo de App_offline-template.htm a App_offline.htm a medida que se agrega a la lista.

En el siguiente procedimiento se muestra cómo agregar este archivo .wpp.targets a un proyecto de aplicación web.

Para agregar un archivo .wpp.targets a un paquete de implementación web

  1. Abra la solución en Visual Studio 2010.

  2. En la ventana Explorador de soluciones, haga clic con el botón derecho en el nodo del proyecto de aplicación web (por ejemplo, ContactManager.Mvc), seleccione Agregar y, después, haga clic en Nuevo elemento.

  3. En el cuadro de diálogo Agregar nuevo elemento, seleccione la plantilla Archivo XML.

  4. En el cuadro Nombre, escriba [nombre del proyecto].wpp.targets (por ejemplo, ContactManager.Mvc.wpp.targets) y, después, haga clic en Agregar.

    In the Name box, type project name .wpp.targets, then click Add.

    Nota:

    Si agrega un nuevo elemento al nodo raíz de un proyecto, el archivo se crea en la misma carpeta que el archivo del proyecto. Para comprobarlo, abra la carpeta en el Explorador de Windows.

  5. En el archivo, agregue el marcado de MSBuild descrito anteriormente.

    <Project ToolsVersion="4.0" 
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <Target Name="AddAppOfflineToPackage"
              BeforeTargets="CopyAllFilesToSingleFolderForPackage">
        <ItemGroup>   
          <FilesForPackagingFromProject Include="App_offline-template.htm">
            <DestinationRelativePath>App_offline.htm</DestinationRelativePath>
        </FilesForPackagingFromProject>
      </ItemGroup>
      </Target>
    </Project>
    
  6. Guarde y cierre el archivo [nombre del proyecto].wpp.targets.

La próxima vez que compile y empaquete el proyecto de aplicación web, WPP detectará automáticamente el archivo .wpp.targets. El archivo App_offline-template.htm se incluirá en el paquete de implementación web resultante como App_offline.htm.

Nota:

Si se produce un error en la implementación, el archivo App_offline.htm permanecerá en su lugar y la aplicación seguirá sin conexión. Este suele ser el comportamiento deseado. Para volver a poner la aplicación en línea, puede eliminar el archivo App_offline.htm del servidor web. Como alternativa, si corrige algún error y ejecuta una implementación correcta, se quitará el archivo App_offline.htm.

Conclusión

En este tema se ha descrito cómo desconectar una aplicación web durante la implementación mediante la publicación de un archivo App_offline.htm en el servidor de destino al principio del proceso de implementación y su eliminación al final. También se ha explicado cómo incluir un archivo App_offline.htm en un paquete de implementación web.

Lecturas adicionales

Para más información sobre el proceso de empaquetado e implementación, vea Compilación y empaquetado de proyectos de aplicación web, Configuración de parámetros para la implementación de paquetesweb e Implementación de paquetes web.

Si publica las aplicaciones web directamente desde Visual Studio, en lugar de usar el enfoque de archivo del proyecto de MSBuild personalizado descrito en estos tutoriales, tendrá que usar un enfoque ligeramente diferente para desconectar la aplicación durante el proceso de publicación.