다음을 통해 공유


docker-compose.yml 사용하여 다중 컨테이너 애플리케이션 정의

팁 (조언)

이 콘텐츠는 .NET Docs 또는 오프라인으로 읽을 수 있는 다운로드 가능한 무료 PDF로 제공되는 컨테이너화된 .NET 애플리케이션용 .NET 마이크로 서비스 아키텍처인 eBook에서 발췌한 내용입니다.

컨테이너화된 .NET 애플리케이션을 위한 .NET 마이크로서비스 아키텍처 eBook의 표지 썸네일.

이 가이드에서는 4단계 섹션에서 docker-compose.yml 파일을 소개했습니다 . 다중 컨테이너 Docker 애플리케이션을 빌드할 때 docker-compose.yml 서비스를 정의합니다. 그러나 더 자세히 살펴볼 가치가 있는 docker-compose 파일을 사용하는 추가 방법이 있습니다.

예를 들어 docker-compose.yml 파일에 다중 컨테이너 애플리케이션을 배포하는 방법을 명시적으로 설명할 수 있습니다. 필요에 따라 사용자 지정 Docker 이미지를 빌드하는 방법을 설명할 수도 있습니다. (사용자 지정 Docker 이미지는 Docker CLI를 사용하여 빌드할 수도 있습니다.)

기본적으로 배포하려는 각 컨테이너와 각 컨테이너 배포에 대한 특정 특성을 정의합니다. 다중 컨테이너 배포 설명 파일이 있으면 docker-compose up CLI 명령으로 오케스트레이션된 단일 작업에서 전체 솔루션을 배포하거나 Visual Studio에서 투명하게 배포할 수 있습니다. 그렇지 않으면 명령줄에서 docker run 명령을 사용하여 여러 단계로 Docker CLI를 통해 컨테이너 하나하나를 배포해야 합니다. 따라서 docker-compose.yml 정의된 각 서비스는 정확히 하나의 이미지 또는 빌드를 지정해야 합니다. 다른 키는 선택 사항이며 명령줄과 유사 docker run 합니다.

다음 YAML 코드는 eShopOnContainers 샘플을 위한 전역적으로 사용되는 단일 docker-compose.yml 파일의 정의입니다. 이 코드는 eShopOnContainers의 실제 docker-compose 파일이 아닙니다. 대신, 나중에 설명한 대로 docker-compose 파일을 사용하는 가장 좋은 방법은 아닌 단일 파일의 간소화되고 통합된 버전입니다.

version: '3.4'

services:
  webmvc:
    image: eshop/webmvc
    environment:
      - CatalogUrl=http://catalog-api
      - OrderingUrl=http://ordering-api
      - BasketUrl=http://basket-api
    ports:
      - "5100:80"
    depends_on:
      - catalog-api
      - ordering-api
      - basket-api

  catalog-api:
    image: eshop/catalog-api
    environment:
      - ConnectionString=Server=sqldata;Initial Catalog=CatalogData;User Id=sa;Password=[PLACEHOLDER]
    expose:
      - "80"
    ports:
      - "5101:80"
    #extra hosts can be used for standalone SQL Server or services at the dev PC
    extra_hosts:
      - "CESARDLSURFBOOK:10.0.75.1"
    depends_on:
      - sqldata

  ordering-api:
    image: eshop/ordering-api
    environment:
      - ConnectionString=Server=sqldata;Database=Services.OrderingDb;User Id=sa;Password=[PLACEHOLDER]
    ports:
      - "5102:80"
    #extra hosts can be used for standalone SQL Server or services at the dev PC
    extra_hosts:
      - "CESARDLSURFBOOK:10.0.75.1"
    depends_on:
      - sqldata

  basket-api:
    image: eshop/basket-api
    environment:
      - ConnectionString=sqldata
    ports:
      - "5103:80"
    depends_on:
      - sqldata

  sqldata:
    environment:
      - SA_PASSWORD=[PLACEHOLDER]
      - ACCEPT_EULA=Y
    ports:
      - "5434:1433"

  basketdata:
    image: redis

