Skip to content

Commit 7777ba3

Browse files
Merge pull request #10322 from ghogen/create-react-spa-aug
React with container: update debug steps
2 parents 8093c67 + 1def13f commit 7777ba3

File tree

5 files changed

+109
-84
lines changed

5 files changed

+109
-84
lines changed

docs/containers/container-tools-react.md

Lines changed: 109 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ms.custom: SEO-VS-2020
55
author: ghogen
66
description: Learn how to create a containerized React SPA app with Visual Studio Container Tools and Docker
77
ms.author: ghogen
8-
ms.date: 10/25/2021
8+
ms.date: 08/25/2022
99
ms.technology: vs-container-tools
1010
ms.topic: quickstart
1111
---
@@ -40,7 +40,6 @@ For Docker installation, first review the information at [Docker Desktop for Win
4040

4141
## Create a project and add Docker support
4242

43-
4443
::: moniker range="vs-2019"
4544

4645
1. Create a new project using the **ASP.NET Core with React.js** template.
@@ -114,19 +113,19 @@ RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1
114113
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
115114
RUN apt-get install -y nodejs
116115
WORKDIR /src
117-
COPY ["ReactSPA/ReactSPA.csproj", "ReactSPA/"]
118-
RUN dotnet restore "ReactSPA/ReactSPA.csproj"
116+
COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
117+
RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
119118
COPY . .
120-
WORKDIR "/src/ReactSPA"
121-
RUN dotnet build "ReactSPA.csproj" -c Release -o /app/build
119+
WORKDIR "/src/ProjectSPA1"
120+
RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build
122121

123122
FROM build AS publish
124-
RUN dotnet publish "ReactSPA.csproj" -c Release -o /app/publish
123+
RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish
125124

126125
FROM base AS final
127126
WORKDIR /app
128127
COPY --from=publish /app/publish .
129-
ENTRYPOINT ["dotnet", "ReactSPA.dll"]
128+
ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
130129
```
131130

132131
:::moniker-end
@@ -152,19 +151,19 @@ RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1
152151
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
153152
RUN apt-get install -y nodejs
154153
WORKDIR /src
155-
COPY ["ReactSPA/ReactSPA.csproj", "ReactSPA/"]
156-
RUN dotnet restore "ReactSPA/ReactSPA.csproj"
154+
COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
155+
RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
157156
COPY . .
158-
WORKDIR "/src/ReactSPA"
159-
RUN dotnet build "ReactSPA.csproj" -c Release -o /app/build
157+
WORKDIR "/src/ProjectSPA1"
158+
RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build
160159

161160
FROM build AS publish
162-
RUN dotnet publish "ReactSPA.csproj" -c Release -o /app/publish
161+
RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish
163162

164163
FROM base AS final
165164
WORKDIR /app
166165
COPY --from=publish /app/publish .
167-
ENTRYPOINT ["dotnet", "ReactSPA.dll"]
166+
ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
168167
```
169168

170169
:::moniker-end
@@ -225,56 +224,56 @@ Update the Dockerfile by adding the following lines. This will copy node and npm
225224
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
226225
COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
227226
WORKDIR /src
228-
COPY ["WebApplicationReact1/WebApplicationReact1.csproj", "WebApplicationReact1/"]
229-
RUN dotnet restore "WebApplicationReact1/WebApplicationReact1.csproj"
227+
COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
228+
RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
230229
COPY . .
231-
WORKDIR "/src/WebApplicationReact1"
232-
RUN dotnet build "WebApplicationReact1.csproj" -c Release -o /app/build
230+
WORKDIR "/src/ProjectSPA1"
231+
RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build
233232

234233
FROM build AS publish
235-
RUN dotnet publish "WebApplicationReact1.csproj" -c Release -o /app/publish
234+
RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish
236235

237236
FROM base AS final
238237
WORKDIR /app
239238
COPY --from=publish /app/publish .
240-
ENTRYPOINT ["dotnet", "WebApplicationReact1.dll"]
239+
ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
241240
```
242241

243242
:::moniker-end
244243
:::moniker range=">=vs-2022"
245244
```Dockerfile
246-
# escape=`
245+
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
246+
247247
#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.
248248
#For more information, please see https://aka.ms/containercompat
249-
FROM mcr.microsoft.com/powershell AS downloadnodejs
249+
# escape=`
250+
FROM mcr.microsoft.com/powershell:nanoserver-1809 AS downloadnodejs
250251
ENV NODE_VERSION=14.16.0
251252
SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"]
252-
RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; \
253-
Expand-Archive nodejs.zip -DestinationPath C:\; \
254-
Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs
253+
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
255254

256-
FROM mcr.microsoft.com/dotnet/core/aspnet:6.0 AS base
255+
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
257256
WORKDIR /app
258257
EXPOSE 80
259258
EXPOSE 443
260-
COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
259+
COPY --from=downloadnodejs C:\\nodejs\\ C:\\Windows\\system32\\
261260

262-
FROM mcr.microsoft.com/dotnet/core/sdk:6.0 AS build
263-
COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
261+
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
262+
COPY --from=downloadnodejs C:\\nodejs\\ C:\\Windows\\system32\\
264263
WORKDIR /src
265-
COPY ["WebApplicationReact1/WebApplicationReact1.csproj", "WebApplicationReact1/"]
266-
RUN dotnet restore "WebApplicationReact1/WebApplicationReact1.csproj"
264+
COPY ["Project1-SPA-Windows/Project1-SPA-Windows.csproj", "Project1-SPA-Windows/"]
265+
RUN dotnet restore "Project1-SPA-Windows/Project1-SPA-Windows.csproj"
267266
COPY . .
268-
WORKDIR "/src/WebApplicationReact1"
269-
RUN dotnet build "WebApplicationReact1.csproj" -c Release -o /app/build
267+
WORKDIR "/src/Project1-SPA-Windows"
268+
RUN dotnet build "Project1-SPA-Windows.csproj" -c Release -o /app/build
270269

271270
FROM build AS publish
272-
RUN dotnet publish "WebApplicationReact1.csproj" -c Release -o /app/publish
271+
RUN dotnet publish "Project1-SPA-Windows.csproj" -c Release -o /app/publish /p:UseAppHost=false
273272

274273
FROM base AS final
275274
WORKDIR /app
276275
COPY --from=publish /app/publish .
277-
ENTRYPOINT ["dotnet", "WebApplicationReact1.dll"]
276+
ENTRYPOINT ["dotnet", "Project1-SPA-Windows.dll"]
278277
```
279278

280279
::: moniker-end
@@ -284,76 +283,103 @@ Update the Dockerfile by adding the following lines. This will copy node and npm
284283
## Debug
285284

286285
:::moniker range=">=vs-2022"
287-
Set the launch properties for debugging. You can use the dropdown menu next to the Start button, and choose **Debug properties**. In the **Launch profile** dialog comes up, choose **Docker**.
286+
The project uses the SPA Proxy during debugging. See [Improved single-page app (SPA) templates](https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-net-6-preview-4/#improved-single-page-app-spa-templates). When debugging, the JavaScript client runs on the host machine, but the ASP.NET Core server code runs in the container. When published, the proxy is not run, and the client code runs on the same server as the ASP.NET Core code. You already have a Debug profile **Docker* that you can use to debug the server code. To debug the JavaScript client code, you can create an additional debug profile. You'll also need to start the proxy manually from a command prompt when debugging JavaScript. You can leave it running through multiple debug sessions.
287+
288+
1. Build the project, if not already built.
288289
289-
Set **Environment variables** to the following. Your SSL port number should match the HTTPS **Host Port** from the **Ports** tab of the **Containers** window.
290+
1. Open a Visual Studio dev command prompt, go to the ClientApp folder in your project, and then give the command, `npm run start`. You should see something like this:
290291
292+
```output
293+
Compiled successfully!
294+
295+
You can now view project3_spa in the browser.
296+
297+
Local: https://localhost:44407
298+
On Your Network: https://192.168.1.5:44407
299+
300+
Note that the development build is not optimized.
301+
To create a production build, use npm run build.
302+
303+
webpack compiled successfully
291304
```
292-
ASPNETCORE_ENVIRONMENT=Development,ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=Microsoft.AspNetCore.SpaProxy,ASPNETCORE_HTTPS_PORT=<your SSL port>,ASPNETCORE_URLS=https:////+:443;http:////+:80
305+
306+
Note the local URL. You'll need to provide this in a debug launch profile, which is stored in your *launchSettings.json* file.
307+
308+
1. Open the dropdown that contains debug profiles (next to the green triangle icon or **Start** button), and choose **{ProjectName} Debug Properties**, and choose the **Docker** profile.
309+
1. Check the **Environment variables** section and add the following environment variables if not already present:
310+
311+
```
312+
ASPNETCORE_ENVIRONMENT=Development,ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=Microsoft.AspNetCore.SpaProxy
293313
```
294314
295-
This action changes the Docker entry in the *launchSettings.json* file and enables the SPA Proxy to work correctly. Find the *launchSettings.json* file in **Solution Explorer** under **Properties**. You should see something like this, but with your app's assigned port numbers:
296-
297-
```json
298-
"Docker": {
299-
"commandName": "Docker",
300-
"launchBrowser": true,
301-
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
302-
"environmentVariables": {
303-
"ASPNETCORE_URLS": "https://+:443;http://+:80",
304-
"ASPNETCORE_HTTPS_PORT": "7136",
305-
"ASPNETCORE_ENVIRONMENT": "Development",
306-
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
307-
},
308-
"publishAllPorts": true,
309-
"useSSL": true,
310-
"httpPort": 5136,
311-
"sslPort": 7136
312-
}
313-
```
314-
:::moniker-end
315315
316-
Select **Docker** from the debug drop-down in the toolbar, and start debugging the app. You might see a message with a prompt about trusting a certificate; choose to trust the certificate to continue. The first time you build, docker downloads the base images, so it might take a bit longer.
316+
1. Set the **URL** to `https://localhost:{proxy-port}` where `{proxy-port}` is the port from the proxy server (from step 1).
317317
318-
:::moniker range=">=vs-2022"
319-
The project uses the SPA Proxy. If the browser loads the front page before the proxy is ready, you might see a page that says you will automatically redirected when the proxy is ready.
318+
![Screenshot of Debug Launch Profile settings for client debugging.](./media/container-tools-react/vs-2022/launch-profiles-debugging.png)
320319
321-
If the page never redirects, check that you are able to run the proxy. Open a Visual Studio dev command prompt, go to the ClientApp folder in your project, and then give the command, `npm run start`. You should see something like this:
320+
This action changes the Docker entry in the *launchSettings.json* file and launches the correct URL for the local proxy running on the host. Find the *launchSettings.json* file in **Solution Explorer** under **Properties**.
322321
323-
```
324-
325-
> node aspnetcore-https && node aspnetcore-react
322+
1. You should see something like the following code:
326323
324+
```json
325+
"profiles": {
326+
"Docker": {
327+
"commandName": "Docker",
328+
"launchBrowser": true,
329+
"environmentVariables": {
330+
"ASPNETCORE_ENVIRONMENT": "Development",
331+
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
332+
},
333+
"launchUrl": "https://localhost:44407",
334+
"useSSL": true
335+
}
336+
}
337+
```
327338

328-
329-
> rimraf ./build && react-scripts start
339+
> [!IMPORTANT]
340+
> Do not set the launch settings option `publishAllPorts` to `true` if you are using a proxy. That option publishes all exposed ports to a random port, which won't work when you set a specific port in the SPA proxy.
330341
331-
[HPM] Proxy created: [ '/weatherforecast' ] -> http://localhost:30449
332-
i 「wds」: Project is running at https://0.0.0.0:44445/
333-
i 「wds」: webpack output is served from
334-
i 「wds」: Content not from webpack is served from c:\Users\ghogen\source\repos\ProjectSpa1\ProjectSpa1\ClientApp\public
335-
i 「wds」: 404s will fallback to /
336-
Starting the development server...
337-
Compiled successfully!
338-
```
342+
1. Open the file *ClientApp/src/setupProxy.js* and change the line that sets the target to use the localhost address and port on the container. You can find the port on the **Ports** tab of the **Containers** window.
343+
344+
```JavaScript
345+
const target = 'https://localhost:{container-port}';
346+
```
347+
348+
If you're using HTTPS, be sure to choose the right port for HTTPS.
349+
350+
1. Launch the app with debugging (**F5**).
351+
352+
![Screenshot of running app.](media/container-tools-react/vs-2022/client-app-page.png)
353+
354+
If you get a build error trying to write the output assemblies, you might have to stop a previously running container to unlock the files.
355+
356+
1. Verify that you can hit a breakpoint in client-side JavaScript code by setting a breakpoint in **ClientApp/src/components/Counter.js** in the **incrementCounter** function, and then try hitting the breakpoint by clicking the **Increment** button on the Counters page.
357+
358+
![Screenshot showing ebugging client-side JavaScript.](./media/container-tools-react/vs-2022/debugging-client-javascript.png)
359+
360+
1. Next, try hitting a breakpoint in the server-side ASP.NET Core code. Set a breakpoint in *WeatherController.cs* in the `Get` method and try appending `/weatherforecast` to the base localhost and port URL to activate that code.
361+
362+
![Screenshot showing debugging server-side ASP.NET Core code.](./media/container-tools-react/vs-2022/debugging-aspnet-core.png)
363+
364+
1. If the container port changes, which can happen if you make a significant change, such as updating *launchSettings.json* or updating the debug launch profile in the IDE, you'll need to update the port in *setupProxy.js* and also restart the proxy. Terminate the current proxy (**Ctrl**+**C** in the command window where it's running), and then restart it using the same command `npm run start`.
339365

