# Publicar aplicaciones ASP.NET Core en IIS con Web Deploy mediante perfiles de publicación de Visual Studio y diferenciando entornos de implementación

Los perfiles de publicación de Visual Studio (opens new window) son archivos de configuración donde se almacena la información de publicación de los servicios que contiene un proyecto. Con ellos podemos automatizar y simplificar la creación del conjunto de ficheros que permiten la ejecución de una aplicación y el despliegue de dichos ficheros a una máquina o servicio de destino.

La creación de múltiples perfiles de publicación en un mismo proyecto es una manera básica de facilitar las tareas de despliegue cuando tenemos una arquitectura de sistemas basada en múltiples niveles de implementación y debemos hacer el despliegue del software en cada uno de ellos. Los entornos o niveles de implementación que se suelen contemplar en los depliegues son:

  • Entorno de desarrollo (Development): es el entorno usado por los programadores y donde se desarrollan los cambios en el software.
  • Entorno de pruebas (Testing): es el entorno donde se realizan las pruebas unitarias, bien automáticas o humanas.
  • Entorno de pre-producción (Staging): es el entorno usado por el cliente para comprobar las características implementadas antes de su puesta en producción.
  • Entorno de producción (Production): es el entorno con el que los usuarios finales interactúan.

# ¿Cómo crear un perfil de publicación?

Los siguientes pasos están basados en Visual Studio 2019 o versiones superiores. Un mismo proyecto puede tener múltiples perfiles de publicación por lo que crearemos uno por cada entorno de implementación. Pasos a seguir:

  • En el Explorador de soluciones de Visual Studio, pulsamos con el botón derecho en el proyecto y seleccionamos la opción Publicar. Otra alternativa es seleccionar el proyecto y seleccionar Publicar {NOMBRE DEL PROYECTO} en el menú Compilar.
  • Si el proyecto no contiene previamente ningún perfil de publicación, se mostrará la página para elegir un destino de publicación.
  • Si previamente teníamos configurado algún perfil de publicación, aparecerá la pestaña Publicar de la página de funcionalidades de la aplicación. En ese caso, seleccionamos la opción Nuevo que aparece debajo de la lista desplegable de perfiles.
  • En la ventana Publicar, elegimos Servidor web (IIS).
  • Elegimos seguidamente Web Deploy como método de implementación.
  • Configuramos las opciones necesarias del método de publicación y seleccionamos Finalizar. Las opciones mínimas que debemos configurar son:
    • Servidor: La ruta del servidor de destino de la publicación.
    • Nombre del sitio: El nombre del sitio web del IIS del servidor de destino de la publicación.
  • Una vez creado el perfil de publicación, cambia el contenido de la pestaña Publicar y el perfil recién creado aparecerá en una lista desplegable.

Por cada perfil de publicación, Visual Studio genera un archivo MSBuild (opens new window) ubicado en la ruta Properties/PublishProfiles/{NOMBRE DEL PERFIL}.pubxml con toda la información de la configuración de publicación y que es posible modificar para personalizar el proceso de compilación y publicación del proyecto.

# Perfiles de publicación y configuración en ASP.NET Core

Cuando hacemos uso de la configuración en ASP.NET Core (opens new window) mediante archivos de configuración como appsetting.json o appsettings.{Entorno}.json, es necesario hacer un ajuste manual en el fichero de publicación .pubxml previamente generado para agregarle el entorno de ejecución que estamos desplegando. Según los niveles de implementación antes mencionados, deberíamos usar los valores Development, Testing, Staging o Production de la siguiente manera:

  <PropertyGroup>
    ...
    <EnvironmentName>Staging</EnvironmentName>
  </PropertyGroup>

Agregando dicha configuración, nos aseguraremos de que cuando publiquemos nuestra aplicación ésta hará uso del fichero de configuración del entorno que hayamos establecido en el nodo EnvironmentName. El proceso por el que se aplicará dicha configuración será mediante la creación automática de un fichero web.config en el que se indicará de manera explícita la varialble de entorno ASPNETCORE_ENVIRONMENT con el valor que hayamos establecido en nuestro nuevo nodo.