이 파일의 루트 키는 서비스입니다. 이 키 아래에서, docker-compose up 명령을 실행하거나 이 docker-compose.yml 파일을 사용하여 Visual Studio에서 배포할 때 배포하고 실행할 서비스를 정의합니다. 이 경우 docker-compose.yml 파일에는 다음 표에 설명된 대로 여러 서비스가 정의되어 있습니다.

서비스 이름 설명
webmvc 서버 쪽 C에서 마이크로 서비스를 사용하는 ASP.NET Core MVC 애플리케이션을 포함한 컨테이너#
카탈로그 API 카탈로그 ASP.NET Core Web API 마이크로 서비스를 포함한 컨테이너
주문 API ASP.NET Core Web API 마이크로 서비스 주문 기능을 포함한 컨테이너
sqldata Linux용 SQL Server를 실행하는 컨테이너, 마이크로 서비스 데이터베이스 보유
basket-api Basket ASP.NET Core Web API 마이크로 서비스를 사용하는 컨테이너
바구니 데이터 BASKET 데이터베이스를 REDIS 캐시로 사용하여 REDIS 캐시 서비스를 실행하는 컨테이너

간단한 웹 서비스 API 컨테이너

단일 컨테이너에 초점을 맞춘 catalog-api 컨테이너-마이크로 서비스에는 다음과 같은 간단한 정의가 있습니다.

  catalog-api:
    image: eshop/catalog-api
    environment:
      - ConnectionString=Server=sqldata;Initial Catalog=CatalogData;User Id=sa;Password=[PLACEHOLDER]
    expose:
      - "80"
    ports:
      - "5101:80"
    #extra hosts can be used for standalone SQL Server or services at the dev PC
    extra_hosts:
      - "CESARDLSURFBOOK:10.0.75.1"
    depends_on:
      - sqldata

컨테이너화된 이 서비스에는 다음과 같은 기본 구성이 있습니다.

  • 사용자 지정 eshop/catalog-api 이미지를 기반으로 합니다. 단순함을 위해 파일에 'build:' 키 설정이 없습니다. 즉, 이미지가 이전에 빌드되었거나(docker 빌드를 사용하여) Docker 레지스트리에서 다운로드(docker pull 명령 포함)되었어야 합니다.

  • Entity Framework에서 카탈로그 데이터 모델을 포함하는 SQL Server 인스턴스에 액세스하는 데 사용할 연결 문자열을 사용하여 ConnectionString이라는 환경 변수를 정의합니다. 이 경우 동일한 SQL Server 컨테이너가 여러 데이터베이스를 보유하고 있습니다. 따라서 Docker용 개발 머신에 더 적은 메모리가 필요합니다. 그러나 각 마이크로 서비스 데이터베이스에 대해 하나의 SQL Server 컨테이너를 배포할 수도 있습니다.

  • SQL Server 이름은 Sqldata로, Linux용 SQL Server 인스턴스를 실행하는 컨테이너에 사용되는 것과 동일한 이름입니다. 이 기능은 편리합니다. 이 이름 확인(Docker 호스트 내부)을 사용할 수 있으면 네트워크 주소가 확인되므로 다른 컨테이너에서 액세스하는 컨테이너의 내부 IP를 알 필요가 없습니다.

