이전 글에 이어...

>> 참조: vs2017에서 ASP.NET Core Docker 컨테이너 배포 (1/2)

 

.NET Core, 즉 ASP.NET Core 앱은 OS 독립적으로 실행 가능하다. 즉 Cross-Platform 환경에서 동작하는 것이 기본이다. 이것이 무엇을 의미하는가 하면, 한번 빌드한 앱은 다시 빌드하지 않아도 Windows 환경에서도, Linux 환경에서도 똑같이 동일하게 배포되어 실행이 가능하다는 의미이다. Java처럼.

이전 글에서 Visual Studio를 이용해서 Docker에 배포하는 방법을 살펴봤는데, Visual Studio를 이용하면 상당히 간단한 몇번의 클릭만으로 배포가 이루어지므로 좋긴 하지만, 이번에 하려는 작업처럼 Cross-Platform 환경에 동일한 앱을 배포하는 것과 같은 작업은 하기 어렵다. (어려운 정도가 아니라 아예 할 수가 없다.)

우선 참조할 내용은 아래와 같다.

>> 참조: https://docs.microsoft.com/ko-kr/aspnet/core/host-and-deploy/docker/building-net-docker-images?view=aspnetcore-3.1#build-and-deploy-manually

 

ASP.NET Core의 Docker 이미지

Docker 레지스트리에서 게시된 .NET Core Docker 이미지를 사용하는 방법을 알아봅니다. 이미지를 끌어오고 고유한 이미지를 빌드합니다.

docs.microsoft.com

위 참조 문서에 절차나 과정은 제대로 나와 있는데, 실제로 그대로 따라하면 안된다. Visual Studio 2017이 아닌 Visual Studio 2019 (.NET Core SDK 3.1) 환경에서 해도 안된다. 안되도록 잘못 만들어놨기 때문이다... ㄷㄷㄷ

 

일단 작업 순서는 아래와 같다.

1. ASP.NET Core 앱을 빌드하고 게시(Publish)한다.

2. 게시한 ASP.NET Core 앱을 Docker에 배포하기 위한 Dockerfile을 만든다.

3. Docker에 배포한다.

작업 자체는 간단한데, 살짝 Docker 명령줄 실행 옵션 및 Dockerfile 내용에 대한 지식과 노하우가 필요하다.

일단 1번 작업은 Visual Studio에서 해도 되고, 아래와 같이 명령줄로 해도 된다.

D:\Project\GitHub\dotnet-docker\samples\aspnetapp\aspnetapp>dotnet publish -c Release -o published

이렇게 하면 위 명령줄 실행경로 하위에 published라는 폴더가 생기고 그 안에 배포용 앱 파일들이 생성되는데, 경로를 잘 기억해 두어야 한다. 경로가 틀리면 Docker에 배포해도 실행이 안되니까.

다음으로 상위 폴더로 이동해서 Dockerfile 중에서 적절한 것을 하나 골라 복사한 다음 수정한다. Linux에 배포할 때는 기본 Dockerfile을 사용하면 되고, Windows에 배포할 때는 Dockerfile.nanoserver-x64를 사용하면 된다. 나는 이전 글에서 내 Windows 10 버전에 맞는 Dockerfile.nanoserver-x64-1803를 별도로 만들었기 때문에 그걸 사용하도록 하겠다.

https://hub.docker.com/_/microsoft-dotnet-core 
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-nanoserver-1803 AS build 
WORKDIR /source 

# copy csproj and restore as distinct layers 
COPY *.sln . 
COPY aspnetapp/*.csproj ./aspnetapp/ 
RUN dotnet restore -r win-x64 

# copy everything else and build app 
COPY aspnetapp/. ./aspnetapp/ 
WORKDIR /source/aspnetapp 
RUN dotnet publish -c release -o /app -r win-x64 --self-contained false --no-restore 

# final stage/image 
# Uses the 1909 release; 1903, and 1809 are other choices 
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-nanoserver-1803 AS runtime 
WORKDIR /app 
COPY --from=build /app ./ 
ENTRYPOINT ["dotnet", "aspnetapp.dll"] 

이것을 복사해서 Dockerfile.nanoserver-x64-1803.publish로 저장하고 아래와 같이 수정한다.

FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-nanoserver-1803 AS runtime 
WORKDIR /app 
COPY aspnetapp/published/. ./ 
ENTRYPOINT ["dotnet", "aspnetapp.dll"]

여기서 COPY 명령어가 있는 줄이 가장 중요하다. 위의 내용과는 다르게 이미 빌드/게시된 결과물을 사용하는 것이므로 해당 게시된 결과물이 포함된 폴더를 지정해야 하는데, 현재 작업 경로를 기준으로 한 상대 경로가 되어야 한다. 즉, 위 Microsoft 참조 문서에 있는 대로 aspnetapp.dll 파일만 지정하면 안되고 꼭! published 폴더를 통째로 지정해야 한다.

D:\Project\GitHub\dotnet-docker\samples\aspnetapp>docker build -t aspnetapp:test -f Dockerfile.nanoserver-x64-1803.publish .
Sending build context to Docker daemon  12.79MB
Step 1/4 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-nanoserver-1803 AS runtime
 ---> 8b7cf3b42002
Step 2/4 : WORKDIR /app
 ---> Using cache
 ---> 391b36e19acb
Step 3/4 : COPY aspnetapp/publish/. ./
 ---> 07d38a87b2ba
Step 4/4 : ENTRYPOINT ["dotnet", "aspnetapp.dll"]
 ---> Running in 5360017dd02e
Removing intermediate container 5360017dd02e
 ---> 6279dc073a6b
Successfully built 6279dc073a6b
Successfully tagged aspnetapp:test

그래야 문제없이 실행이 가능하다.

즉, 최종 배포할 Docker의 종류에 따라 위와 같이 컨테이너 빌드용 Dockerfile을 만들어 사용하면 된다.

앱 자체는 별도로 다시 빌드할 필요가 없다. Cross-Platform이니까.

 

끝.

 

 



Posted by 떼르미
,


자바스크립트를 허용해주세요!
Please Enable JavaScript![ Enable JavaScript ]