Udostępnij za pośrednictwem


Definiowanie aplikacji z wieloma kontenerami za pomocą pliku docker-compose.yml

Napiwek

Ta zawartość jest fragmentem książki eBook, architektury mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET dostępnych na platformie .NET Docs lub jako bezpłatnego pliku PDF, który można odczytać w trybie offline.

Architektura mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET — miniatura książki eBook.

W tym przewodniku plik docker-compose.yml został wprowadzony w sekcji Krok 4. Zdefiniuj usługi w docker-compose.yml podczas kompilowania aplikacji platformy Docker z wieloma kontenerami. Istnieją jednak dodatkowe sposoby korzystania z plików docker-compose, które warto dokładniej zbadać.

Możesz na przykład jawnie opisać sposób wdrażania aplikacji wielokontenerowej w pliku docker-compose.yml. Opcjonalnie możesz również opisać sposób tworzenia niestandardowych obrazów platformy Docker. (Niestandardowe obrazy platformy Docker można również skompilować przy użyciu interfejsu wiersza polecenia platformy Docker).

Zasadniczo definiujesz każdy kontener, który chcesz wdrożyć, oraz pewne cechy dla każdego wdrożenia kontenera. Po utworzeniu pliku opisu wdrożenia z wieloma kontenerami można wdrożyć całe rozwiązanie w ramach jednej akcji orkiestrowanej za pomocą polecenia interfejsu wiersza polecenia docker-compose up lub wdrożyć je w sposób niewidoczny dla programu Visual Studio. W przeciwnym razie należy użyć interfejsu wiersza polecenia platformy Docker do wdrożenia kontenera po kontenerze w wielu krokach przy użyciu docker run polecenia z wiersza polecenia. W związku z tym każda usługa zdefiniowana w docker-compose.yml musi określać dokładnie jeden obraz lub kompilację. Inne klucze są opcjonalne i są analogiczne do ich docker run odpowiedników wiersza polecenia.

Poniższy kod YAML jest definicją możliwego pliku globalnego, ale pojedynczego docker-compose.yml dla przykładu eShopOnContainers. Ten kod nie jest rzeczywistym plikiem docker-compose z aplikacji eShopOnContainers. Zamiast tego jest to uproszczona i skonsolidowana wersja w jednym pliku, która nie jest najlepszym sposobem pracy z plikami docker-compose, jak wyjaśniono później.

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

Kluczem głównym w tym pliku są usługi. W tym kluczu zdefiniujesz usługi, które chcesz wdrożyć i uruchomić podczas wykonywania docker-compose up polecenia lub podczas wdrażania z programu Visual Studio przy użyciu tego pliku docker-compose.yml. W tym przypadku plik docker-compose.yml zawiera wiele zdefiniowanych usług, zgodnie z opisem w poniższej tabeli.

Service name opis
webmvc Kontener zawierający aplikację ASP.NET Core MVC korzystającą z mikrousług po stronie serwera C#
catalog-api Kontener zawierający mikrousługę internetowego interfejsu API ASP.NET Core
ordering-api Kontener zawierający mikrousługę interfejsu API sieci Web ASP.NET Core
sqldata Kontener z uruchomionym programem SQL Server dla systemu Linux, który przechowuje bazy danych mikrousług
koszyk-api Kontener z mikrousługą interfejsu API sieci Web ASP.NET Koszyk
koszykdata Kontener z uruchomioną usługą pamięci podręcznej REDIS z bazą danych koszyka jako pamięcią podręczną REDIS

Prosty kontener interfejsu API usługi internetowej

Koncentrując się na jednym kontenerze, mikrousługa catalog-api container-microservice ma prostą definicję:

  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