연결 문자열은 환경 변수에 의해 정의되므로 다른 메커니즘을 통해 다른 시간에 해당 변수를 설정할 수 있습니다. 예를 들어 최종 호스트에서 프로덕션에 배포하거나 Azure DevOps Services 또는 선호하는 DevOps 시스템의 CI/CD 파이프라인에서 배포할 때 다른 연결 문자열을 설정할 수 있습니다.

  • Docker 호스트 내 의 catalog-api 서비스에 대한 내부 액세스를 위해 포트 80을 노출합니다. 호스트는 Linux용 Docker 이미지를 기반으로 하기 때문에 현재 Linux VM이지만 대신 Windows 이미지에서 실행되도록 컨테이너를 구성할 수 있습니다.

  • 컨테이너의 노출된 포트 80을 Docker 호스트 컴퓨터(Linux VM)의 포트 5101로 전달합니다.

  • 웹 서비스를 sqldata 서비스(컨테이너에서 실행되는 Linux 데이터베이스용 SQL Server 인스턴스)에 연결합니다. 이 종속성을 지정하면 sqldata 컨테이너가 이미 시작될 때까지 catalog-api 컨테이너가 시작되지 않습니다. catalog-api는 SQL Server 데이터베이스를 먼저 실행해야 하므로 이 측면이 중요합니다. 그러나 Docker는 컨테이너 수준에서만 검사하기 때문에 이러한 종류의 컨테이너 종속성만으로는 충분하지 않습니다. 경우에 따라 서비스(이 경우 SQL Server)가 아직 준비되지 않을 수 있으므로 클라이언트 마이크로 서비스에서 지수 백오프를 사용하여 재시도 논리를 구현하는 것이 좋습니다. 이렇게 하면 종속성 컨테이너가 짧은 시간 동안 준비되지 않은 경우에도 애플리케이션은 복원력이 있습니다.

  • 외부 서버에 대한 액세스를 허용하도록 구성됩니다. extra_hosts 설정을 사용하면 개발 PC의 로컬 SQL Server 인스턴스와 같이 Docker 호스트 외부(즉, 개발 Docker 호스트인 기본 Linux VM 외부)의 외부 서버 또는 컴퓨터에 액세스할 수 있습니다.

또한 다음 섹션에서 설명하는 다른 고급 docker-compose.yml 설정도 있습니다.

docker-compose 파일을 사용하여 여러 환경 대상으로 지정

파일은 docker-compose.*.yml 정의 파일이며 해당 형식을 이해하는 여러 인프라에서 사용할 수 있습니다. 가장 간단한 도구는 docker-compose 명령입니다.

따라서 docker-compose 명령을 사용하여 다음 주요 시나리오를 대상으로 지정할 수 있습니다.

개발 환경

애플리케이션을 개발할 때는 격리된 개발 환경에서 애플리케이션을 실행할 수 있어야 합니다. docker-compose CLI 명령 또는 Visual Studio를 사용하여 해당 환경을 만들 수 있습니다. Visual Studio는 내부적으로 docker-compose를 사용합니다.

docker-compose.yml 파일을 사용하면 애플리케이션의 모든 서비스 종속성(기타 서비스, 캐시, 데이터베이스, 큐 등)을 구성하고 문서화할 수 있습니다. docker-compose CLI 명령을 사용하여 단일 명령(docker-compose up)을 사용하여 각 종속성에 대해 하나 이상의 컨테이너를 만들고 시작할 수 있습니다.

docker-compose.yml 파일은 Docker 엔진에서 해석되는 구성 파일이지만 다중 컨테이너 애플리케이션의 구성에 대한 편리한 설명서 파일로도 사용됩니다.

테스트 환경

CD(지속적인 배포) 또는 CI(연속 통합) 프로세스의 중요한 부분은 단위 테스트 및 통합 테스트입니다. 이러한 자동화된 테스트에는 격리된 환경이 필요하므로 사용자 또는 애플리케이션 데이터의 다른 변경 내용의 영향을 받지 않습니다.

Docker Compose를 사용하면 다음 명령과 같이 명령 프롬프트 또는 스크립트의 몇 가지 명령에서 격리된 환경을 매우 쉽게 만들고 제거할 수 있습니다.

docker-compose -f docker-compose.yml -f docker-compose-test.override.yml up -d
./run_unit_tests
docker-compose -f docker-compose.yml -f docker-compose-test.override.yml down

프로덕션 배포

Compose를 사용하여 원격 Docker 엔진에 배포할 수도 있습니다. 일반적인 경우는 단일 Docker 호스트 인스턴스에 배포하는 것입니다.

