Despliegue de aplicaciones web con ASP.NET en una máquina virtual de Linux en Azure
Tags: dotnet, azure, linux, csharp
Published: 2021-09-06 19:17:18

Hola! Un gusto poder saludarte. En este nuevo artículo aprenderemos paso a paso a desplegar nuestras aplicaciones web con ASP.NET (con un proyecto de DotVVM como ejemplo) en una máquina virtual Ubuntu Server 20.04 bajo el concepto Infraestructura como Servicio en Microsoft Azure. 

Dadas estas consideraciones, estos son los puntos importantes que revisaremos en este artículo tutorial: 

+ Crear una máquina virtual con una distribución de Linux en Azure. 
+ Instalar el entorno de .NET y un servidor de Apache en la máquina virtual.
+ Publicar la aplicación web ASP.NET en Visual Studio 2019. 
+ Alojar la aplicación web en la máquina virtual.
+ Plus: Asociar una base de datos en la máquina virtual. 

##Parte 1: Crear una máquina virtual con una distribución de Linux en Azure

Para empezar, debemos disponer de una suscripción en Azure, si no disponemos de una cuenta podemos obtener una gratuita aquí: [https://azure.microsoft.com/es-es/free/](https://azure.microsoft.com/es-es/free/). 

Como primer paso, debemos dirigirnos al portal de Azure y buscar el recurso de Máquinas Virtuales y crear una nueva. En el proceso de creación tendremos varias partes importantes para la creación del recurso. A continuación, se detalla cada una de estas partes. 

####**Aspectos generales** 

Para empezar, es necesario especificar la suscripción y el grupo de recursos, luego los detalles de la instancia a crear. Aquí es donde definiremos el sistema operativo que tendrá la máquina virtual y el tamaño de la misma. Para nuestros objetivos, trabajaremos con Ubuntu Server 20.04. 

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

En cuanto al tamaño de la máquina virtual, todo dependerá de la cantidad de créditos de Azure que podamos destinar para la implementación de la aplicación y de la cantidad requerida de recursos. 

Luego debemos definir la información de la cuenta de administrador de la máquina virtual a través del nombre de usuario y la contraseña. Estos datos son muy importantes ya que nos permitirán acceder a la máquina virtual posteriormente. Para este propósito tenemos dos opciones, ya sea generar una *SSH Public Key*, o establecer una contraseña de acceso. Para este caso, seleccionaremos la opción de contraseña y tendremos algo como esto: 

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

Finalmente, en la sección general podemos definir reglas para los puertos de la máquina virtual. En este caso habilitaremos el puerto 80 para las conexiones HTTP que permitirán acceder a la página web desde el navegador de internet. El otro puerto es el SSH (22), el cual nos permitirá acceder a la máquina virtual de forma remota. 

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

####**Aspectos específicos**

Una vez especificados los aspectos generales se puede realizar la revisión general de los parámetros establecidos y crear el recurso. En otro escenario, también podemos especificar en detalle la configuración de los discos para la máquina virtual, ya sea de tipo SSD o HDD, la configuración de red y el balance de carga, la administración y el manejo de extensiones. 

Finalizadas estas configuraciones y una vez empezado el proceso de creación, esta operación tardara unos pocos minutos en ejecutarse. 

Con el recurso listo, ahora podemos dirigirnos a la sección principal del recurso en Azure y obtener la dirección de IP pública asignada a nuestra máquina virtual. 

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

De ser el caso, en la configuración de la IP pública podemos establecer que esta dirección IP sea estática, es decir, que la dirección no cambie al momento de reiniciar la máquina virtual. Por otro lado, también podemos establecer un DNS para esta dirección IP pública. 

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

##Parte 2: Instalar el entorno de .NET y un servidor de Apache en la máquina virtual

Ahora que ya tenemos la máquina virtual con Ubuntu Server 20.04 establecida en Azure, nos conectaremos de forma remota por medio del protocolo SSH (Secure SHell) a través de la consola de comandos. 

En este caso, ejecutaremos el siguiente comando con el nombre de usuario (establecido al momento de crear la máquina virtual en Azure), seguido de la dirección IP o del DNS:

```shell
ssh azureuser@40.77.109.26
```

Aquí deberemos introducir nuestras credenciales de acceso:

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

####**Instalación de .NET**

Muy bien, para comenzar instalaremos el SDK de .NET. La instalación con APT puede realizarse con unos pocos comandos. Antes de instalar .NET, debemos agregar la clave de la firma del paquete de Microsoft a la lista de claves de confianza y agregar el repositorio de paquetes.

```shell
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb

sudo dpkg -i packages-microsoft-prod.deb
```

Ahora bien, al instalar el SDK de .NET, no se necesita instalar el entorno de ejecución correspondiente. Para instalar el SDK de .NET, debemos ejecutar los siguientes comandos: 

```shell
sudo apt-get update
sudo apt-get install -y apt-transport-https
sudo apt-get update
sudo apt-get install -y dotnet-sdk-5.0
```

Con este proceso, ya tendremos .NET instalado en nuestra máquina virtual. Para realizar una verificación del SDK instalado, podemos introducir el siguiente comando:

```shell
dotnet --version
```

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

####**Instalación de Apache**

Para exponer nuestra aplicación a internet, necesitamos IIS (Internet Information Services), Nginx, o Apache como servidor proxy inverso que acepte la solicitud HTTP y reenvíe a Kestrel (servidor web que se incluye y habilita de forma predeterminada en las plantillas de proyecto de ASP.NET).
 
Dadas estas consideraciones, debemos introducir el siguiente comando para instalar Apache:

```shell
sudo apt-get install apache2
```

Considerando que el puerto 80 de la máquina virtual se encuentra abierto, ahora podemos copiar la IP pública o el DNS y ejecutarla en el navegador, si apache está instalado correctamente, podemos visualizar la página predeterminada de apache:

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

Ahora, debemos habilitar los módulos *modproxy* de Apache para que este pueda funcionar como un proxy inverso:

```console
systemctl restart apache2
a2enmod proxy proxy_http proxy_html
```

##Parte 3: Publicar la aplicación web con ASP.NET en Visual Studio 2019 

Hasta este punto, la máquina con Ubuntu Server 20.04 en Azure se encuentra con todos los componentes requeridos. A partir de este momento, iniciaremos con el proceso de despliegue de una aplicación web hacia la máquina virtual con .NET.

Para ejemplificar este escenario, desplegaremos una aplicación web con el framework DotVVM, basada en el patrón MVVM (Modelo, Vista, VistaModelo) sobre ASP.NET 5. 

Lo primero que haremos es dirigirnos a nuestra solución en Visual Studio 2019 para seleccionar el proyecto principal (en este caso con DotVVM) en .NET, y dar clic en el botón `Publish`:

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

En el cuadro de dialogo que se despliega, crearemos un nuevo perfil de publicación de tipo Folder, y especificaremos la ruta en donde queremos que nuestros archivos se desplieguen:

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

Finalmente, publicaremos nuestra solución desde el perfil creado:

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

Al terminar, nuestros archivos se habrán desplegado en la carpeta especificada previamente:

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

Estos archivos los utilizaremos en el siguiente paso dentro de la máquina virtual. 

##Parte 4: Alojar la aplicación web en la máquina virtual

####**Configurar el servidor de Apache**

Todos los archivos de configuración en Apache se almacenan en el directorio `/etc/apache2/conf-enabled`. De vuelta a nuestra máquina virtual a través de una conexión SSH, necesitaremos crear un archivo `.conf` para nuestra aplicación web. Esto lo podemos realizar al abrir el editor de texto nano de la siguiente manera:

```shell
sudo nano /etc/apache2/conf-enabled/DotNetApp.conf
```

***Nota:*** el nombre del archivo puede ser el que nosotros queramos especificar. 

En `DotNetApp.conf`, insertaremos el siguiente contenido:

```html
<VirtualHost *:80>  
   ProxyPreserveHost On  
   ProxyPass / http://127.0.0.1:5000/  
   ProxyPassReverse / http://127.0.0.1:5000/  
   ErrorLog /var/log/apache2/DotNetApp-error.log  
   CustomLog /var/log/apache2/DotNetApp-access.log common  
</VirtualHost>
```

En .NET, las aplicaciones web por la consola de comandos se ejecutan por defecto en el puerto 5000, en caso de que quisiéramos que nuestra aplicación se ejecute en otro puerto, podemos especificar el puerto de ejecución en el `webBuilder` dentro de la clase `Program.cs` de nuestro proyecto de la siguiente manera:

```csharp
.UseUrls("http://*:8080")
```

Asimismo, en el archivo de configuración `DotNetApp.conf` estamos indicando que nuestra aplicación podrá ser accedida desde el puerto 80. De ser el caso, podríamos cambiar el puerto, sin embargo, es importante recordar habilitar el puerto en cuestión desde los ajustes de la máquina virtual en Azure. 

####**Copiar los archivos de la aplicación en la máquina virtual**

Lo que nos toca hacer ahora es configurar nuestra aplicación web para que pueda ser accedida desde el puerto 80. En este sentido, lo que realizaremos en este momento es copiar los archivos desplegados previamente en Visual Studio 2019 hacia la máquina virtual. Esto lo realizaremos desde el directorio `/var/`:

```shell
cd /var/
sudo mkdir DotNetApp
```

Ahora, deberemos realizar la transferencia de archivos. Desde Windows, podemos utilizar el programa *WinSCP* para conectarnos con la máquina virtual y realizar este proceso. 

***Instalador de WinSCP:*** [https://winscp.net/eng/download.php](https://winscp.net/eng/download.php).

Una vez instalado *WinSCP* e inicializado, crearemos una nueva sesión con las credenciales de nuestra máquina virtual de Azure:

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

Con esta conexión, en el usuario por defecto podemos crear una nueva carpeta, por ejemplo, App, y en ella copiar los archivos de nuestra aplicación:

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

Ahora todos los archivos se han cargado en la máquina virtual, en el siguiente paso necesitamos mover los archivos del directorio `/home/azureuser/App` al directorio `/var/DotNetApp`:

```shell
cd /home/azureuser/App
sudo cp -R * /var/DotNetApp/
```

Con este proceso, nuestra aplicación web ya se encuentra alojada en la máquina virtual como tal: 

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

####**Creación de un servicio para iniciar y supervisar la aplicación web.**

Para crear este archivo de servicio que permitirá poner en ejecución nuestra aplicación web, abriremos el editor nano:

```shell
sudo nano /etc/systemd/system/kestrel-DotNetApp.service
```

En este archivo agregaremos el siguiente contenido para proporcionar el directorio de trabajo y qué archivo se debe ejecutar para poner en funcionamiento la aplicación web.

```conf
[Unit]  
Description=Aspnet 5 Web App running on Ubuntu  
[Service]  
WorkingDirectory=/var/DotNetApp  
ExecStart=/usr/bin/dotnet /var/DotNetApp/UserDashboard.dll  
Restart=always  
RestartSec=10  
SyslogIdentifier=dotnet-demo  
User=www-data  
Environment=ASPNETCORE_ENVIRONMENT=Production  
[Install]  
WantedBy=multi-user.target  
```

Ahora, habilitaremos e iniciaremos el servicio creado:

```shell
sudo systemctl enable kestrel-DotNetApp.service  
sudo systemctl start kestrel-DotNetApp.service
```

Con el atributo *status* podemos verificar el estado del servicio: 

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

Finalmente podemos reiniciar el servidor de Apache y ver que nuestra aplicación se encuentra ejecutándose desde el puerto 80 también:

```shell
systemctl restart apache2 
sudo service apache2 restart
```

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

Ahora que el alojamiento y todas las configuraciones correspondientes se han realizado, ya podemos acceder al navegador usando la IP pública asignada, o el nombre del DNS, y ver a nuestra aplicación web ASP.NET con DotVVM ejecutándose correctamente sobre la máquina virtual con Linux sobre Azure. 

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

##Plus: Asociar una base de datos en la máquina virtual 

Hasta este punto ya hemos desplegado nuestra aplicación, sin embargo, la mayoría de los proyectos web (por no decir todos), se encuentran asociados a una base de datos. En este caso, veamos un ejemplo sobre como instalar una base de datos PostgreSQL dentro de la máquina virtual, y asociarlo a nuestro proyecto con DotVVM en ASP.NET 5. 

Para instalar PostgreSQL escribiremos el siguiente comando: 

```shell
sudo apt install postgresql postgresql-contrib
```

Luego, es necesario dentro de la configuración de la máquina virtual en Azure habilitar el puerto 5432 para acceder a PostgreSQL de manera remota. 

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

Ahora, en Ubuntu Server debemos modificar el archivo `pg_hba.conf` para permitir conexiones a PostgreSQL de manera remota: 

```shell
sudo nano /etc/postgresql/12/main/pg_hba.conf
```

Dentro del archivo `pg_hba.conf`, en la sección *IPv4 local connections* dejaremos la sentencia correspondiente de esta manera:

```conf
# IPv4 local connections:
host    all             all             all            md5
```
El último archivo que deberemos modificar se llama: `postgresql.conf`. Esta configuración servirá para establecer las direcciones IP que se pueden conectar a PostgreSQL de manera remota:

```shell
sudo nano /etc/postgresql/12/main/postgresql.conf
```

En la sección *Connections and Authentication* quitaremos el símbolo # y nos quedaremos con la siguiente sentencia:

```conf
listen_addresses = '*'
```

Finalmente debemos reiniciar el servicio de la base de datos:

```shell
sudo service postgresql restart
```

Con estas configuraciones ya podemos establecer un usuario para acceder a la base de datos, este podría ser un ejemplo:

```console
sudo -u postgres psql

CREATE USER admin PASSWORD 'Abc#1234'
ALTER ROLE admin WITH SUPERUSER;
```

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

Luego, ya solo nos queda realizar las configuraciones correspondientes en nuestra base de datos. Para ello podemos conectarnos de manera remota con el usuario que acabamos de crear:

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

Finalmente, de acuerdo con nuestro ejemplo, en la aplicación web deberíamos establecer esta nueva conexión con la base de datos. 

```
host=localhost;port=5432;Username=admin;Password=Abc#1234;Database=postgres
```

Para reflejar estos cambios en producción, debemos reemplazar los archivos o el archivo con la nueva configuración en `/var/DotNetApp`, y reiniciar los servicios asociados (*Kestrel* y *Apache*). 

###¿Qué sigue? 

Con este articulo hemos todo paso a paso como desplegar una aplicación web con ASP.NET 5 y DotVVM desde Visual Studio 2019 a una máquina virtual con Ubuntu Server 20.04 en Azure. A continuación, se encuentran recursos adicionales para que puedas seguir aprendiendo sobre el desarrollo de aplicaciones con .NET y con Azure: 

+ [Despliegue de aplicaciones web ASP.NET a través de una máquina virtual con Windows Server en Azure](https://dev.to/esdanielgomez/despliegue-de-aplicaciones-web-asp-net-core-y-dotvvm-a-traves-de-una-maquina-virtual-en-azure-4g6).

+ [.NET 5: Despliegue de aplicaciones web con Azure App Service](https://dev.to/esdanielgomez/net-5-despliegue-de-aplicaciones-web-con-azure-app-service-3i18).

+ [Construyendo un Dashboard con ASP.NET Core y DotVVM](https://dev.to/esdanielgomez/construyendo-un-dashboard-con-asp-net-core-y-dotvvm-geh).

###Gracias por leer

Muchas gracias por leer, espero que este artículo te haya parecido interesante y pueda serte de utilidad en el futuro. Si tienes alguna pregunta o alguna idea que necesites discutir, será un gusto poder colaborarte y juntos intercambiar conocimientos entre sí.

¡Nos vemos en [Twitter](https://twitter.com/esDanielGomez)! O si gustas también puedes escribirme por [Instagram](https://instagram.com/esdanielgomez) o [Telegram](https://t.me/esdanielgomez). :=)