Ta konteneryzowana usługa ma następującą podstawową konfigurację:

  • Jest on oparty na niestandardowym obrazie eshop/catalog-api . Dla uproszczenia nie ma kompilacji: ustawienie klucza w pliku. Oznacza to, że obraz musi zostać wcześniej skompilowany (z kompilacją platformy Docker) lub pobrany (za pomocą polecenia ściągania platformy Docker) z dowolnego rejestru platformy Docker.

  • Definiuje zmienną środowiskową o nazwie ConnectionString z parametry połączenia, która ma być używana przez program Entity Framework w celu uzyskania dostępu do wystąpienia programu SQL Server zawierającego model danych wykazu. W takim przypadku ten sam kontener programu SQL Server przechowuje wiele baz danych. W związku z tym potrzebna jest mniejsza ilość pamięci na maszynie deweloperów dla platformy Docker. Można jednak również wdrożyć jeden kontener programu SQL Server dla każdej bazy danych mikrousług.

  • Nazwa programu SQL Server to sqldata, czyli taka sama nazwa, która jest używana dla kontenera z uruchomionym wystąpieniem programu SQL Server dla systemu Linux. Jest to wygodne; możliwość używania tego rozpoznawania nazw (wewnętrznego hosta platformy Docker) rozpozna adres sieciowy, dzięki czemu nie musisz znać wewnętrznego adresu IP kontenerów, do których uzyskujesz dostęp z innych kontenerów.

Ponieważ parametry połączenia jest definiowana przez zmienną środowiskową, można ustawić zmienną za pomocą innego mechanizmu i w innym czasie. Można na przykład ustawić inny parametry połączenia podczas wdrażania w środowisku produkcyjnym na końcowych hostach lub wykonując go z potoków ciągłej integracji/ciągłego wdrażania w usługach Azure DevOps Services lub preferowanym systemie DevOps.

  • Udostępnia port 80 dla wewnętrznego dostępu do usługi catalog-api na hoście platformy Docker. Host jest obecnie maszyną wirtualną z systemem Linux, ponieważ jest oparty na obrazie platformy Docker dla systemu Linux, ale zamiast tego można skonfigurować kontener do uruchamiania na obrazie systemu Windows.

  • Przekazuje on uwidoczniony port 80 w kontenerze do portu 5101 na maszynie hosta platformy Docker (maszyna wirtualna z systemem Linux).

  • Łączy ona usługę internetową z usługą sqldata (wystąpienie programu SQL Server dla bazy danych systemu Linux uruchomionej w kontenerze). Po określeniu tej zależności kontener catalog-api nie zostanie uruchomiony, dopóki kontener sqldata nie zostanie już uruchomiony. Ten aspekt jest ważny, ponieważ najpierw musi być uruchomiona baza danych programu SQL Server. Jednak ten rodzaj zależności kontenera nie jest wystarczający w wielu przypadkach, ponieważ platforma Docker sprawdza tylko na poziomie kontenera. Czasami usługa (w tym przypadku program SQL Server) może nadal nie być gotowa, dlatego zaleca się zaimplementowanie logiki ponawiania próby z wycofywaniem wykładniczym w mikrousług klienta. W ten sposób, jeśli kontener zależności nie jest gotowy przez krótki czas, aplikacja będzie nadal odporna.

  • Jest on skonfigurowany do zezwalania na dostęp do serwerów zewnętrznych: ustawienie extra_hosts umożliwia dostęp do zewnętrznych serwerów lub maszyn spoza hosta platformy Docker (czyli poza domyślną maszyną wirtualną z systemem Linux, która jest hostem deweloperskim platformy Docker), takim jak lokalne wystąpienie programu SQL Server na komputerze deweloperskim.

Istnieją również inne, bardziej zaawansowane docker-compose.yml ustawienia, które omówimy w poniższych sekcjach.

Używanie plików docker-compose do docelowych wielu środowisk

Pliki docker-compose.*.yml są plikami definicji i mogą być używane przez wiele infrastruktur, które rozumieją ten format. Najprostszym narzędziem jest polecenie docker-compose.

W związku z tym za pomocą polecenia docker-compose można kierować do następujących głównych scenariuszy.

Środowiska projektowe

Podczas tworzenia aplikacji ważne jest, aby móc uruchamiać aplikację w izolowanym środowisku projektowym. Możesz użyć polecenia interfejsu wiersza polecenia platformy Docker-compose, aby utworzyć to środowisko lub program Visual Studio, który używa narzędzia docker-compose w ramach okładek.