# Publicación de carpetas personalizadas

En ocasiones debemos incluir en nuestra publicación carpetas que de forma predeterminada nuestro proyecto no agregaría. Es el caso por ejemplo de una carpeta situada al mismo nivel que la carpeta de nuestro proyecto. Para ello debemos realizar la siguiente modificación en el fichero del perfil de publicación:

  <PropertyGroup>
    <PipelineCollectFilesPhaseDependsOn>
      IncludeCustomFiles;
      $(PipelineCollectFilesPhaseDependsOn);
    </PipelineCollectFilesPhaseDependsOn>
  </PropertyGroup>
  <Target Name="IncludeCustomFiles">
    <Message Text="Including custom files" Importance="high" />
    <ItemGroup>
      <_CustomFiles Include="$(MSBuildProjectDirectory)\..\myfolder\**\*" />
      <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
        <DestinationRelativePath>myfolder\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
  </Target>

En el anterior ejemplo la carpeta myfolder está al mismo nivel que la carpeta de nuestro proyecto. Si dicha carpeta estuviera dentro de nuestro proyecto, bastaría cambiar $(MSBuildProjectDirectory)\..\myfolder\**\* por myfolder\**\*.

# Omisión de carpetas

En otras ocasiones simplementer queremos excluir de nuestra publicación carpetas que de forma predeterminada nuestro proyecto sí agregarían al despliegue. En dicho caso debemos realizar la siguiente modificación en el fichero del perfil de publicación:

  <ItemGroup>
    <MsDeploySkipRules Include="CustomSkipFolder">
      <ObjectName>dirPath</ObjectName>
      <AbsolutePath>myfolder\\mysubfolder</AbsolutePath>
    </MsDeploySkipRules>
  </ItemGroup>

En el anterior ejemplo se excluiría de la publicación la carpeta myfolder\mysubfolder.

# Creación del entorno de ejecución en IIS 8 o posterior

Para poder publicar nuestro proyecto en el servidor IIS, previamente debemos haber preparado el entorno de ejecución siguiendo los siguientes pasos en el servidor de publicación:

  1. Instalar la versión de .NET Core que use nuestro proyecto. Será necesario instalar la opción ASP.NET Core Hosting Bundle y en algunos casos es posible que sea también necesario reiniciar la máquina.
  2. Instalar el certificado SSL del cual hará uso nuestra aplicación.
    • Podemos hacerlo mediante la obtención del fichero pfx de nuestro certificado con la clave privada incluida y el uso de la herramienta mmc.exe (Microsoft Management Console) para su importación a través del Snap-in Certificates a nivel de Computer account.
  3. Instalar IIS Web Deploy.
  4. Crearemos el directorio físico donde alojaremos nuestra aplicación.
  5. Añadiremos al IIS un nuevo sitio web
    • El nuevo sitio apuntará a la ruta física del directorio que hemos creado para alojar la aplicación.
    • Al nuevo sitio creado se le asignará a un nuevo pool propio, sin código gestionado (No Managed Code).
    • Asignaremos al nuevo sitio web el certificado que hemos importado previamente a través del apartado Bindings de la sección Actions del IIS, mediante la creación de una entrada para el protocolo https. Si necesitáramos configurar más de un certificado en una misma IP, tendremos que activar la opción Require Server Name Indication.

# Errores comunes durante el proceso de publicación y al consumir servicios publicados

Cuando intentemos realizar la publicación de nuestro proyecto o bien intentemos consumir los servicios de dicho proyecto una vez publicados, podemos encontrarnos con algunos errores comunes como los de de a continuación.

Recordemos que la publicación de un proyecto se puede realizar desde el Explorador de soluciones de Visual Studio, pulsamos con el botón derecho en el proyecto y seleccionamos la opción Publicar o como alternativa seleccionando el proyecto y elegir Publicar {NOMBRE DEL PROYECTO} en el menú Compilar.

