빠른 시작: Visual Studio에서 React 단일 페이지 애플리케이션과 함께 Docker 사용
Visual Studio를 사용하여 React.js 단일 페이지 애플리케이션(SPA)과 같은 클라이언트 쪽 JavaScript를 포함한 앱과 더불어 컨테이너화된 ASP.NET Core 앱을 손쉽게 빌드, 디버그, 실행하고 Azure Container Registry(SPA), Docker Hub, Azure App Service 또는 자체 Container Registry에 게시할 수 있습니다. 이 문서에서는 Azure Container Registry에 게시합니다.
필수 조건
- Docker Desktop
- 웹 개발, Azure 도구 워크로드 및/또는 .NET Core 크로스 플랫폼 개발 워크로드가 설치된 Visual Studio 2019.
- .NET Core 3.1을 사용하여 개발하기 위한 .NET Core 3.1 개발 도구
- Azure Container Registry에 게시하려면 Azure 구독이 있어야 합니다. 평가판에 가입합니다.
- Node.js
- Windows 컨테이너의 경우 이 문서에서 참조된 Docker 이미지를 사용하려면 Windows 10 버전 1809 이상이어야 합니다.
- Docker Desktop
- 웹 개발, Azure 도구 워크로드 및/또는 .NET Core 플랫폼 간 개발 워크로드가 설치된 Visual Studio 2022
- Azure Container Registry에 게시하려면 Azure 구독이 있어야 합니다. 평가판에 가입합니다.
- Node.js
- Windows 컨테이너의 경우 이 문서에서 참조된 Docker 이미지를 사용하려면 Windows 10 버전 1809 이상이어야 합니다.
설치 및 설정
Docker 데스크탑을 설치하려면 우선 Windows용 Docker: 설치하기 전에 알아야 할 사항의 정보를 검토하세요. 다음으로 Docker Desktop을 설치합니다.
프로젝트를 만들고 Docker 지원 추가
ASP.NET Core(React.js 사용) 템플릿을 사용하여 새 프로젝트를 만듭니다.
추가 정보 화면에서는 Docker 지원 사용을 선택할 수 없으며 다만 나중에 해당 지원을 추가할 수 있으니 걱정하지 마세요.
프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 추가>Docker 지원을 선택하여 프로젝트에 Dockerfile을 추가합니다.
컨테이너 형식을 선택합니다.
다음 단계는 Linux 컨테이너를 사용 중인지 Windows 컨테이너를 사용 중인지에 따라 달라집니다.
참고 항목
Visual Studio 2022 이상에서 최신 프로젝트 템플릿을 사용하는 경우 Dockerfile을 수정할 필요가 없습니다.
Dockerfile 수정(Linux 컨테이너)
최종 Docker 이미지를 만들기 위한 레시피인 Dockerfile은 프로젝트에 생성됩니다. 그 안의 명령을 이해하려면 Dockerfile 참조를 참조하세요.
기본 Dockerfile은 기본 이미지를 사용하여 컨테이너를 실행하지만, 컨테이너에서 Node.js 애플리케이션을 실행하려면 Node.js 설치해야 합니다. 즉, Dockerfile의 몇 위치에 일부 설치 명령을 추가해야 합니다. 변경 내용이 컨테이너의 권한 있는 시스템 파일 및 폴더에 영향을 주므로 설치 명령에는 상승된 권한이 필요합니다.
새 프로젝트 대화 상자의 HTTPS에 대한 구성 확인란이 선택되면 Dockerfile은 두 개의 포트를 노출합니다. 한 포트는 HTTP 트래픽에 사용되고 다른 포트는 HTTPS에 사용됩니다. 이 확인란을 선택하지 않으면 단일 포트(80)가 HTTP 트래픽에 노출됩니다.
.NET 8 이상을 대상으로 하는 경우 Visual Studio에서 일반 사용자 계정(줄 USER app
찾기)을 사용하여 만드는 기본 Dockerfile이지만 해당 계정에는 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 및 특정 필수 노드 라이브러리를 컨테이너에 설치합니다. 이 행을 둘 다 첫 번째 섹션에 추가하고 노드 패키지 관리자
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>
참고 항목
Dockerfile이 Dockerfile의 시작 부분에 스테이지를 추가하므로 DockerfileFastModeStage를 변경해야 합니다. 성능을 최적화하기 위해 Visual Studio는 빠른 모드를 사용하지만 올바른 단계를 사용하는 경우에만 작동합니다. 기본값은 Dockerfile의 첫 번째 단계이며, 이 예시에서는 base
Node.js 다운로드하기 위해 다른 항목으로 변경됩니다. 빠른 모드에 대한 추가 설명은 Visual Studio에서 Docker 컨테이너사용자 지정을 참조 하세요.
다음 줄을 추가하여 Dockerfile을 업데이트합니다. 이 줄들은 노드 및 'npm''을 컨테이너에 복사됩니다.
Dockerfile의 첫 번째 줄에
# escape=`
를 추가합니다.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 이상과 vite.js
을(를) 사용하는 React 및 ASP.NET Core 템플릿을 사용하면 프로젝트가 디버깅을 지원하는 클라이언트 및 서버 프로젝트를 모두 시작하도록 이미 구성되어 있지만 컨테이너에서 실행 중인 ASP.NET Core 서버에 액세스하는 데 사용할 SPA(단일 페이지 애플리케이션) 프록시에 적합한 포트를 설정해야 합니다. Visual Studio의 컨테이너 창에서 호스트 포트를 가져와 React 앱 만들기 - Docker에 설명된 대로 React 프로젝트에서 설정할 수 있습니다.
이 시나리오에서는 필요하지 않은 Swagger를 사용하여 열도록 설정된 서버의 브라우저에서 시작을 사용하지 않도록 설정할 수도 있습니다. 브라우저 시작을 사용하지 않도록 설정하려면 속성(Alt+Enter)을 열고 디버그 탭으로 이동한 다음 디버그 시작 프로필 UI 열기 링크를 클릭하고 브라우저 시작 확인란의 선택을 취소합니다.
이전 버전의 Visual Studio 2022를 사용하는 경우 읽기를 계속하여 SPA(단일 페이지 애플리케이션) 프록시 서버를 통해 디버깅을 설정합니다.
이 프로젝트는 디버깅 중에 SPA 프록시를 사용합니다. 향상된 SPA(단일 페이지 앱) 템플릿을 참조하세요. 디버깅할 때 JavaScript 클라이언트는 호스트 컴퓨터에서 실행되지만 ASP.NET Core 서버 코드는 컨테이너에서 실행됩니다. 게시되면 프록시가 실행되지 않고 클라이언트 코드가 ASP.NET Core 코드와 동일한 서버에서 실행됩니다. 서버 코드를 디버그하는 데 사용할 수 있는 디버그 프로필 *Docker가 이미 있습니다. JavaScript 클라이언트 코드를 디버그하려면 추가 디버그 프로필을 만들 수 있습니다. 또한 JavaScript를 디버깅할 때 명령 프롬프트에서 프록시를 수동으로 시작해야 합니다. 여러 디버그 세션을 통해 실행 중인 상태로 둘 수 있습니다.
아직 빌드되지 않은 경우 프로젝트를 빌드합니다.
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}
는 프록시 서버의 포트입니다(1단계부터).이 작업은
launchSettings.json
파일의 Docker 항목을 변경하고 호스트에서 실행되는 로컬 프록시에 대한 올바른 URL을 시작합니다. 솔루션 탐색기의 속성에서launchSettings.json
파일을 찾습니다.다음과 같은 코드가 표시됩니다.
"profiles": { "Docker": { "commandName": "Docker", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" }, "launchUrl": "https://localhost:44407", "useSSL": true } }
Important
프록시를 사용하는 경우 시작 설정 옵션
publishAllPorts
를true
로 설정하지 마세요. 해당 옵션은 임의의 포트에 노출된 모든 포트를 게시하며, 이는 SPA 프록시에서 특정 포트를 설정한 경우 작동하지 않습니다.ClientApp/src/setupProxy.js 파일을 열고 대상에서 컨테이너의
localhost
주소 및 포트를 사용하도록 설정하는 줄을 변경합니다. 포트 탭의 컨테이너 창에서 포트를 찾을 수 있습니다.const target = 'https://localhost:{container-port}';
HTTPS를 사용하는 경우 HTTPS에 적합한 포트(이 자습서에서는 443)를 선택해야 합니다.
디버깅을 사용하여 앱을 시작합니다(F5).
출력 어셈블리를 작성하려고 시도할 때 빌드 오류가 발생하는 경우 파일의 잠금을 해제하기 위해 이전에 실행 중인 컨테이너를 중지해야 할 수 있습니다.
incrementCounter 함수의 ClientApp/src/components/Counter.js에서 중단점을 설정하여 클라이언트 쪽 JavaScript 코드에서 중단점을 적중할 수 있는지 확인합니다. 그런 다음 카운터 페이지에서 증가 단추를 클릭하여 중단점을 적중해 봅니다.
다음으로 서버 쪽 ASP.NET Core 코드에서 중단점을 적중해 봅니다.
Get
메서드의WeatherController.cs
에서 중단점을 설정하고 기본localhost
및 포트 URL에/weatherforecast
를 추가하여 해당 코드를 활성화해 봅니다.launchSettings.json
을 업데이트하거나 IDE에서 디버그 시작 프로필을 업데이트하는 등 중요한 변경을 수행할 경우 발생할 수 있는 컨테이너 포트 변경이 있으면setupProxy.js
의 포트를 업데이트하고 프록시도 다시 시작해야 합니다. 현재 프록시를 종료한 다음(실행 중인 명령 창에서 Ctrl+C) 동일한 명령npm run start
를 사용하여 다시 시작합니다.
툴바의 디버그 드롭다운 목록에서 Docker를 선택하고 앱에서 디버깅을 시작합니다. 인증서 신뢰 요청 메시지가 표시될 수 있습니다. 계속하려면 인증서를 신뢰하도록 선택하세요. 처음 빌드할 때는 Docker가 기본 이미지를 다운로드하기 때문에 시간이 조금 더 걸릴 수 있습니다.
출력 창의 컨테이너 도구 옵션에 실행 중인 작업이 표시됩니다. npm.exe와 연관된 설치 단계가 표시됩니다.
브라우저에 앱의 홈페이지가 표시됩니다.
컨테이너 창
컨테이너 도구 창을 엽니다. 이 창은 보기>다른 창>컨테이너 아래의 메뉴에서 찾을 수 있습니다. 또는 Ctrl+Q를 누르고 검색 상자에 containers
를 입력하여 결과에서 컨테이너 창을 선택합니다. 창이 나타나면 편집기 창의 아래쪽에 도킹합니다.
컨테이너 창에서는 실행 중인 컨테이너가 표시되며 해당 컨테이너에 대한 정보를 볼 수 있습니다. 환경 변수, 레이블, 포트, 볼륨, 파일 시스템 및 로그를 볼 수 있습니다. 도구 모음 단추를 사용하여 컨테이너 내에서 터미널(셸 프롬프트)을 만들거나, 디버거를 연결하거나, 사용하지 않는 컨테이너를 정리할 수 있습니다. 컨테이너 창 사용을 참조하세요.
파일 탭을 클릭하고 app
폴더를 확장하여 게시된 애플리케이션 파일을 확인합니다.
이미지를 보고 이에 대한 정보를 검사할 수도 있습니다. 이미지 탭을 선택하고 프로젝트에 대한 탭을 찾은 다음 세부 정보 탭을 선택하여 이미지에 대한 정보가 포함된 json 파일을 봅니다.
참고 항목
디버그 구성은 볼륨 마운트를 사용하여 반복 편집 및 디버그 환경을 제공하므로 dev 이미지에는 앱 바이너리 및 다른 콘텐츠가 포함되지 않습니다. 모든 콘텐츠를 포함하는 프로덕션 이미지를 만들려면 릴리스 구성을 사용하세요.
Docker 이미지 게시
앱의 개발 및 디버그 주기가 완료되면 앱의 프로덕션 이미지를 만들 수 있습니다.
구성 드롭다운 목록을 릴리스로 변경하고 앱을 빌드합니다.
솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 게시를 선택합니다.
Publish target(게시 대상) 대화 상자에서 Docker 컨테이너 레지스트리를 선택합니다.
다음으로, Azure Container Registry를 선택합니다.
새 Azure Container Registry 만들기를 선택합니다.
새 Azure Container Registry 만들기 화면에 원하는 값을 채웁니다.
설정 제안 값 설명 DNS 접두사 전역적으로 고유한 이름 컨테이너 레지스트리를 고유하게 식별하는 이름입니다. 구독 구독 선택 사용할 Azure 구독입니다. 리소스 그룹 myResourceGroup 컨테이너 레지스트리를 만들 리소스 그룹의 이름입니다. 새로 만들기를 선택하여 새 리소스 그룹을 만듭니다. SKU 표준 컨테이너 레지스트리의 서비스 계층 레지스트리 위치 가까운 위치 사용자 또는 컨테이너 레지스트리를 사용할 기타 서비스에 가까운 지역의 위치를 선택합니다. 만들기를 선택한 다음 마침을 선택합니다.
게시 프로세스가 종료되면 게시 설정을 검토하고 필요한 경우 편집하거나 게시 단추를 사용하여 이미지를 다시 게시할 수 있습니다.
게시 대화 상자를 사용하여 다시 시작하려면 이 페이지에서 삭제 링크를 사용하여 게시 프로필을 삭제한 다음 게시를 다시 선택합니다.
구성 드롭다운 목록을 릴리스로 변경하고 앱을 빌드합니다.
솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 게시를 선택합니다.
Publish target(게시 대상) 대화 상자에서 Docker 컨테이너 레지스트리를 선택합니다.
다음으로, Azure Container Registry를 선택합니다.
새 Azure Container Registry 만들기를 선택합니다.
새 Azure Container Registry 만들기 화면에 원하는 값을 채웁니다.
설정 제안 값 설명 DNS 접두사 전역적으로 고유한 이름 컨테이너 레지스트리를 고유하게 식별하는 이름입니다. 구독 구독 선택 사용할 Azure 구독입니다. 리소스 그룹 myResourceGroup 컨테이너 레지스트리를 만들 리소스 그룹의 이름입니다. 새로 만들기를 선택하여 새 리소스 그룹을 만듭니다. SKU 표준 컨테이너 레지스트리의 서비스 계층 레지스트리 위치 가까운 위치 사용자 또는 컨테이너 레지스트리를 사용할 기타 서비스에 가까운 지역의 위치를 선택합니다. 만들기를 선택한 다음 마침을 선택합니다.
게시 프로세스가 종료되면 게시 설정을 검토하고 필요한 경우 편집하거나 게시 단추를 사용하여 이미지를 다시 게시할 수 있습니다.
게시 대화 상자를 사용하여 다시 시작하려면 이 페이지에서 삭제 링크를 사용하여 게시 프로필을 삭제한 다음 게시를 다시 선택합니다.
다음 단계
이제 레지스트리에서 Docker 이미지를 실행할 수 있는 모든 호스트로 컨테이너를 끌어올 수 있습니다(예: Azure Container Instances).