Plik docker-compose.yml umożliwia konfigurowanie i dokumentowanie wszystkich zależności usługi aplikacji (innych usług, pamięci podręcznej, baz danych, kolejek itp.). Za pomocą polecenia interfejsu wiersza polecenia docker-compose można utworzyć i uruchomić co najmniej jeden kontener dla każdej zależności za pomocą jednego polecenia (docker-compose up).

Pliki docker-compose.yml to pliki konfiguracji interpretowane przez aparat platformy Docker, ale także służą jako wygodne pliki dokumentacji dotyczące kompozycji aplikacji wielokontenerowej.

Środowiska testowe

Ważną częścią każdego procesu ciągłego wdrażania (CD) lub ciągłej integracji (CI) są testy jednostkowe i testy integracji. Te testy automatyczne wymagają środowiska izolowanego, więc nie mają one wpływu na użytkowników ani inne zmiany w danych aplikacji.

Za pomocą narzędzia Docker Compose można utworzyć i zniszczyć środowisko izolowane bardzo łatwo w kilku poleceniach z poziomu wiersza polecenia lub skryptów, takich jak następujące polecenia:

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

Wdrożenia produkcyjne

Możesz również użyć narzędzia Compose do wdrożenia w zdalnym akompanie platformy Docker. Typowym przypadkiem jest wdrożenie w jednym wystąpieniu hosta platformy Docker.

Jeśli używasz innego koordynatora (na przykład usługi Azure Service Fabric lub Kubernetes), może być konieczne dodanie ustawień konfiguracji i metadanych, takich jak te w docker-compose.yml, ale w formacie wymaganym przez innego koordynatora.

W każdym razie narzędzie docker-compose jest wygodnym narzędziem i formatem metadanych dla przepływów pracy tworzenia, testowania i produkcji, chociaż przepływ pracy produkcji może się różnić w zależności od używanego orkiestratora.

Używanie wielu plików docker-compose do obsługi kilku środowisk

W przypadku określania wartości docelowych w różnych środowiskach należy użyć wielu plików redagowania. Takie podejście umożliwia utworzenie wielu wariantów konfiguracji w zależności od środowiska.

Zastępowanie podstawowego pliku docker-compose

Można użyć pojedynczego pliku docker-compose.yml, jak w uproszczonych przykładach przedstawionych w poprzednich sekcjach. Nie jest to jednak zalecane w przypadku większości aplikacji.

Domyślnie compose odczytuje dwa pliki, docker-compose.yml i opcjonalny plik docker-compose.override.yml. Jak pokazano na rysunku 6–11, jeśli używasz programu Visual Studio i włączasz obsługę platformy Docker, program Visual Studio tworzy również dodatkowy plik docker-compose.vs.debug.g.yml do debugowania aplikacji, możesz przyjrzeć się temu plikowi w folderze obj\Docker\ w głównym folderze rozwiązania.

Pliki w projekcie docker compose.

Rysunek 6–11. pliki docker-compose w programie Visual Studio 2019

struktura pliku projektu docker-compose :

  • .dockerignore — używany do ignorowania plików
  • docker-compose.yml — służy do tworzenia mikrousług
  • docker-compose.override.yml — służy do konfigurowania środowiska mikrousług

Możesz edytować pliki docker-compose za pomocą dowolnego edytora, takiego jak Visual Studio Code lub Sublime, i uruchomić aplikację za pomocą polecenia docker-compose up.

Zgodnie z konwencją plik docker-compose.yml zawiera konfigurację podstawową i inne ustawienia statyczne. Oznacza to, że konfiguracja usługi nie powinna się zmieniać w zależności od docelowego środowiska wdrażania.

Plik docker-compose.override.yml, jak sugeruje jego nazwa, zawiera ustawienia konfiguracji, które zastępują podstawową konfigurację, taką jak konfiguracja, która zależy od środowiska wdrażania. Można również mieć wiele przesłonięć plików o różnych nazwach. Pliki przesłonięcia zwykle zawierają dodatkowe informacje wymagane przez aplikację, ale specyficzne dla środowiska lub wdrożenia.

Określanie wielu środowisk

Typowy przypadek użycia polega na zdefiniowaniu wielu plików redagowania, dzięki czemu można kierować do wielu środowisk, takich jak produkcja, przemieszczanie, ciągła integracja lub programowanie. Aby obsługiwać te różnice, możesz podzielić konfigurację redagowania na wiele plików, jak pokazano na rysunku 6–12.