다른 오케스트레이터(예: Azure Service Fabric 또는 Kubernetes)를 사용하는 경우 docker-compose.yml 다른 오케스트레이터에 필요한 형식으로 설정 및 메타데이터 구성 설정을 추가해야 할 수 있습니다.

어떤 경우든 docker-compose는 개발, 테스트 및 프로덕션 워크플로를 위한 편리한 도구 및 메타데이터 형식이지만 프로덕션 워크플로는 사용 중인 오케스트레이터에 따라 다를 수 있습니다.

여러 docker-compose 파일을 사용하여 여러 환경 처리

다른 환경을 대상으로 하는 경우 여러 작성 파일을 사용해야 합니다. 이 방법을 사용하면 환경에 따라 여러 구성 변형을 만들 수 있습니다.

기본 docker-compose 파일 재정의

이전 섹션에 표시된 간소화된 예제와 같이 단일 docker-compose.yml 파일을 사용할 수 있습니다. 그러나 대부분의 애플리케이션에는 권장되지 않습니다.

기본적으로 Compose는 docker-compose.yml 및 선택적 docker-compose.override.yml 파일이라는 두 개의 파일을 읽습니다. 그림 6-11과 같이 Visual Studio를 사용하고 Docker 지원을 사용하도록 설정하는 경우 Visual Studio는 애플리케이션을 디버깅하기 위한 추가 docker-compose.vs.debug.g.yml 파일을 만듭니다. 기본 솔루션 폴더의 obj\Docker\ 폴더에서 이 파일을 살펴볼 수 있습니다.

Docker 작성 프로젝트의 파일입니다.

그림 6-11. Visual Studio 2019의 docker-compose 파일

docker-compose 프로젝트 파일 구조:

  • .dockerignore - 파일을 무시하는 데 사용됨
  • docker-compose.yml - 마이크로 서비스를 구성하는 데 사용
  • docker-compose.override.yml - 마이크로 서비스 환경을 구성하는 데 사용됨

Visual Studio Code 또는 Sublime과 같은 편집기를 사용하여 docker-compose 파일을 편집하고 docker-compose up 명령을 사용하여 애플리케이션을 실행할 수 있습니다.

규칙에 따라 docker-compose.yml 파일에는 기본 구성 및 기타 정적 설정이 포함됩니다. 즉, 대상으로 하는 배포 환경에 따라 서비스 구성이 변경되지 않아야 합니다.

이름에서 설명한 대로 docker-compose.override.yml 파일에는 배포 환경에 따라 달라지는 구성과 같이 기본 구성을 재정의하는 구성 설정이 포함되어 있습니다. 이름이 다른 파일을 여러 개 재정의할 수도 있습니다. 재정의 파일에는 일반적으로 애플리케이션에 필요하지만 환경 또는 배포와 관련된 추가 정보가 포함됩니다.

여러 환경 대상 지정

일반적인 사용 사례는 프로덕션, 스테이징, CI 또는 개발과 같은 여러 환경을 대상으로 지정할 수 있도록 여러 작성 파일을 정의하는 경우입니다. 이러한 차이를 지원하기 위해 그림 6-12와 같이 Compose 구성을 여러 파일로 분할할 수 있습니다.

기본 파일을 재정의하도록 설정된 세 개의 docker-compose 파일 다이어그램

그림 6-12. 여러 docker-compose 파일이 기본 docker-compose.yml 파일에서 설정 값을 덮어씁니다.

여러 docker-compose*.yml 파일을 결합하여 다양한 환경을 처리할 수 있습니다. 기본 docker-compose.yml 파일로 시작합니다. 이 기본 파일에는 환경에 따라 변경되지 않는 기본 또는 정적 구성 설정이 포함되어 있습니다. 예를 들어 eShopOnContainers 앱에는 기본 파일로 다음과 같은 docker-compose.yml 파일(더 적은 수의 서비스로 간소화됨)이 있습니다.

