快速入門:在 Visual Studio 中使用 Docker 搭配 React 單頁應用程式
使用 Visual Studio,您可以輕鬆地建置、偵錯和執行容器化的 ASP.NET Core 應用程式 (包括具有用戶端 JavaScript 的應用程式,例如 React.js 單一頁面應用程式 (SPA)),並發佈到 Azure Container Registry、Docker Hub、Azure App Service 或您自己的容器登錄。 在本文中,我們會發佈至 Azure Container Registry。
必要條件
- Docker Desktop
- 已安裝網頁程式開發、Azure Tools 工作負載及(或) .NET Core 跨平台開發 工作負載的 Visual Studio 2019
- 適合使用 .NET Core 3.1 開發的 .NET Core 3.1 開發工具。
- 發佈至 Azure Container Registry (Azure 訂用帳戶)。 註冊免費試用版。
- Node.js
- 針對 Windows 容器,Windows 10 版本 1809 或更新版本,請使用本文所參考的 Docker 映像。
- Docker Desktop
- 已安裝網頁程式開發、Azure Tools 工作負載及(或) .NET Core 跨平台開發 工作負載的 Visual Studio 2022
- 發佈至 Azure Container Registry (Azure 訂用帳戶)。 註冊免費試用版。
- Node.js
- 針對 Windows 容器,Windows 10 版本 1809 或更新版本,請使用本文所參考的 Docker 映像。
安裝和設定
針對 Docker 安裝,請先檢閱 Docker Desktop for Windows: What to know before you install (英文) 中的資訊。 接下來,安裝 Docker Desktop。
建立專案並新增 Docker 支援
使用 ASP.NET Core 搭配 React.js 範本建立新專案。
在 [其他資訊] 畫面上,您無法選取 [啟用 Docker 支援],但別擔心,您可以稍後加入該支援。
以滑鼠右鍵按一下專案節點,然後選擇 [新增]> [Docker 支援],將 Dockerfile 新增至您的專案。
選取容器類型。
下一個步驟會根據您使用 Linux 容器或 Windows 容器而有所不同。
注意
如果在 Visual Studio 2022 或更新版本使用的是最新專案範本,則不需要修改 Dockerfile。
修改 Dockerfile (Linux 容器)
Dockerfile 是用於建立最終 Docker 映像的配方,會在專案中建立。 請參閱 Dockerfile 參考,以了解其內的命令。
預設 Dockerfile 會使用基底映像來執行容器,但當您想要也能夠在容器上執行 Node.js 應用程式時,您需要安裝 Node.js,這表示在 Dockerfile 的幾個位置中新增一些安裝命令。 安裝命令需要提高的權限,因為變更會影響容器的特殊權限系統檔案和資料夾。
核取新專案對話方塊的 [設定 HTTPS] 核取方塊時,Dockerfile 會提供兩個連接埠。 其中一個連接埠用於 HTTP 流量,另一個連接埠則用於 HTTPS。 如果未核取該核取方塊,則會為 HTTP 流量提供單一連接埠 (80)。
如果您是以 .NET 8 或更新版本為目標,則為 Visual Studio 使用一般使用者帳戶建立的預設 Dockerfile (尋找 USER app
行),但該帳戶並未安裝 Node.js 所需提高的權限。 若要考慮這種情況,請執行下列動作:
- 在 Dockerfile 中,刪除
USER app
行。 - 將 Dockerfile 第一個區段中公開的連接埠針對 HTTP 要求變更為連接埠 80,以及 (如果您在建立專案時選擇支援 HTTPS) 針對 HTTPS 要求變更為 443。
- 編輯
launchSettings.json
以將該處的連接埠參考變更為 80 和 443;針對 HTTP 將 8080 取代為 80,以及針對 HTTPS 將 8081 取代為 443。
針對所有 .NET 版本,使用下列步驟來更新 Dockerfile 以安裝 Node.js:
- 新增下列幾行,以在容器中安裝 curl、Node.js 14.x 和特定必要的 Node 程式庫。 務必將這些程式碼行加入第一個區段中,將 Node 封裝管理員
npm.exe
的安裝加入至基底映像,以及在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
Dockerfile 現在看起來應像這樣:
#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"]
上述的 Dockerfile 以 mcr.microsoft.com/dotnet/aspnet 影像為基礎,包含用於建置專案後加入容器以修改基底影像的指令。
修改 Dockerfile (Windows 容器)
按兩下專案節點以開啟專案檔,並藉由將下列屬性加入為 <PropertyGroup>
元素的子系來更新專案檔 (*.csproj):
<DockerfileFastModeStage>base</DockerfileFastModeStage>
注意
需要 DockerfileFastModeStage 的變更,因為這裡的 Dockerfile 會將階段新增至 Dockerfile 的開頭。 為了最佳化效能,Visual Studio 會使用 Fast 模式,但只有在使用正確的階段時才能運作。 預設值是 Dockerfile 中的第一個階段,在此範例中會從 base
變更為其他項目以下載 Node.js。 如需 [快速模式] 的詳細說明,請參閱在 Visual Studio 中自訂 Docker 容器。
加入下列幾行來更新 Dockerfile。 這幾行會將 Node 和 `npm`` 複製到容器。
將
# escape=`
加入至 Dockerfile 的第一行在
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
在
FROM ... build
之前和之後加入下列這一行COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
完成的 Dockerfile 現在看起來應像這樣:
# 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"]
藉由移除
**/bin
來更新.dockerignore
檔案。
如果您使用 Visual Studio 2022 17.8 版或更新版本,請遵循下列步驟:
使用 React 和 ASP.NET Core 範本建立新專案。
在 [其他資訊] 畫面上,選取 [啟用容器支援]。 請務必選取 [Dockerfile] 選項,因為您必須手動變更該檔案。
注意
某些 Visual Studio 2022 版本未啟用此選項,但您可稍後再新增該支援。
Visual Studio 會建立兩個專案 - 一個用於 React JavaScript 用戶端程式代碼,另一個用於 ASP.NET Core C# 伺服器程式碼。
如果專案建立期間未新增 Docker 容器支援,請以滑鼠右鍵按一下伺服器專案節點,然後選擇 [新增]>[Docker 支援],並務必選擇建立 Dockerfile 的 [Dockerfile] 選項。
選取容器類型。
針對 Visual Studio 2022 17.0 版至 17.7,請使用下列步驟:
使用 ASP.NET Core 搭配 React.js 範本建立新專案。
在 [其他資訊] 畫面上,您無法選取 [啟用 Docker 支援],但別擔心,您可以稍後加入該支援。
以滑鼠右鍵按一下專案節點,然後選擇 [新增]> [Docker 支援],將 Dockerfile 新增至您的專案。
選取容器類型。
偵錯
使用 Visual Studio 2022 17.9 版和更新版本以及 React 和 ASP.NET Core 使用 vite.js
的範本,專案已設定為同時啟動用戶端和伺服器專案,並提供偵錯支援;但您需要為單頁應用程式 (SPA) Proxy 設定要使用的正確連接埠,以存取容器中執行的 ASP.NET Core 伺服器。 您可以從 Visual Studio 的 [容器] 視窗取得主機連接埠,如建立 React 應用程式 - Docker 所述,在 React 專案加以設定。
您也可以停用在瀏覽器啟動伺服器,此功能已設定為使用 Swagger 開啟,但此案例不需要 Swagger。 若要停用瀏覽器啟動,請開啟 [屬性] (Alt+Enter),移至 [偵錯] 索引標籤,然後按下 [開啟偵錯啟動設定檔 UI] 連結,並清除 [啟動瀏覽器] 核取方塊。
如果使用的是舊版 Visual Studio 2022,請繼續閱讀,設定以單頁應用程式 (SPA) Proxy 伺服器進行偵錯。
專案會在偵錯期間使用 SPA Proxy。 請參閱改善的單頁應用程式 (SPA) 範本。 偵錯時,JavaScript 用戶端會在主機電腦上執行,但 ASP.NET Core 伺服器程式碼會在容器中執行。 發佈時,Proxy 不會執行,且用戶端程式碼會在與 ASP.NET Core 程式碼相同的伺服器上執行。 您已經有偵錯設定檔 *Docker,可用來偵錯伺服器程式碼。 若要偵錯 JavaScript 用戶端程式碼,您可以建立額外的偵錯設定檔。 偵錯 JavaScript 時,您也需要從命令提示字元手動啟動 Proxy。 您可以讓它在多個偵錯工作階段中執行。
建置專案 (如果尚未建置)。
開啟 Visual Studio dev 命令提示字元,移至專案中的 ClientApp 資料夾,然後提供命令
npm run start
。 您應該會看到類似這樣的畫面︰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
注意
記下本機 URL。 您必須在偵錯啟動設定檔中提供此功能,其會儲存在您的
launchSettings.json
檔案中。開啟包含偵錯設定檔的下拉式清單 (綠色三角形圖示或 [開始] 按鈕旁),並選擇 [{ProjectName} 偵錯屬性],然後選擇 [Docker] 設定檔。
檢查 [環境變數] 區段,如果還不存在,請新增下列環境變數:
ASPNETCORE_ENVIRONMENT=Development,ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=Microsoft.AspNetCore.SpaProxy
將 URL 設定為
https://localhost:{proxy-port}
,其中的{proxy-port}
是來自 Proxy 伺服器的連接埠 (從步驟 1)。此動作會變更
launchSettings.json
檔案中的 Docker 項目,並針對主機上執行的本機 Proxy 啟動正確的 URL。 在 [方案總管] 中的 [屬性] 底下尋找launchSettings.json
檔案。您應該會看到類似下列程式碼的畫面:
"profiles": { "Docker": { "commandName": "Docker", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" }, "launchUrl": "https://localhost:44407", "useSSL": true } }
重要
如果您使用 Proxy,請勿將啟動設定選項
publishAllPorts
設定為true
。 該選項會將所有公開的連接埠發行至隨機連接埠,當您在 SPA Proxy 中設定特定連接埠時,將無法運作。開啟檔案 ClientApp/src/setupProxy.js,並變更會將目標設定為在容器上使用
localhost
位址和連接埠的行。 您可以在 [容器] 視窗的 [連接埠] 索引標籤上找到連接埠。const target = 'https://localhost:{container-port}';
如果您使用 HTTPS,請務必針對 HTTPS 選擇正確的連接埠,在本教學課程中為 443。
使用偵錯啟動應用程式 (F5)。
如果您收到嘗試寫入輸出元件的建置錯誤,可能必須停止先前執行的容器來解除鎖定檔案。
驗證您可以在用戶端 JavaScript 程式碼中叫用中斷點,方法是在 incrementCounter 函式的 ClientApp/src/components/Counter.js 中設定中斷點,然後按一下 [計數器] 頁面上的 [遞增] 按鈕,嘗試叫用中斷點。
接下來,嘗試在伺服器端 ASP.NET Core 程式碼中叫用中斷點。 在
Get
方法的WeatherController.cs
中設定中斷點,並嘗試將/weatherforecast
附加至基礎localhost
和連接埠 URL 以啟用該程式碼。如果容器連接埠變更 (可能在您進行重大變更時發生,例如更新
launchSettings.json
或更新 IDE 中的偵錯啟動設定檔),則需要更新setupProxy.js
中的連接埠,並同時重新啟動 Proxy。 終止目前的 Proxy (在執行它的命令視窗中按 Ctrl+C),然後使用相同的命令npm run start
將它重新啟動。
從工具列的偵錯下拉式清單中選取 [Docker],然後開始對應用程式進行偵錯。 您可能會看到提示信任憑證的訊息,請選擇信任憑證以繼續進行。 第一次建置時,Docker 會下載基礎映像,因此可能需要長一點的時間。
[輸出] 視窗中的 [容器工具] 選項會顯示要採取哪些動作。 您應該會看到與 npm.exe 相關聯的安裝步驟。
瀏覽器會顯示應用程式的首頁。
容器視窗
開啟 [容器] 工具視窗。 您可以在 [檢視] > [其他 Windows] > [容器] 下方的功能表上找到它,或按 Ctrl+Q 並開始在搜尋方塊中輸入 containers
,然後從結果中選擇 [容器] 視窗。 當視窗出現時,請將視窗固定在編輯器窗格底端。
[容器] 視窗會顯示執行中的容器,並可讓您檢視其相關資訊。 您可以檢視環境變數、標籤、連接埠、磁碟區、檔案系統和記錄。 工具列按鈕可讓您在容器內建立終端 (殼層提示字元),連結偵錯工具,或剪除未使用的容器。 請參閱使用 [容器] 視窗。
按一下 [檔案] 索引標籤,然後展開 app
資料夾以查看已發行的應用程式檔案。
您也可以檢視映像,並檢查其相關資訊。 選擇 [映像] 索引標籤,找出您專案的索引標籤,然後選擇 [詳細資料] 索引標籤,以檢視包含映像相關資訊的 JSON 檔案。
注意
dev 映像未包含應用程式二進位檔案和其他內容,因為 [偵錯] 組態會使用磁碟區掛接來提供反覆編輯和偵錯體驗。 若要建立包含所有內容的生產映像,請使用 [發行] 組態。
發行 Docker 映像
一旦應用程式的開發和偵錯循環完成,您就可以建立應用程式的生產映像。
將組態下拉式清單變更為 [發行] 並建置應用程式。
在方案總管中以滑鼠右鍵按一下專案,並選擇 [發佈]。
在 [發行目標] 對話方塊上,選取 [Docker Container Registry]。
下一步,選擇 [Azure Container Registry]。
選擇 [建立新的 Azure Container Registry]。
在 [建立新的 Azure Container Registry] 畫面中填入您想要的值。
設定 建議的值 描述 DNS 首碼 全域唯一的名稱 用以唯一識別容器登錄的名稱。 訂用帳戶 選擇您的訂用帳戶 要使用的 Azure 訂用帳戶。 資源群組 myResourceGroup 要在其中建立容器登錄的資源群組名稱。 選擇 [新增] 以建立新的資源群組。 SKU 標準 容器登錄的服務層 登錄位置 接近您的位置 在 [區域] 中選擇您附近的位置,或選擇使用您容器登錄之其他服務的鄰近位置。 選取 [建立],然後選取 [完成]。
發行程序結束時,您可以檢閱發行設定,並視需要編輯它們,或使用 [發行] 按鈕再次發行映像。
若要使用 [發行] 對話方塊再次啟動,請使用此頁面上的 [刪除] 連結來刪除發行設定檔,然後再次選擇 [發行]。
將組態下拉式清單變更為 [發行] 並建置應用程式。
在方案總管中以滑鼠右鍵按一下專案,並選擇 [發佈]。
在 [發行目標] 對話方塊上,選取 [Docker Container Registry]。
下一步,選擇 [Azure Container Registry]。
選擇 [建立新的 Azure Container Registry]。
在 [建立新的 Azure Container Registry] 畫面中填入您想要的值。
設定 建議的值 描述 DNS 首碼 全域唯一的名稱 用以唯一識別容器登錄的名稱。 訂用帳戶 選擇您的訂用帳戶 要使用的 Azure 訂用帳戶。 資源群組 myResourceGroup 要在其中建立容器登錄的資源群組名稱。 選擇 [新增] 以建立新的資源群組。 SKU 標準 容器登錄的服務層 登錄位置 接近您的位置 在 [區域] 中選擇您附近的位置,或選擇使用您容器登錄之其他服務的鄰近位置。 選取 [建立],然後選取 [完成]。
發行程序結束時,您可以檢閱發行設定,並視需要編輯它們,或使用 [發行] 按鈕再次發行映像。
若要使用 [發行] 對話方塊再次啟動,請使用此頁面上的 [刪除] 連結來刪除發行設定檔,然後再次選擇 [發行]。
下一步
您現在可以從登錄中,將容器提取至能夠執行 Docker 映像的任何主機,例如 Azure 容器執行個體。