Diagram przedstawiający trzy pliki docker-compose ustawione w celu zastąpienia pliku podstawowego.

Rysunek 6–12. Wiele plików docker-compose przesłaniających wartości w pliku podstawowym docker-compose.yml

W celu obsługi różnych środowisk można połączyć wiele plików docker-compose*.yml. Zaczynasz od podstawowego pliku docker-compose.yml. Ten plik podstawowy zawiera podstawowe lub statyczne ustawienia konfiguracji, które nie zmieniają się w zależności od środowiska. Na przykład aplikacja eShopOnContainers ma następujący plik docker-compose.yml (uproszczony z mniejszą liczbą usług) jako plik podstawowy.

#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

Wartości w podstawowym pliku docker-compose.yml nie powinny zmieniać się z powodu różnych docelowych środowisk wdrażania.

Jeśli na przykład skoncentrujesz się na definicji usługi webmvc, możesz zobaczyć, jak te informacje są takie same niezależnie od tego, jakie środowisko można kierować. Masz następujące informacje:

  • Nazwa usługi: webmvc.

  • Obraz niestandardowy kontenera: eshop/webmvc.

  • Polecenie kompilowania niestandardowego obrazu platformy Docker wskazującego, który plik Dockerfile ma być używany.

  • Zależności od innych usług, więc ten kontener nie jest uruchamiany do momentu uruchomienia innych kontenerów zależności.

Możesz mieć dodatkową konfigurację, ale ważnym punktem jest to, że w pliku podstawowym docker-compose.yml chcesz po prostu ustawić informacje wspólne w różnych środowiskach. Następnie w docker-compose.override.yml lub podobnych plikach dla środowiska produkcyjnego lub przejściowego należy umieścić konfigurację specyficzną dla każdego środowiska.

Zazwyczaj docker-compose.override.yml jest używany dla środowiska deweloperskiego, jak w poniższym przykładzie z 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"

W tym przykładzie konfiguracja programowania przesłaniania uwidacznia niektóre porty na hoście, definiuje zmienne środowiskowe z adresami URL przekierowania i określa parametry połączenia dla środowiska deweloperskiego. Te ustawienia są przeznaczone tylko dla środowiska deweloperskiego.

Po uruchomieniu (lub uruchomieniu docker-compose up go z programu Visual Studio) polecenie odczytuje przesłonięcia automatycznie tak, jakby scalało oba pliki.

Załóżmy, że chcesz utworzyć inny plik dla środowiska produkcyjnego z różnymi wartościami konfiguracji, portami lub parametry połączenia. Możesz utworzyć inny plik zastąpienia, taki jak plik o nazwie docker-compose.prod.yml z różnymi ustawieniami i zmiennymi środowiskowymi. Ten plik może być przechowywany w innym repozytorium Git lub zarządzanym i zabezpieczonym przez inny zespół.

Jak wdrożyć za pomocą określonego pliku przesłonięcia

Aby użyć wielu przesłonięć plików lub przesłonięcia pliku o innej nazwie, możesz użyć opcji -f z poleceniem docker-compose i określić pliki. Redagowanie scala pliki w kolejności, w której są określone w wierszu polecenia. W poniższym przykładzie pokazano, jak wdrożyć za pomocą przesłonięć plików.

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

Używanie zmiennych środowiskowych w plikach docker-compose

Jest to wygodne, szczególnie w środowiskach produkcyjnych, aby móc uzyskać informacje o konfiguracji ze zmiennych środowiskowych, jak pokazano w poprzednich przykładach. Możesz odwołać się do zmiennej środowiskowej w plikach docker-compose przy użyciu składni ${MY_VAR}. Poniższy wiersz z pliku docker-compose.prod.yml pokazuje, jak odwoływać się do wartości zmiennej środowiskowej.

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

