loading

심재운 블로그

반응형

 

 

최신 .NET 5.0 을 사용하여 Docker Desktop으로 ASP.NET Core 5 웹 사이트를 만드는 방법을 알아볼까 합니다.

  • ASP.NET Core 3.1 웹 사이트 만들기 및 실행

  • 첫 번째 컨테이너 구축

  • 웹 사이트를 로컬 컨테이너로 실행

  • 기본 명령 이해

  • 문제 해결

 

요구 사항

이 게시물에서는 다음 요구 사항이 설치되어 있는지 확인합니다.

 

.NET Core Docker SDK 다운로드

Docker는 dotnet의 Docker SDK를 가져와 로컬 저장소에 저장합니다.

C:\SourceSample>docker pull mcr.microsoft.com/dotnet/aspnet:5.0

 

Docker Desktop이 올바르게 설치되었는지 확인하는 테스트입니다. 이미지를 빌드 할 때 볼 수 있듯이 Docker는 이미지가 로컬에 있는 경우 원격 호스트에서 이미지를 제거하는 것을 알아서 건너 뛰므로, 지금 실행하는 과정은 걱정 안하셔도 됩니다.

이미지가 로컬 저장소에 있는지 확인하려면 다음을 실행해 보죠.

C:\SourceSample>docker image ls

 

아래 목록이 보이면 성공적으로 설치 된 것을 의미합니다.

mcr.microsoft.com/dotnet/aspnet   5.0       7fafba04799a   2 days ago       205MB

 

이제 app 을 만들어 보겠습니다.

cmd 창에서  dotnet CLI, 를 통해 asp.net 5 를 생성해 보겠습니다. webapp 라는 폴더가 생성되면서 자동적으로 asp.net 5 솔루션 샘플 소스가 제공됩니다.

C:\SourceSample>dotnet new mvc -o webapp

 

생성된 폴더로 들어가서 실행해 봅니다. 실행은 dotnet run 입니다.

cd webapp
dotnet run

https://localhost:5001 를 브라우저에 실행하면 간단한 asp.net 5 로 개발된 화면을 보실 수 있습니다.

웹 애플리케이션 Containerizing (컨테이너화)

 

이제 애플리케이션을 컨테이너화 하겠습니다. 이것을 배우는 것은 microservices 에 관심이 있는 사람들에게 필요한 단계입니다. 컨테이너는 새로운 배포 단위이므로 Docker 이미지 내에 빌드를 캡슐화하고 모든 것을 Docker 파일에 래핑 할 수 있습니다.

Dockerfile 파일 생성하기

 

webapp 폴더 내부에 확장자 없는 dockerfile 이라는 파일을 생성합니다.

 

메모장이나 에디터를 열어서 아래 구문을 입력하여 저장합니다. 저는 ASP.NET 5 를 설치했으므로 SDK5.0 을 셋팅하였습니다.

버전에 맞는 dotnet 의 sdk 를 사용하여 image 를 빌드합니다.

ASP.NET CORE 3.1 : FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build

ASP.NET 5 : FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build

 

그리고 asp.net runtime 를 사용하여 실행합니다.

ASP.NET CORE 3.1 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1

ASP.NET 5 : FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base

# builds our image using dotnet's sdk
#FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /source
COPY . ./webapp/
WORKDIR /source/webapp
RUN dotnet restore
RUN dotnet publish -c release -o /app --no-restore

# runs it using aspnet runtime
#FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
COPY --from=build /app ./
ENTRYPOINT ["dotnet", "webapp.dll"]



 

이제 IMAGE 을 빌드 해 봅니다.

C:\SourceSample\webapp>docker build . -t webapp

Sending build context to Docker daemon  4.391MB
Step 1/10 : FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
 ---> fc3ec13a2fac
Step 2/10 : WORKDIR /source
 ---> Using cache
 ---> 18ca54a5c786
Step 3/10 : COPY . ./webapp/
 ---> 847771670d86
Step 4/10 : WORKDIR /source/webapp
 ---> Running in 2b0a1800223e
Removing intermediate container 2b0a1800223e
 ---> fb80acdfe165
Step 5/10 : RUN dotnet restore
 ---> Running in cc08422b2031
  Restore completed in 145.41 ms for /source/webapp/webapp.csproj.
Removing intermediate container cc08422b2031
 ---> a9be4b61c2e6
Step 6/10 : RUN dotnet publish -c release -o /app --no-restore
 ---> Running in 8c2e6f280cb9
Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  webapp -> /source/webapp/bin/release/netcoreapp3.1/webapp.dll
  webapp -> /source/webapp/bin/release/netcoreapp3.1/webapp.Views.dll
  webapp -> /app/
Removing intermediate container 8c2e6f280cb9
 ---> ceda76392fe7
Step 7/10 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
 ---> c819eb4381e7
Step 8/10 : WORKDIR /app
 ---> Using cache
 ---> 4f0b0bc1c33b
Step 9/10 : COPY --from=build /app ./
 ---> 26e01e88847d
Step 10/10 : ENTRYPOINT ["dotnet", "webapp.dll"]
 ---> Running in 785f438df24c
Removing intermediate container 785f438df24c
 ---> 5e374df44a83
Successfully built 5e374df44a83
Successfully tagged webapp:latest

 

IMAGE 가 생성되어 있는지 docker image ls 로 확인해 봅니다.

 

아래 webapp 의 DOCKER IMAGE 가 보이면 설치된것으로 보시면 됩니다.

webapp                            latest    57aa5b439675   About an hour ago   210MB

 