#docker-compose.yml (Base)
version: '3.4'
services:
  basket-api:
    image: eshop/basket-api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Basket/Basket.API/Dockerfile
    depends_on:
      - basketdata
      - identity-api
      - rabbitmq

  catalog-api:
    image: eshop/catalog-api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
    depends_on:
      - sqldata
      - rabbitmq

  marketing-api:
    image: eshop/marketing-api:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Services/Marketing/Marketing.API/Dockerfile
    depends_on:
      - sqldata
      - nosqldata
      - identity-api
      - rabbitmq

  webmvc:
    image: eshop/webmvc:${TAG:-latest}
    build:
      context: .
      dockerfile: src/Web/WebMVC/Dockerfile
    depends_on:
      - catalog-api
      - ordering-api
      - identity-api
      - basket-api
      - marketing-api

  sqldata:
    image: mcr.microsoft.com/mssql/server:2019-latest

  nosqldata:
    image: mongo

  basketdata:
    image: redis

  rabbitmq:
    image: rabbitmq:3-management

기본 docker-compose.yml 파일의 값은 서로 다른 대상 배포 환경 때문에 변경되지 않아야 합니다.

예를 들어 webmvc 서비스 정의에 집중하는 경우 대상으로 지정할 수 있는 환경에 관계없이 해당 정보가 어떻게 동일한지 확인할 수 있습니다. 다음과 같은 정보가 있습니다.

  • 서비스 이름: webmvc.

  • 컨테이너의 사용자 지정 이미지: eshop/webmvc.

  • 사용할 Dockerfile을 나타내는 사용자 지정 Docker 이미지를 빌드하는 명령입니다.

  • 다른 서비스에 대한 종속성이므로 이 컨테이너는 다른 종속성 컨테이너가 시작될 때까지 시작되지 않습니다.

추가 구성을 사용할 수 있지만 중요한 점은 기본 docker-compose.yml 파일에서 환경 간에 공통적인 정보를 설정하려고 한다는 것입니다. 그런 다음 프로덕션 또는 스테이징에 대한 docker-compose.override.yml 또는 유사한 파일에서 각 환경에 특정한 구성을 배치해야 합니다.

일반적으로 docker-compose.override.yml eShopOnContainers의 다음 예제와 같이 개발 환경에 사용됩니다.

#docker-compose.override.yml (Extended config for DEVELOPMENT env.)
version: '3.4'

