Desplegando una Web App de .Net Core con Docker y Azure Pipelines (I)
Tags: azure, docker, netcore, webapp
Published: 2022-08-13 01:14:00

Hace unos días empecé a probar Docker con proyectos desarrollados en .Net y desplegarlos en servicios de Azure, para lo cual me encontré con dos situaciones: la primera es la escasa documentación que existe o se encuentra desactualizada; y la segunda es que el proceso es relativamente sencillo.
Por lo cual decidí que lo mejor será compartir mi experiencia en este proceso; así que manos a la obra.
Primero creamos un proyecto de ASP.NET Core Web App:

![Image1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egmodlo2lnk5i7jzv4ax.png)

Colocamos el nombre de nuestro proyecto:
![Image2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iv0omi38ktvy3j4xi0ah.png)

Seleccionamos la opción de **Enable Docker** y seleccionamos el SO como **Linux**

![Image3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oj2e3qwr6mdg4pmdluxn.png)

Una vez que termino de crear el proyecto podemos notar que por default el target de la compilación se cambió a **Docker **😱. Por el momento vamos a cambiar este target al nombre de nuestro proyecto; en mi caso **WebAppDocker**. 

![Image4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vtzcomt4qrqrn1zwceoq.png)

Otro cambio que se puede observar es que a nuestro proyecto le agrego un archivo **Dockerfile**; el cual contiene la configuración para Docker el cual analizaremos más adelante. Por el momento revisamos que nuestro proyecto funcione correctamente sin utilizar Docker.

![Image5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xr7gslasoa0ifttskhm.png)

Una vez que nos cercioramos de que nuestra aplicación funciona correctamente continuemos con probar esta funcionalidad, pero ahora dentro de nuestro contenedor de Docker. Antes de continuar te preguntarás y si es un proyecto existente como hago para que se ejecute en un Docker Container; con Visual Studio es relativamente fácil para esto: Dar click derecho sobre el nombre del proyecto -> Add -> Docker Support

![Image6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wpbi1nnh7nt17i609xr.png)

Seleccionamos el Target OS: Linux

![Image7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi9bjiub424k8jcbvbl9.png)

Esto nos genera el archivo Dockerfile adecuado para nuestro proyecto.

Ahora si ejecutamos el proyecto con el Target: Docker

![Image8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oode54kyw6n4vwgxebfm.png)

Como podemos observar dentro del Visual Studio tenemos una herramienta para visualizar los contenedores, en la cual tenemos la misma funcionalidad que se tiene dentro de Docker Desktop.

![Image9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85h4s1grnyu9zcospns6.png)

Al ejecutar nuestro proyecto en VS podemos observar que se crea la imagen y a su vez se ejecuta el contenedor, lo cual en otro escenario significaría que con esta imagen ya podemos levantar nuestro contenedor dentro de Azure; lamentablemente para mi sorpresa esto no es así ya que por alguna extraña razón al detener el proceso de debug en el VS ya no se ejecuta la aplicación correctamente 🤔🤔. Para entender la razón del porque la app corriendo en el contenedor ya no funciona, aunque el proceso esta corriendo en Docker y no marca ningún error; revise los pasos que realiza el Visual Studio para compilar, empaquetar y publicar el proyecto. Esta información la podemos revisar en la terminal de Salida del VS.

![Image10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hq8i9j3am0g2u3yus0uu.png)
 
Al revisar el comando docker build solo recibe los parámetros del archivo Dockerfile a construir,  --force-rm -t para borrar la imagen existente y labels, así que descartamos el problema en la construcción de la imagen de Docker.
```powershell
docker build -f "C:\Users\vicos\CursoDocker\WebAppDocker\WebAppDocker\WebAppDocker\Dockerfile" --force-rm -t webappdocker  --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=WebAppDocker" "C:\Users\vicos\CursoDocker\WebAppDocker\WebAppDocker"
```
El siguiente paso es revisar hasta el final del log aparece el comando docker run.
```powershell
docker run -dt -v "C:\Users\vicos\vsdbg\vs2017u5:/remote_debugger:rw" -v "C:\Users\vicos\AppData\Roaming\Microsoft\UserSecrets:/root/.microsoft/usersecrets:ro" -v "C:\Users\vicos\AppData\Roaming\ASP.NET\Https:/root/.aspnet/https:ro" -e "ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS=true" -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=https://+:443;http://+:80" -P --name WebAppDocker --entrypoint tail webappdocke1r -f /dev/null

```