# ERROR: The remote certificate is invalid according to the validation procedure.

En caso de tener errores de publicación relativos a dicho problema, es necesario agregar manualmente la propiedad AllowUntrustedCertificate con un valor de True al perfil de publicación:

<PropertyGroup>
    ...
  <AllowUntrustedCertificate>True</AllowUntrustedCertificate>
</PropertyGroup>

# ERROR: HTTP 502.5 - Process Failure (IIS)

Si una vez publicado el servicio, al hacer una llamada, por ejemplo con Postman (opens new window), recibiéramos este error, añadiendo la siguiente propiedad al perfil de publicación, se solucionaría:

<PropertyGroup>
    ...
   <PublishWithAspNetCoreTargetManifest>false</PublishWithAspNetCoreTargetManifest>
</PropertyGroup>

# ERROR: HTTP 405 - Method Not Allowed (IIS)

https://stackoverflow.com/questions/48188895/asp-net-core-with-iis-http-verb-not-allowed (opens new window)

Básicamente es necesario añadir un fichero web.config con el siguiente contenido:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <modules>
        <remove name="WebDAVModule" />
      </modules>
      <handlers>
        <remove name="aspNetCore" />
        <remove name="WebDAV" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="TRACEVerbHandler" />
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
    </system.webServer>
  </location>
</configuration>

# ERROR: Web deployment task failed

https://go.microsoft.com/fwlink/?LinkId=221672#ERROR_DESTINATION_NOT_REACHABLE (opens new window)

El error se produce porque Web Management Service o Remote Agent no están instalados o arrancados en el servidor. La instalación de Manager Service se realiza agregando al servidor el rol Web Server (IIS)/Management Tool/Management Service. Una vez instalado, debemos reiniciar el IIS Manager y arrancar el Management Service a nivel de servidor.

# ERROR: Web deployment task failed

https://go.microsoft.com/fwlink/?LinkId=221672#ERROR_COULD_NOT_CONNECT_TO_REMOTESVC (opens new window)

Además de las soluciones propuestas por Microsoft, también cabe la posibilidad de que este error se produzca por haber instalado el Manager Service después de Web Deploy. En ese caso, debemos desinstalar y volver a instalar Web Deploy.

# ERROR: Could not connect to the remote computer

http://go.microsoft.com/fwlink/?LinkId=221672#ERROR_COULD_NOT_CONNECT_TO_REMOTES (opens new window)

Si las soluciones propuestas por Microsoft no son válidas, otra posible causa del error puede que esté en la restricción de direcciones IP del propio Management Service del IIS, cuyo valor debe ser Allow o indicar explícitamente las direcciones IP desde las cuales se realizará el despliegue.

# ERROR: Could not verify server's certificate

https://docs.microsoft.com/en-us/iis/publish/troubleshooting-web-deploy/web-deploy-error-codes#ERROR_CERTIFICATE_VALIDATION_FAILED (opens new window)

El error se produce porque de manera predeterminada el IIS usa el certificado auto firmado de Windows, el cual no está emitido por una entidad raíz de confianza.

# Solución 1 (usar un certificado válido)

Debemos seguir los siguientes pasos:

  1. Abrir el administrador de IIS (IIS Manager).
  2. En el árbol de conexiones, seleccionar la máquina.
  3. En el panel de características, abrir Management Service (se encuentra en el área Management).
  4. Paramos el servicio con el botón Stop.
  5. En el desplegable de SSL certificate seleccionamos el certificado que queremos usar.
  6. Volvemos a arrancar el servicio con el botón Start (aceptamos cuando nos pregunte si queremos guardar los cambios).

# Solución 2 (usar el certificado auto firmado)

Opción 2.1 (ASP.NET Core 3.0) "Publicación en un servidor mediante un certificado que no es de confianza" (opens new window)

Opción 2.2 (opens new window)

# Otros errores

https://docs.microsoft.com/en-us/iis/publish/troubleshooting-web-deploy/troubleshooting-web-deploy-problems-with-visual-studio (opens new window)