Inicio rápido: uso de Docker con una aplicación de página única de React en Visual Studio
Con Visual Studio, es muy fácil compilar, depurar y ejecutar aplicaciones ASP.NET Core en contenedores, incluidas aquellas con JavaScript en el lado cliente como una aplicación de página única (SPA) de React.js y publicarlas en Azure Container Registry, Docker Hub, Azure App Service o en su propio registro de contenedor. En este artículo, publicaremos en Azure Container Registry.
Requisitos previos
- Docker Desktop
- Visual Studio 2019 con las cargas de trabajo Desarrollo web, Azure Tools o Desarrollo multiplataforma de .NET Core instaladas
- Herramientas de desarrollo de .NET Core 3.1 para el desarrollo con .NET Core 3.1.
- Para publicar en Azure Container Registry, una suscripción de Azure. Regístrese para obtener una evaluación gratuita.
- Node.js
- Para contenedores de Windows, Windows 10 versión 1809 o posterior, para usar las imágenes de Docker a las que se hace referencia en este artículo.
- Docker Desktop
- Visual Studio 2022 con las cargas de trabajo Desarrollo web, Azure Tools o Desarrollo multiplataforma de .NET Core instaladas
- Para publicar en Azure Container Registry, una suscripción de Azure. Regístrese para obtener una evaluación gratuita.
- Node.js
- Para contenedores de Windows, Windows 10 versión 1809 o posterior, para usar las imágenes de Docker a las que se hace referencia en este artículo.
Instalación y configuración
Para instalar Docker, primero revise la información de Docker Desktop for Windows: What to know before you install (Docker Desktop para Windows: información previa a la instalación). Después, instale Docker Desktop.
Creación de un proyecto y adición de compatibilidad con Docker
Cree un nuevo proyecto con la plantilla ASP.NET Core con React.js.
En la pantalla Información adicional, no puede seleccionar Habilitar compatibilidad con Docker, pero no se preocupe, puede agregar esa compatibilidad más adelante.
Haga clic derecho en el nodo del proyecto y elija Agregar>Compatibilidad con Docker para agregar un archivo Dockerfile al proyecto.
Seleccione el tipo de contenedor.
El siguiente paso es diferente en función de si usa contenedores de Linux o contenedores de Windows.
Nota:
Si usa las plantillas de proyecto más recientes en Visual Studio 2022 o versiones posteriores, no es necesario modificar el Dockerfile.
Modificación de Dockerfile (contenedores de Linux)
Se agrega al proyecto un Dockerfile, la receta para crear una imagen de Docker final. Vea Dockerfile reference (Referencia de Dockerfile) para obtener una descripción de los comandos que contiene.
El Dockerfile predeterminado usa una imagen base para ejecutar el contenedor, pero cuando también desea poder ejecutar una aplicación Node.js en él, debe instalar Node.js, lo que significa agregar algunos comandos de instalación en un par de lugares en el Dockerfile. Los comandos de instalación requieren permisos elevados, ya que los cambios afectan a los archivos y carpetas del sistema con privilegios del contenedor.
Si la casilla Configurar para HTTPS del cuadro de diálogo del nuevo proyecto está marcada, Dockerfile expondrá dos puertos. Uno se utiliza para el tráfico HTTP, mientras que el otro se emplea para HTTPS. Si la casilla no está activada, se expone un único puerto (80) para el tráfico HTTP.
Si tiene como destino .NET 8 o versión posterior, el Dockerfile predeterminado que crea Visual Studio usa la cuenta de usuario normal (busque la línea USER app
), pero esa cuenta no tiene los permisos elevados necesarios para instalar Node.js. Para tener en cuenta esta situación, haga lo siguiente:
- En Dockerfile, elimine la línea
USER app
. - Cambie los puertos que están expuestos en la primera sección del Dockerfile para que el puerto 80 sea para solicitudes HTTP y (si eligió admitir HTTPS cuando creó el proyecto) 443 para solicitudes HTTPS.
- Edite
launchSettings.json
para cambiar las referencias de puerto a 80 y 443. Reemplace 8080 por 80 para HTTP y 8081 por 443 para HTTPS.
Para todas las versiones de .NET, siga estos pasos para actualizar el Dockerfile para instalar Node.js:
- Agregue las líneas siguientes para instalar curl, Node.js 14.x y determinadas bibliotecas de Node requeridas en el contenedor. No olvide agregar estas dos líneas en la primera sección, para agregar la instalación del administrador de paquetes de Node
npm.exe
a la imagen base, así como a la secciónbuild
.
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
El archivo Dockerfile debería tener ahora un aspecto similar al siguiente:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
WORKDIR /src
COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
COPY . .
WORKDIR "/src/ProjectSPA1"
RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
El elemento Dockerfile anterior se basa en la imagen mcr.microsoft.com/dotnet/core/aspnet e incluye instrucciones para modificar la imagen base mediante la creación del proyecto y su incorporación al contenedor.
Modificación de Dockerfile (contenedores de Windows)
Abra el archivo de proyecto; para ello, haga doble clic en el nodo del proyecto y actualice el archivo de proyecto (*.csproj) agregando la siguiente propiedad como elemento secundario del elemento <PropertyGroup>
:
<DockerfileFastModeStage>base</DockerfileFastModeStage>
Nota:
El cambio a DockerfileFastModeStage es necesario, ya que el Dockerfile aquí agrega una fase al principio del Dockerfile. Para optimizar el rendimiento, Visual Studio usa el Modo rápido, pero solo funciona si se usa la fase correcta. El valor predeterminado es la primera fase del Dockerfile, que en este ejemplo, se cambia de base
a otra cosa para descargar Node.js. Para obtener más información sobre el Modo rápido, consulte Personalizar contenedores de Docker en Visual Studio.
Actualice Dockerfile agregando las líneas siguientes. Estas líneas copiarán Node y "npm" en el contenedor.
Agregue
# escape=`
a la primera línea de DockerfileAgregue las líneas siguientes delante de
FROM ... base
FROM mcr.microsoft.com/powershell AS downloadnodejs ENV NODE_VERSION=14.16.0 SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"] RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; ` Expand-Archive nodejs.zip -DestinationPath C:\; ` Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs
Agregue la línea siguiente delante y después de
FROM ... build
COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
El archivo Dockerfile completo debería tener ahora un aspecto similar al siguiente:
# escape=` #Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed. #For more information, please see https://aka.ms/containercompat FROM mcr.microsoft.com/powershell AS downloadnodejs ENV NODE_VERSION=14.16.0 SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"] RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; \ Expand-Archive nodejs.zip -DestinationPath C:\; \ Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 COPY --from=downloadnodejs C:\\nodejs C:\\Windows\\system32 FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build COPY --from=downloadnodejs C:\\nodejs C:\\Windows\\system32 WORKDIR /src COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"] RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj" COPY . . WORKDIR "/src/ProjectSPA1" RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
Actualice el archivo
.dockerignore
quitando el**/bin
.
Siga estos pasos si usa Visual Studio 2022, versión 17.8 o posterior:
Cree un nuevo proyecto con la plantilla React y ASP.NET Core.
En la pantalla Información adicional, seleccione Habilitar compatibilidad con contenedores. Asegúrese de seleccionar la opción Dockerfile, ya que deberá realizar cambios manualmente en ese archivo.
Nota:
En algunas versiones de Visual Studio 2022, esta opción no está habilitada, pero puede agregar esa compatibilidad más adelante.
Visual Studio crea dos proyectos: uno para el código cliente React JavaScript y otro para el código de servidor ASP.NET Core C#.
Si no ha agregado compatibilidad con contenedores de Docker durante la creación del proyecto, haga clic con el botón derecho en el nodo del proyecto de servidor y elija Agregar>compatibilidad con Docker y asegúrese de elegir la opción Dockerfile para crear un Dockerfile.
Seleccione el tipo de contenedor.
Siga estos pasos para Visual Studio 2022 versión 17.0 a 17.7:
Cree un nuevo proyecto con la plantilla ASP.NET Core con React.js.
En la pantalla Información adicional, no puede seleccionar Habilitar compatibilidad con Docker, pero no se preocupe, puede agregar esa compatibilidad más adelante.
Haga clic derecho en el nodo del proyecto y elija Agregar>Compatibilidad con Docker para agregar un archivo Dockerfile al proyecto.
Seleccione el tipo de contenedor.
Depurar
Con Visual Studio 2022 versión 17.9 o posterior y la plantilla React y ASP.NET Core que usa vite.js
, los proyectos ya están configurados para iniciar los proyectos de cliente y servidor con compatibilidad de depuración, pero debe configurar el puerto correcto para que el proxy de aplicación de página única (SPA) lo use para acceder al servidor Core ASP.NET que se ejecuta en el contenedor. Puede obtener el puerto de host desde la ventana Contenedores de Visual Studio y establecerlo en el proyecto de React, tal como se describe en Creación de una aplicación React: Docker.
También puede deshabilitar el inicio en el explorador para el servidor, que está configurado para abrirse con Swagger, que no es necesario para este escenario. Para deshabilitar el inicio del explorador, abra las Propiedades (Alt+Entrar), vaya a la pestaña Depurar y haga clic en el vínculo Abrir interfaz de usuario de perfiles de inicio de depuración y desactive la casilla Iniciar explorador.
Si usa una versión anterior de Visual Studio 2022, siga leyendo para configurar la depuración con el servidor proxy de aplicación de página única (SPA).
El proyecto usa el proxy SPA durante la depuración. Consulte Plantillas de aplicación de página única (SPA) mejoradas. Al depurar, el cliente de JavaScript se ejecuta en el equipo host, pero el código del servidor ASP.NET Core se ejecuta en el contenedor. Cuando se publica, el proxy no se ejecuta y el código de cliente se ejecuta en el mismo servidor que el código de ASP.NET Core. Ya tiene un perfil de depuración *Docker que puede usar para depurar el código del servidor. Para depurar el código de cliente de JavaScript, puede crear un perfil de depuración adicional. También tendrá que iniciar el proxy manualmente desde un símbolo del sistema al depurar JavaScript. Puede dejarlo en ejecución a través de varias sesiones de depuración.
Compile el proyecto, si aún no está compilado.
Abra un símbolo del sistema de desarrollador de Visual Studio, vaya a la carpeta ClientApp del proyecto y ejecute el comando
npm run start
. Deberíamos ver algo parecido a lo siguiente:Compiled successfully! You can now view project3_spa in the browser. Local: https://localhost:44407 On Your Network: https://192.168.1.5:44407 Note that the development build isn't optimized. To create a production build, use npm run build. webpack compiled successfully
Nota:
Anote la dirección URL local. Deberá proporcionarla en un perfil de inicio de depuración, que se almacena en el archivo
launchSettings.json
.Abra la lista desplegable que contiene perfiles de depuración (junto al icono de triángulo verde o el botón Iniciar) y elija Propiedades de depuración de {ProjectName} y, luego, seleccione el perfil de Docker.
Compruebe la sección Variables de entorno y agregue las siguientes variables de entorno si aún no están presentes:
ASPNETCORE_ENVIRONMENT=Development,ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=Microsoft.AspNetCore.SpaProxy
Establezca la dirección URL en
https://localhost:{proxy-port}
, donde{proxy-port}
es el puerto del servidor proxy (del paso 1).Esta acción cambia la entrada de Docker en el archivo
launchSettings.json
e inicia la dirección URL correcta para el proxy local que se ejecuta en el host. Encuentre el archivolaunchSettings.json
en el Explorador de soluciones en la sección Propiedades.Debería ver algo parecido al siguiente código:
"profiles": { "Docker": { "commandName": "Docker", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" }, "launchUrl": "https://localhost:44407", "useSSL": true } }
Importante
No establezca la opción de configuración de inicio
publishAllPorts
entrue
si usa un proxy. Esa opción publica todos los puertos expuestos en un puerto aleatorio, que no funcionará cuando establezca un puerto específico en el proxy SPA.Abra el archivo ClientApp/src/setupProxy.js y cambie la línea que establece el destino para usar la dirección y el puerto
localhost
en el contenedor. Puede encontrar el puerto en la pestaña Puertos de la ventana Contenedores.const target = 'https://localhost:{container-port}';
Si usa HTTPS, asegúrese de elegir el puerto adecuado para HTTPS, que es 443 en este tutorial.
Inicie la aplicación con depuración (F5).
Si recibe un error de compilación al intentar escribir los ensamblados de salida, es posible que tenga que detener un contenedor en ejecución previamente para desbloquear los archivos.
Compruebe que puede alcanzar un punto de interrupción en el código de JavaScript del lado cliente estableciendo un punto de interrupción en ClientApp/src/components/Counter.js en la función incrementCounter y, a continuación, intente alcanzar el punto de interrupción haciendo clic en el botón Incrementar de la página Contadores.
A continuación, intente alcanzar un punto de interrupción en el código de ASP.NET Core del lado servidor. Establezca un punto de interrupción en
WeatherController.cs
en el métodoGet
e intente anexar/weatherforecast
allocalhost
base y a la dirección URL del puerto para activar ese código.Si el puerto del contenedor cambia, lo que puede ocurrir si realiza un cambio significativo, como actualizar
launchSettings.json
o actualizar el perfil de inicio de depuración en el IDE, deberá actualizar el puerto ensetupProxy.js
y reiniciar también el proxy. Finalice el proxy actual (Ctrl+C en la ventana de comandos donde se está ejecutando) y, a continuación, reinícielo con el mismo comandonpm run start
.
Seleccione Docker en la lista desplegable de depuración de la barra de herramientas y empiece a depurar la aplicación. Es posible que vea un mensaje que pregunte sobre cómo confiar en un certificado; elija la opción de confiar en el certificado para continuar. La primera vez que compila, Docker descarga las imágenes base, por lo que puede tardar un poco más.
La opción Herramientas de contenedor de la ventana Salida muestra las acciones que están teniendo lugar. Debería ver los pasos de instalación asociados con npm.exe.
El explorador muestra la página principal de la aplicación.
Ventana Contenedores
Abra la ventana de herramientas Contenedores. Puede encontrarla en el menú en Ver>Otras ventanas>Contenedores, o presione Ctrl+Q y empiece a escribir containers
en el cuadro de búsqueda. A continuación, elija la ventana Contenedores en los resultados. Cuando se abra la ventana, acóplela en la parte inferior bajo el panel del editor.
La ventana Contenedores muestra los contenedores en ejecución y le permite ver información sobre ellos. Puede ver las variables de entorno, las etiquetas, los puertos, los volúmenes, el sistema de archivos y los registros. Los botones de la barra de herramientas permiten crear un terminal (símbolo del sistema del shell) dentro del contenedor, adjuntar el depurador o eliminar contenedores no usados. Consulte Uso de la ventana Contenedores.
Haga clic en la pestaña Archivos y expanda la carpeta app
para ver los archivos de aplicación publicados.
También puede ver las imágenes e inspeccionar información sobre ellas. Elija la pestaña Imágenes, busque la del proyecto y, a continuación, elija la pestaña Detalles para ver un archivo JSON que contiene información sobre una imagen.
Nota
La imagen dev no contiene los archivos binarios de la aplicación ni otro contenido, ya que las configuraciones de Depurar usan el montaje de volumen para proporcionar la experiencia de depuración y edición iterativa. Para crear una imagen de producción que contenga todo el contenido, use la configuración de Liberar.
Publicar imágenes de Docker
Una vez completado el ciclo de desarrollo y depuración de la aplicación, puede crear una imagen de producción de la aplicación.
Cambie la lista desplegable de configuración a Versión y compile la aplicación.
Haga clic con el botón derecho en el Explorador de soluciones y elija Publicar.
En el cuadro de diálogo de destino de publicación, seleccione Container Registry para Docker.
Después, elija Azure Container Registry.
Elija Crear una instancia de Azure Container Registry.
Rellene los valores deseados en la pantalla Crear una instancia de Azure Container Registry.
Parámetro Valor sugerido Descripción Prefijo de DNS Nombre único globalmente Nombre que identifica de forma única el nuevo registro de contenedor. Suscripción Elija una suscripción La suscripción de Azure que se va a usar. Grupo de recursos myResourceGroup Nombre del grupo de recursos en el que se va a crear el registro de contenedor. Elija Nuevo para crear un grupo de recursos nuevo. SKU Estándar Nivel de servicio del registro de contenedor Ubicación del registro Una ubicación cercana a usted Elija una ubicación en una región cercana a usted o a otros servicios usen el registro de contenedor. Seleccione Crear y, después, Finalizar.
Una vez finalizado el proceso de publicación, puede revisar la configuración de publicación y editarla, si es necesario, o bien volver a publicar la imagen con el botón Publicar.
Para volver a empezar mediante el cuadro de diálogo Publicar, elimine el perfil de publicación mediante el vínculo Eliminar de esta página y, después, vuelva a seleccionar Publicar.
Cambie la lista desplegable de configuración a Versión y compile la aplicación.
Haga clic con el botón derecho en el Explorador de soluciones y elija Publicar.
En el cuadro de diálogo de destino de publicación, seleccione Container Registry para Docker.
Después, elija Azure Container Registry.
Elija Crear una instancia de Azure Container Registry.
Rellene los valores deseados en la pantalla Crear una instancia de Azure Container Registry.
Parámetro Valor sugerido Descripción Prefijo de DNS Nombre único globalmente Nombre que identifica de forma única el nuevo registro de contenedor. Suscripción Elija una suscripción La suscripción de Azure que se va a usar. Grupo de recursos myResourceGroup Nombre del grupo de recursos en el que se va a crear el registro de contenedor. Elija Nuevo para crear un grupo de recursos nuevo. SKU Estándar Nivel de servicio del registro de contenedor Ubicación del registro Una ubicación cercana a usted Elija una ubicación en una región cercana a usted o a otros servicios usen el registro de contenedor. Seleccione Crear y, después, Finalizar.
Una vez finalizado el proceso de publicación, puede revisar la configuración de publicación y editarla, si es necesario, o bien volver a publicar la imagen con el botón Publicar.
Para volver a empezar mediante el cuadro de diálogo Publicar, elimine el perfil de publicación mediante el vínculo Eliminar de esta página y, después, vuelva a seleccionar Publicar.
Pasos siguientes
Ahora puede extraer el contenedor del registro a cualquier host capaz de ejecutar imágenes de Docker, por ejemplo Azure Container Instances.
Recursos adicionales
- Desarrollo de contenedores con Visual Studio
- Troubleshoot Visual Studio development with Docker (Solución de problemas de desarrollo de Visual Studio con Docker)
- Visual Studio Container Tools GitHub repository (Repositorio de GitHub de herramientas de contenedor de Visual Studio)