이제 DOCKER IMAGE 를 실행해 보도록 하겠습니다.

C:\SourceSample\webapp>docker run --rm -it -p 8000:80 webapp

 

C:\SourceSample\webapp>docker run --rm -it -p 8000:80 webapp
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {fde34a42-919f-4362-9343-dc7b01858148} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
      Failed to determine the https port for redirect.
^Cinfo: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...

[+] Building 1.4s (15/15) FINISHED
 => [internal] load build definition from Dockerfile                                                             0.0s
 => => transferring dockerfile: 32B                                                                              0.0s
 => [internal] load .dockerignore                                                                                0.0s
 => => transferring context: 2B                                                                                  0.0s
 => [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim                                 1.0s
 => [internal] load metadata for mcr.microsoft.com/dotnet/sdk:5.0-buster-slim                                    1.1s
 => [base 1/3] FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim@sha256:3ce00016aa06e270c1abec24a543c939d4dd  0.0s
 => [internal] load build context                                                                                0.0s
 => => transferring context: 7.51kB                                                                              0.0s
 => [build 1/6] FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim@sha256:ce42a8769573cd30233a2ae17c9a5c3dcc8da7  0.0s
 => CACHED [base 2/3] WORKDIR /app                                                                               0.0s
 => CACHED [build 2/6] WORKDIR /source                                                                           0.0s
 => CACHED [build 3/6] COPY . ./webapp/                                                                          0.0s
 => CACHED [build 4/6] WORKDIR /source/webapp                                                                    0.0s
 => CACHED [build 5/6] RUN dotnet restore                                                                        0.0s
 => CACHED [build 6/6] RUN dotnet publish -c release -o /app --no-restore                                        0.0s
 => CACHED [base 3/3] COPY --from=build /app ./                                                                  0.0s
 => exporting to image                                                                                           0.1s
 => => exporting layers                                                                                          0.0s
 => => writing image sha256:57aa5b439675ebcbb193b18c8126b6b2194306b097ce3498dc37eddf53b7a2b4                     0.0s
 => => naming to docker.io/library/webapp

 

 http://localhost:8000 을 실행하면 컨테이너화된 웹사이트를 보실 수 있습니다.

 

정리를 하자면..

Dockerfile을 빌드 할 때 두 개의 이미지 ( SDK  ASP.NET 이미지 )를 활용 했습니다. 처음 사용해 보시는 분들에게는 다소 덜 직관적이지만 이미지 크기가 더 작고 배포 된 코드가 적어 공격 표면??? (attack surface) 을 줄임으로써 더 안전 해 지므로 실제로는 좋은 습관입니다. 오늘 사용한 명령은 다음과 같습니다.

 

  • FROM <src> : Docker에게 이미지에 필요한 기본 이미지를 가져 오도록 지시합니다. SDK IMAGE 는 프로젝트와 빌드하는 데 필요한 도구가 포함되어 ASP.NET IMAGE 를 실행합니다.

  • COPY . : 현재 디렉토리의 내용을 컨테이너 내부에 지정된 위치에 복사합니다.

  • RUN <cmd> : 컨테이너 내부에서 명령을 실행합니다.

  • WORKDIR <path> : 후속 지침에 대한 작업 디렉토리를 설정하고 컨테이너 자체의 시작 위치로 설정합니다.

  • ENTRYPOINT [arg1, arg2, argN] : 컨테이너가 배열 형식으로 시작될 때 실행할 명령을 지정합니다. 우리의 경우 게시 된 웹 사이트를 외부에서 실행하는 것처럼 컨테이너에서 dotnet webapp.dll 을 실행합니다.

 

Docker 빌드

다음으로 docker build. -t webapp 은 다음을 의미합니다.

  • docker build . : Docker에게 현재 폴더 (.)의 내용을 기반으로 IMAGE 를 빌드하도록 지시합니다. 이 명령은 이 경우에 제공하지 않은 선택적 Dockerfile 도 허용합니다. 제공되지 않으면 Docker는 이 명령을 실행하기 전에 복사하여 붙여 넣은 현재 폴더에 Dockerfile을 예상 합니다.

  • -t webapp : 명령을 실행할 수 있도록 IMAGE 에 webapp 으로 태그 지정

 

Docker 실행

완료하려면 docker run --rm -it -p 8000 : 80 webapp 의미를 이해하겠습니다 .

  • docker run : 이미지 인스턴스 (컨테이너)를 실행합니다.

  • --rm : 완료된 직후 IMAGE 를 제거합니다. 이 명령을 여러 번 실행하고 각 실행이 새 컨테이너를 생성하므로 로컬 환경을 오염시키지 않기 위해 이렇게했습니다. Docker는 이미지가 삭제 된 후 이미지에 대한 로그를 보존하지 않으므로 개발시에만 사용해야합니다.

  • --it : 로그를보고 Ctrl-C로 취소 할 수 있도록 터미널에 연결하여 계속 실행합니다 .

  • -p 8000 : 80 : 포트 8000 의 로컬 호스트에서 컨테이너의 포트 80을 노출합니다. 

  • webapp : IMAGE 의 태그명

 

참고사이트 

blog.hildenco.com/2020/10/how-to-create-aspnet-core-website-with.html

 

Creating ASP.NET Core websites with Docker

.Net, Alpine, C#, Debian, Development, Docker, Microservices, Open Source, Ubuntu, Debian, Alpine, Asp.Net,

blog.hildenco.com

 

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band

댓글

비밀글모드