닷넷 프로젝트 도커 배포 어떻게들 하십니까?

예상 외로 다른 기술스택과 오픈소스 협업 할일이 생겼습니다.
전체 프로젝트의 일부로 MSA로 닷넷앱을 포함할 생각인데 제가 클라우드 인프라 DevOps일을 안하다보니 모르겠습니다. (배포 주체자가 제가 아님)

웹개발자들 기술스택 프로젝트들이 보통은 빌드가 불필요한 프로젝트들이 많긴하지만 (PHP), JS 기술스택들은 또 의외로 빌드를 하더군요 (Typescript, Webpack).

도커 파일을

  1. SDK 받도록 해서 프로젝트폴더를 빌드, 거기서 나온걸 실행하도록 하든
  2. 런타임만 받도록 작성하고, 배포폴더에는 따로 빌드된 버전 파일넣고
    컨테이너를 구성하는 방법이 있을텐데요.

도커가 빌드까지 실행되게 소스코드를 포함한 버전을 배포해야하나?
도커가 빌드는 실행할 필요없이 런타임 버전만 배포해야하나?

라는 고민입니다.

2번이 맞는거 같은데 개발-배포가 지속적으로 이루어지다보면 좀 번거로운 느낌도 들고요.

1 Like

비주얼 스튜디오에서 기본 생성해 주는 Dockerfile은 다음과 같은 형태인데요

# 빌드 단계
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app

# 프로젝트 파일 복사 및 복원
COPY *.csproj ./
RUN dotnet restore

# 소스 코드 복사 및 빌드
COPY . ./
RUN dotnet publish -c Release -o out

# 런타임 단계
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
WORKDIR /app
COPY --from=build /app/out ./
ENTRYPOINT ["dotnet", "YourApp.dll"]

생성된 컨테이너에는 소스 파일이 없죠.

개발-배포가 지속적이려면 CI/CD(gitlab ci, github action, etc…)를 도입하면 해결됩니다.

1 Like

다음과 같은 이유로 저는 2번을 주로 사용합니다.

1. 소스코드 보안

도커 이미지를 컨테이너화하여 실행하게되면 컨테이너 내부 파일들은 아주 쉽게 노출되게 됩니다. 그래서 파이썬 앱의 경우 이런 문제에 특히 취약하여 배포 라인에서 소스코드 난독화를 하기도 합니다.
따라서 소스코드 노출을 최소화하기 위해 빌드 단계와 런타임 단계는 분리하는 것이 좋아 보입니다.

2. 이미지 용량

sdk에는 호스팅에 불필요한 요소들이 포함되어 있기 때문에, 호스팅만을 위한 런타임만 포함하면 이미지 크기를 줄일 수 있습니다.

dockerfile은 한번만 잘 작성해두면 변경할 일이 많지 않으니 크게 번거로우실 것 같진 않고, docker의 경우 이미지 빌드 과정이 다 레이어로 캐싱되기 때문에, 염려하시는 것 만큼 번거롭진 않을 듯 합니다.

4 Likes

도커 이미지가 실행되는 환경을 생각해보면, 실제 런타임만 남기려는 이유는 주로 다음과 같은 부분 때문입니다.

  • 서버가 처음 프로비저닝될 때 (콜드 부팅할 때) 이미지를 다운로드받는데 걸리는 시간을 줄일 수 있습니다. 만약 SDK 이미지를 받아서 쓰게 되면 런타임보다는 기본 이미지 크기가 커지므로 상황에 따라서는 30초 ~ 1분 이상 시간이 걸릴 수 있습니다.
  • 빌드하는 방법에 따라 달라지겠지만, 이미지를 변경/교체할 때 새로 받아야할 레이어의 크기를 런타임 부분만 남겨두는 방식으로 관리하면 좀 더 줄일 여지가 있습니다.

이런 점 때문에 다소 복잡해보이는 멀티스테이지 빌드 방법을 많이 쓴다고 보시면 될 것 같습니다.

2 Likes