En los parámetros que recibe este comando si observamos algunos parámetros adicionales, empezando con el parámetro -v "C:\Users\vicos\vsdbg\vs2017u5:/remote_debugger:rw" este parámetro monta un volumen hacia el debugger lo cual no es necesario para la ejecución en productivo de nuestra WebApp en Docker. 
Los siguientes dos parámetros son utilizados por el Web Server para definir el certificado https que se va a utilizar, como podemos visualizar se referencian hacia una ruta local del equipo de desarrollo lo cual en un ambiente de producción no tendremos acceso a estas carpetas. Para agregar al contenedor el certificado hay que modificar nuestro proyecto.
Dentro del explorador de Windows nos ubicamos en la carpeta **_%USERPROFILE%\AppData\Roaming\ASP.NET\Https_** en la cual encontraremos el certificado para nuestro proyecto. 

![Image11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ahpo1yillb7bg29sxtd9.png)
 
Este archivo lo copiamos y lo colocamos dentro de nuestro proyecto. 

![Image12](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5wau6myw51tygciwrugt.png)

Damos click derecho ->  propiedades (Alt + Enter)

![Image13](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfhoi7jot6xpofr40af8.png)

En la propiedad de “Copy to Output Directory” seleccionamos la opción “Copy Always”

![Image14](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/69mkoelpet0pd542lemh.png)
 
Abrimos el archivo Appsettings.json y agregamos lo siguiente
```json
"Kestrel": {
    "Certificates": {
      "Default": {
        "Path": "WebAppDocker.pfx",
        "Password": "f9503e4f-0cd7-4630-b752-4d41df791f69"
      }
    }
  }
```

Una ves realizado estos cambios continuamos al siguiente parámetro que no es necesario que se proporcione al comando docker run. **-e "ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS=true"** este parámetro es opcional ya que solo deshabilita los colores en la consola del log. 
Los siguientes dos parámetros **ENVIRONMENT** y **URLS **si son necesarios por lo cual los dejaremos dentro de nuestro script de ejecución, junto con el parámetro -P que nos permite publicar los puertos expuestos hacia puertos aleatorios; esto lo cambiaremos más adelante cuando publiquemos nuestra imagen de docker hacia un servicio de Azure.
Despues viene el nombre de nuestro container y en teoría debería ir el nombre de la imagen que deseamos ejecutar pero en el comando que ejecuta VS sobrecarga el entrypoint por un** tail webappdocker:dev -f /dev/null**, lo cual no es necesario para nuestro ambiente en ejecución. 
Con estos cambios nuestro comando docker run quedaría de la siguiente manera:
```powershell
docker run -e "ASPNETCORE_ENVIRONMENT=Development" -e "ASPNETCORE_URLS=https://+:443;http://+:80" -P --name WebAppDocker webappdocker
```

Con esto comprobamos que efectivamente nuestra aplicación se encuentre levantada dentro del container. 
 
![Image15](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkxsc7k7993pivwbaw97.png)
 
![Image16](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2mdwvcexngpty8qcbus.png)

![Image17](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bo9yc0374rc0dt8f2hz.png)

Como podemos observar nuestra WebApp se encuentra ejecutándose correctamente dentro del container de docker y tenemos nuestra aplicación lista para ser desplegada dentro de nuestro servicio de Azure.

En la siguiente parte crearemos los Pipelines de Azure para su compilación y despliegue hacia el servicio de Azure. 

Los espero para la próxima, ¡mis mejores deseos, salud y éxitos!