Zmienne środowiskowe są tworzone i inicjowane na różne sposoby w zależności od środowiska hosta (Linux, Windows, Cloud cluster itp.). Jednak wygodnym podejściem jest użycie pliku env. Pliki docker-compose obsługują deklarowanie domyślnych zmiennych środowiskowych w pliku env. Te wartości zmiennych środowiskowych są wartościami domyślnymi. Można je jednak zastąpić wartościami zdefiniowanymi w poszczególnych środowiskach (system operacyjny hosta lub zmienne środowiskowe z klastra). Ten plik env należy umieścić w folderze, z którego jest wykonywane polecenie docker-compose.

W poniższym przykładzie pokazano plik env, taki jak plik env dla aplikacji eShopOnContainers.

# .env file

ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal

ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92

Docker-compose oczekuje, że każdy wiersz w pliku env będzie w formacie <variable>=<value>.

Wartości ustawione w środowisku czasu wykonywania zawsze zastępują wartości zdefiniowane w pliku env. W podobny sposób wartości przekazywane za pośrednictwem argumentów wiersza polecenia zastępują również wartości domyślne ustawione w pliku env.

Dodatkowe zasoby

Kompilowanie zoptymalizowanych obrazów platformy Docker ASP.NET Core

Jeśli eksplorujesz platformę Docker i platformę .NET w źródłach w Internecie, znajdziesz pliki Dockerfile, które pokazują prostotę tworzenia obrazu platformy Docker przez skopiowanie źródła do kontenera. Te przykłady sugerują, że przy użyciu prostej konfiguracji możesz mieć obraz platformy Docker ze środowiskiem spakowanym przy użyciu aplikacji. W poniższym przykładzie pokazano prosty plik Dockerfile w tym środowisku.

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

Plik Dockerfile podobny do tego będzie działać. Można jednak znacznie zoptymalizować obrazy, zwłaszcza obrazy produkcyjne.

W modelu kontenerów i mikrousług stale uruchamiasz kontenery. Typowy sposób korzystania z kontenerów nie powoduje ponownego uruchomienia kontenera uśpienia, ponieważ kontener jest jednorazowy. Orkiestratory (takie jak Kubernetes i Azure Service Fabric) tworzą nowe wystąpienia obrazów. Oznacza to konieczność optymalizacji przez wstępne skompilowanie aplikacji, aby proces tworzenia wystąpienia był szybszy. Po uruchomieniu kontenera powinien być gotowy do uruchomienia. Nie przywracaj i kompiluj w czasie wykonywania przy użyciu poleceń interfejsu dotnet restore wiersza polecenia i dotnet build , jak można zobaczyć we wpisach w blogu dotyczących platformy .NET i platformy Docker.

Zespół platformy .NET wykonuje ważną pracę, aby platforma .NET i ASP.NET Core stała się strukturą zoptymalizowaną pod kątem kontenerów. Nie tylko platforma .NET jest uproszczoną strukturą o małym rozmiarze pamięci; zespół skupił się na zoptymalizowanych obrazach platformy Docker pod kątem trzech głównych scenariuszy i opublikował je w rejestrze usługi Docker Hub pod adresem dotnet/, począwszy od wersji 2.1:

  • Programowanie: Priorytetem jest możliwość szybkiego iterowania i debugowania zmian oraz miejsca, w którym rozmiar jest pomocniczy.
  • Kompilacja: Priorytetem jest kompilowanie aplikacji, a obraz zawiera pliki binarne i inne zależności w celu optymalizacji plików binarnych.
  • Produkcja: Koncentruje się na szybkim wdrażaniu i uruchamianiu kontenerów, więc te obrazy są ograniczone do plików binarnych i zawartości potrzebnej do uruchomienia aplikacji.

Zespół platformy .NET udostępnia kilka podstawowych wariantów w systemie dotnet/, na przykład:

  • zestaw SDK: na potrzeby scenariuszy programowania i kompilacji
  • aspnet: w przypadku scenariuszy ASP.NET produkcyjnych
  • środowisko uruchomieniowe: w scenariuszach produkcyjnych platformy .NET
  • runtime-deps: w przypadku scenariuszy produkcyjnych aplikacji samodzielnie zawartych

W celu szybszego uruchamiania obrazy środowiska uruchomieniowego również automatycznie ustawiają aspnetcore_urls na port 80 i używają narzędzia Ngen do utworzenia natywnej pamięci podręcznej obrazów zestawów.

Dodatkowe zasoby