services:
# Simplified number of services here:

  basket-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_REDIS_BASKET_DB:-basketdata}
      - identityUrl=http://identity-api
      - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
      - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
      - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
      - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
      - AzureServiceBusEnabled=False
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
      - UseLoadTest=${USE_LOADTEST:-False}

    ports:
      - "5103:80"

  catalog-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_CATALOG_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=[PLACEHOLDER]}
      - PicBaseUrl=${ESHOP_AZURE_STORAGE_CATALOG_URL:-http://host.docker.internal:5202/api/v1/catalog/items/[0]/pic/}
      - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
      - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
      - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
      - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_CATALOG_NAME}
      - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_CATALOG_KEY}
      - UseCustomizationData=True
      - AzureServiceBusEnabled=False
      - AzureStorageEnabled=False
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
    ports:
      - "5101:80"

  marketing-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - ConnectionString=${ESHOP_AZURE_MARKETING_DB:-Server=sqldata;Database=Microsoft.eShopOnContainers.Services.MarketingDb;User Id=sa;Password=[PLACEHOLDER]}
      - MongoConnectionString=${ESHOP_AZURE_COSMOSDB:-mongodb://nosqldata}
      - MongoDatabase=MarketingDb
      - EventBusConnection=${ESHOP_AZURE_SERVICE_BUS:-rabbitmq}
      - EventBusUserName=${ESHOP_SERVICE_BUS_USERNAME}
      - EventBusPassword=${ESHOP_SERVICE_BUS_PASSWORD}
      - identityUrl=http://identity-api
      - IdentityUrlExternal=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105
      - CampaignDetailFunctionUri=${ESHOP_AZUREFUNC_CAMPAIGN_DETAILS_URI}
      - PicBaseUrl=${ESHOP_AZURE_STORAGE_MARKETING_URL:-http://host.docker.internal:5110/api/v1/campaigns/[0]/pic/}
      - AzureStorageAccountName=${ESHOP_AZURE_STORAGE_MARKETING_NAME}
      - AzureStorageAccountKey=${ESHOP_AZURE_STORAGE_MARKETING_KEY}
      - AzureServiceBusEnabled=False
      - AzureStorageEnabled=False
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
      - UseLoadTest=${USE_LOADTEST:-False}
    ports:
      - "5110:80"

  webmvc:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - PurchaseUrl=http://webshoppingapigw
      - IdentityUrl=http://10.0.75.1:5105
      - MarketingUrl=http://webmarketingapigw
      - CatalogUrlHC=http://catalog-api/hc
      - OrderingUrlHC=http://ordering-api/hc
      - IdentityUrlHC=http://identity-api/hc
      - BasketUrlHC=http://basket-api/hc
      - MarketingUrlHC=http://marketing-api/hc
      - PaymentUrlHC=http://payment-api/hc
      - SignalrHubUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5202
      - UseCustomizationData=True
      - ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
      - OrchestratorType=${ORCHESTRATOR_TYPE}
      - UseLoadTest=${USE_LOADTEST:-False}
    ports:
      - "5100:80"
  sqldata:
    environment:
      - SA_PASSWORD=[PLACEHOLDER]
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"
  nosqldata:
    ports:
      - "27017:27017"
  basketdata:
    ports:
      - "6379:6379"
  rabbitmq:
    ports:
      - "15672:15672"
      - "5672:5672"

이 예제에서 개발 재정의 구성은 호스트에 일부 포트를 노출하고 리디렉션 URL을 사용하여 환경 변수를 정의하며 개발 환경에 대한 연결 문자열을 지정합니다. 이러한 설정은 모두 개발 환경에만 사용됩니다.

docker-compose up를 실행하거나 Visual Studio에서 실행할 때 명령은 두 파일을 병합하는 것처럼 자동으로 설정을 읽습니다.

다른 구성 값, 포트 또는 연결 문자열을 사용하여 프로덕션 환경에 다른 Compose 파일을 사용하려는 경우를 가정해 보겠습니다. 다른 설정 및 환경 변수를 사용하여 명명된 docker-compose.prod.yml 파일과 같은 다른 재정의 파일을 만들 수 있습니다. 해당 파일은 다른 Git 리포지토리에 저장되거나 다른 팀에서 관리하고 보호될 수 있습니다.

특정 오버라이드 파일을 사용하여 배포하는 방법

여러 재정의 파일 또는 다른 이름의 재정의 파일을 사용하려면 docker-compose 명령과 함께 -f 옵션을 사용하고 파일을 지정할 수 있습니다. 컴포즈는 명령줄에 지정된 순서대로 파일을 병합합니다. 다음 예제에서는 재정의 파일을 사용하여 배포하는 방법을 보여줍니다.

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

docker-compose 파일에서 환경 변수 사용

이전 예제와 같이 환경 변수에서 구성 정보를 가져올 수 있는 것이 특히 프로덕션 환경에서 편리합니다. ${MY_VAR} 구문을 사용하여 docker-compose 파일에서 환경 변수를 참조할 수 있습니다. docker-compose.prod.yml 파일의 다음 줄에서는 환경 변수의 값을 참조하는 방법을 보여 줍니다.

IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105

환경 변수는 호스트 환경(Linux, Windows, 클라우드 클러스터 등)에 따라 다양한 방법으로 만들어지고 초기화됩니다. 그러나 편리한 방법은 .env 파일을 사용하는 것입니다. docker-compose 파일은 .env 파일에서 기본 환경 변수 선언을 지원합니다. 환경 변수에 대한 이러한 값은 기본값입니다. 그러나 각 환경(호스트 OS 또는 클러스터의 환경 변수)에서 정의한 값으로 덮어쓸 수 있습니다. docker-compose 명령이 실행되는 폴더에 이 .env 파일을 배치합니다.

다음 예제에서는 eShopOnContainers 애플리케이션에 대한 .env 파일과 같은 .env 파일을 보여줍니다.

# .env file

ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal

ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92

Docker-compose는 .env 파일의 각 줄이 <변수>=<값> 형식이어야 합니다.

런타임 환경에 설정된 값은 항상 .env 파일 내에 정의된 값을 재정의합니다. 마찬가지로 명령줄 인수를 통해 전달되는 값도 .env 파일에 설정된 기본값을 재정의합니다.

추가 리소스

최적화된 ASP.NET Core Docker 이미지 빌드

인터넷의 원본에서 Docker 및 .NET을 탐색하는 경우 원본을 컨테이너에 복사하여 Docker 이미지를 빌드하는 단순성을 보여 주는 Dockerfiles를 찾을 수 있습니다. 이러한 예제에서는 간단한 구성을 사용하여 애플리케이션으로 패키지된 환경이 있는 Docker 이미지를 가질 수 있음을 시사합니다. 다음 예제에서는 이 맥락에서 간단한 Dockerfile을 보여줍니다.

FROM mcr.microsoft.com/dotnet/sdk:8.0
WORKDIR /app
ENV ASPNETCORE_URLS http://+:80
EXPOSE 80
COPY . .
RUN dotnet restore
ENTRYPOINT ["dotnet", "run"]

이와 같은 Dockerfile이 작동합니다. 그러나 이미지, 특히 프로덕션 이미지를 크게 최적화할 수 있습니다.

컨테이너 및 마이크로 서비스 모델에서는 컨테이너를 지속적으로 시작합니다. 컨테이너를 사용하는 일반적인 방법은 컨테이너가 삭제 가능하기 때문에 절전 모드 컨테이너를 다시 시작하지 않습니다. 오케스트레이터(예: Kubernetes 및 Azure Service Fabric)는 이미지의 새 인스턴스를 만듭니다. 즉, 인스턴스화 프로세스가 더 빨라지도록 애플리케이션을 빌드할 때 미리 컴파일하여 최적화해야 합니다. 컨테이너가 시작되면 실행할 준비가 되어 있어야 합니다. .NET 및 Docker에 대한 블로그 게시물에서 볼 수 있듯이 런타임에 CLI 명령을 사용하여 dotnet restoredotnet build 복원하고 컴파일하지 마세요.

.NET 팀은 .NET 및 ASP.NET Core를 컨테이너 최적화 프레임워크로 만들기 위해 중요한 작업을 수행해 왔습니다. .NET은 메모리 공간이 작은 경량 프레임워크일 뿐만 아니라 팀은 세 가지 주요 시나리오에 최적화된 Docker 이미지에 초점을 맞추고 버전 2.1부터 dotnet/의 Docker Hub 레지스트리에 게시했습니다.

  • 개발: 우선 순위는 변경 사항을 신속하게 반복하고 디버그할 수 있는 기능이며, 크기는 부차적인 요소입니다.
  • 빌드: 우선 순위는 애플리케이션을 컴파일하는 것입니다. 이미지에는 바이너리 및 기타 종속성을 포함하여 바이너리를 최적화합니다.
  • 프로덕션: 컨테이너를 빠르게 배포하고 시작하는 데 중점을 두므로 이러한 이미지는 애플리케이션을 실행하는 데 필요한 이진 파일 및 콘텐츠로 제한됩니다.

.NET 팀은 dotnet/에서 다음과 같은 몇 가지 기본 변형을 제공합니다.

  • sdk: 개발 및 빌드 시나리오용
  • aspnet: ASP.NET 프로덕션 시나리오의 경우
  • 런타임: .NET 프로덕션 시나리오의 경우
  • runtime-deps: 자체 포함 애플리케이션의 프로덕션 시나리오를 위한

더 빠른 시작을 위해 런타임 이미지는 aspnetcore_urls 포트 80으로 자동으로 설정하고 Ngen을 사용하여 어셈블리의 네이티브 이미지 캐시를 만듭니다.

추가 리소스