340-
If that succeeds, try starting the app again in the browser. If it doesn't succeed, check again that everything is correct in your *launchSettings.json* file.
341366
:::moniker-end
342367

368+
:::moniker range="vs-2019"
369+
370+
Select **Docker** from the debug drop-down in the toolbar, and start debugging the app. You might see a message with a prompt about trusting a certificate; choose to trust the certificate to continue. The first time you build, Docker downloads the base images, so it might take a bit longer.
371+
343372
The **Container Tools** option in the **Output** window shows what actions are taking place. You should see the installation steps associated with *npm.exe*.
344373

345374
The browser shows the app's home page.
346375

347-
::: moniker range="vs-2019"
348-
![Screenshot of running app.](media/container-tools-react/vs-2019/running-app.png)
349-
::: moniker-end
350-
::: moniker range=">=vs-2022"
351-
![Screenshot of running app.](media/container-tools-react/vs-2022/client-app-page.png)
352-
::: moniker-end
353-
376+
![Screenshot of running app.](media/container-tools-react/vs-2019/running-app.png)
377+
:::moniker-end
354378

355379
:::moniker range=">=vs-2019"
356380

381+
## Containers window
382+
357383
Open the **Containers** tool window. You can find it on the menu under **View** > **Other Windows** > **Containers**, or press **Ctrl**+**Q** and start typing `containers` in the search box, then choose **Containers** window from the results. When the window comes up, dock it on the bottom under the editor pane.
358384

359385
The **Containers** window shows the running containers and lets you view information about them. You can view the environment variables, labels, ports, volumes, the file system, and logs. The toolbar buttons let you create a terminal (shell prompt) inside the container, attach the debugger, or prune unused containers. See [Use the Containers window](view-and-diagnose-containers.md).
@@ -375,7 +401,6 @@ You can also view the images and inspect information about them. Choose the **Im
375401

376402
Once the develop and debug cycle of the app is completed, you can create a production image of the app.
377403

378-
379404
:::moniker range="vs-2019"
380405

381406
1. Change the configuration drop-down to **Release** and build the app.
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)