Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Tipp
Dieser Inhalt ist ein Auszug aus dem eBook .NET Microservices Architecture for Containerized .NET Applications, verfügbar auf .NET Docs oder als kostenlose herunterladbare PDF, die offline gelesen werden kann.
In diesem Handbuch wurde die docker-compose.yml Datei im Abschnitt Schritt 4 eingeführt. Definieren Sie Ihre Dienste in docker-compose.yml beim Erstellen einer Docker-Anwendung mit mehreren Containern. Es gibt jedoch zusätzliche Möglichkeiten, die Docker-Compose-Dateien zu verwenden, die es wert sind, ausführlicher zu untersuchen.
Sie können beispielsweise explizit beschreiben, wie Sie Ihre Multicontaineranwendung in der docker-compose.yml-Datei bereitstellen möchten. Optional können Sie auch beschreiben, wie Sie Ihre benutzerdefinierten Docker-Images erstellen. (Benutzerdefinierte Docker-Images können auch mit der Docker CLI erstellt werden.)
Grundsätzlich definieren Sie jeden container, den Sie bereitstellen möchten, sowie bestimmte Merkmale für jede Containerbereitstellung. Sobald Sie über eine Beschreibungsdatei für die Bereitstellung mit mehreren Containern verfügen, können Sie die gesamte Lösung in einer einzigen Aktion bereitstellen, die vom Befehl docker-compose up CLI koordiniert wird, oder Sie können sie transparent in Visual Studio bereitstellen. Andernfalls müssten Sie die Docker-CLI verwenden, um jeden Container einzeln in mehreren Schritten mithilfe des docker run
-Befehls über die Befehlszeile zu deployen. Daher muss jeder in docker-compose.yml definierte Dienst genau ein Image oder Build angeben. Andere Tasten sind optional und entsprechen ihren docker run
Befehlszeilenentsprechungen.
Der folgende YAML-Code ist die Definition einer möglichen globalen, aber einzelnen docker-compose.yml Datei für das eShopOnContainers-Beispiel. Dieser Code ist nicht die eigentliche Docker-Compose-Datei von eShopOnContainers. Stattdessen handelt es sich um eine vereinfachte und konsolidierte Version in einer einzelnen Datei, die nicht die beste Möglichkeit ist, mit Docker-Compose-Dateien zu arbeiten, wie später erläutert wird.
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
Der Stammschlüssel in dieser Datei ist Dienste. Unter diesem Schlüssel definieren Sie die Dienste, die Sie bereitstellen und ausführen möchten, wenn Sie den docker-compose up
Befehl ausführen oder wenn Sie über Visual Studio mithilfe dieser docker-compose.yml Datei bereitstellen. In diesem Fall hat die datei docker-compose.yml mehrere Dienste definiert, wie in der folgenden Tabelle beschrieben.
Dienstname | BESCHREIBUNG |
---|---|
webmvc | Container, einschließlich der ASP.NET Core-MVC-Anwendung, die die Microservices der serverseitigen Programmiersprache C# verwendet |
Katalog-API | Container, einschließlich des Katalogmicroservice für die ASP.NET Core-Web-API |
Sortier-API | Container, einschließlich des Microservice für Bestellungen für die ASP.NET Core-Web-API |
sqldata | Container mit SQL Server für Linux, der die Microservices-Datenbanken enthält |
basket-api | Container mit dem Warenkorbmicroservice für die ASP.NET Core-Web-API |
basketdata | Container, der den REDIS-Cachedienst ausführt, mit der Korbdatenbank als REDIS-Cache |
Ein einfacher Webdienst-API-Container
Der Katalog-API-Container-Microservice, der sich auf einen einzelnen Container konzentriert, hat eine klare und einfache Definition.
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
Dieser containerisierte Dienst verfügt über die folgende Grundlegende Konfiguration:
Sie basiert auf dem benutzerdefinierten eshop/catalog-api Image . Der Einfachheit halber gibt es keine „build: key“-Einstellung in der Datei. Dies bedeutet, dass das Image zuvor (mit Docker-Build) erstellt oder (mit dem Docker-Pullbefehl) aus einer beliebigen Docker-Registrierung heruntergeladen wurde.
Es definiert eine Umgebungsvariable namens ConnectionString mit der Verbindungszeichenfolge, die von Entity Framework verwendet werden soll, um auf die SQL Server-Instanz zuzugreifen, die das Katalogdatenmodell enthält. In diesem Fall enthält derselbe SQL Server-Container mehrere Datenbanken. Daher benötigen Sie weniger Arbeitsspeicher auf Ihrem Entwicklungscomputer für Docker. Sie können jedoch auch einen SQL Server-Container für jede Microservice-Datenbank bereitstellen.
Der SQL Server-Name ist sqldata, der für den Container verwendet wird, der die SQL Server-Instanz für Linux ausführt. Dies ist praktisch; Wenn Sie diese Namensauflösung (intern für den Docker-Host) verwenden können, wird die Netzwerkadresse aufgelöst, sodass Sie die interne IP für die Container, auf die Sie von anderen Containern zugreifen, nicht kennen müssen.
Da die Verbindungszeichenfolge durch eine Umgebungsvariable definiert wird, können Sie diese Variable über einen anderen Mechanismus und zu einem anderen Zeitpunkt festlegen. Sie können beispielsweise eine andere Verbindungszeichenfolge festlegen, wenn Sie diese in der Produktion auf den endgültigen Hosts bereitstellen oder dies aus Ihren CI/CD-Pipelines in Azure DevOps Services oder Ihrem bevorzugten DevOps-System heraus tun.
Es macht Port 80 für internen Zugriff auf den Katalog-API-Dienst innerhalb des Docker-Hosts verfügbar. Der Host ist derzeit eine Linux-VM, da er auf einem Docker-Image für Linux basiert, aber Sie könnten den Container so konfigurieren, dass er stattdessen auf einem Windows-Image ausgeführt wird.
Er leitet den verfügbar gemachten Port 80 im Container an Port 5101 auf dem Docker-Hostcomputer (der Linux-VM) weiter.
Er verknüpft den Webdienst mit dem SQLData-Dienst (die SQL Server-Instanz für Linux-Datenbank, die in einem Container ausgeführt wird). Wenn Sie diese Abhängigkeit angeben, wird der Katalog-API-Container erst gestartet, wenn der sqldata-Container bereits gestartet wurde. Dieser Aspekt ist wichtig, da die Katalog-API die SQL Server-Datenbank zuerst ausführen muss. Diese Art von Containerabhängigkeit reicht jedoch in vielen Fällen nicht aus, da Docker nur auf Containerebene überprüft. Manchmal ist der Dienst (in diesem Fall SQL Server) möglicherweise noch nicht bereit, daher ist es ratsam, Wiederholungslogik mit exponentiellem Backoff in Ihren Client-Microservices zu implementieren. Falls ein Abhängigkeitscontainer kurzfristig nicht bereitsteht, bleibt die Anwendung dennoch widerstandsfähig.
Sie ist so konfiguriert, dass der Zugriff auf externe Server zulässt: Mit der Einstellung extra_hosts können Sie auf externe Server oder Computer außerhalb des Docker-Hosts zugreifen (d. h. außerhalb der standardmäßigen Linux-VM, die ein Entwicklungs-Docker-Host ist), z. B. eine lokale SQL Server-Instanz auf Ihrem Entwicklungs-PC.
Es gibt auch andere, erweiterte docker-compose.yml
Einstellungen, die in den folgenden Abschnitten erläutert werden.
Verwenden von Docker-Compose-Dateien, um auf mehrere Umgebungen abzuzielen.
Die docker-compose.*.yml
Dateien sind Definitionsdateien und können von mehreren Infrastrukturen verwendet werden, die dieses Format verstehen. Das einfachste Tool ist der Docker-Compose-Befehl.
Daher können Sie mithilfe des Docker-Compose-Befehls die folgenden Hauptszenarien ansprechen.
Entwicklungsumgebungen
Wenn Sie Anwendungen entwickeln, ist es wichtig, eine Anwendung in einer isolierten Entwicklungsumgebung ausführen zu können. Sie können den CLI-Befehl docker-compose verwenden, um diese Umgebung zu erstellen, oder Visual Studio, das docker-compose im Hintergrund verwendet.
Mit der docker-compose.yml Datei können Sie alle Dienstabhängigkeiten Ihrer Anwendung konfigurieren und dokumentieren (andere Dienste, Cache, Datenbanken, Warteschlangen usw.). Mithilfe des Befehls docker-compose CLI können Sie einen oder mehrere Container für jede Abhängigkeit mit einem einzigen Befehl (docker-compose up) erstellen und starten.
Die docker-compose.yml Dateien sind Konfigurationsdateien, die vom Docker-Modul interpretiert werden, dienen aber auch als praktische Dokumentationsdateien zur Zusammensetzung Ihrer Multi-Container-Anwendung.
Testumgebungen
Ein wichtiger Teil des Prozesses jeder fortlaufenden Bereitstellung (Continuous Deployment, CD) oder fortlaufenden Integration (Continuous Integration, CI) sind die Komponententests und Integrationstests. Diese automatisierten Tests erfordern eine isolierte Umgebung, sodass sie nicht von den Benutzern oder einer anderen Änderung der Anwendungsdaten betroffen sind.
Mit Docker Compose können Sie diese isolierte Umgebung sehr einfach in einigen Befehlen über die Eingabeaufforderung oder Skripts erstellen und zerstören, z. B. die folgenden Befehle:
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
Produktionseinsätze
Sie können Compose auch zum Bereitstellen auf eine Docker-Remote-Engine verwenden. Ein typischer Fall ist die Bereitstellung in einer einzelnen Docker-Hostinstanz.
Wenn Sie einen anderen Orchestrator verwenden (z. B. Azure Service Fabric oder Kubernetes), müssen Sie möglicherweise Setup- und Metadatenkonfigurationseinstellungen wie die in docker-compose.yml hinzufügen, aber im format, das vom anderen Orchestrator benötigt wird.
In jedem Fall ist Docker-Compose ein bequemes Tool- und Metadatenformat für Entwicklungs-, Test- und Produktionsworkflows, obwohl der Produktionsworkflow für den verwendeten Orchestrator variieren kann.
Verwenden mehrerer Docker-Compose-Dateien zur Verarbeitung mehrerer Umgebungen
Wenn Sie auf verschiedene Umgebungen abzielen, sollten Sie mehrere Verfassendateien verwenden. Mit diesem Ansatz können Sie je nach Umgebung mehrere Konfigurationsvarianten erstellen.
Überschreiben der docker-compose-Basisdatei
Sie können eine einzelne docker-compose.yml Datei wie in den vereinfachten Beispielen in früheren Abschnitten verwenden. Dies wird jedoch für die meisten Anwendungen nicht empfohlen.
Standardmäßig liest Compose zwei Dateien, eine docker-compose.yml und eine optionale docker-compose.override.yml Datei. Wie in Abbildung 6-11 dargestellt, erstellt Visual Studio, wenn Sie Visual Studio verwenden und die Docker-Unterstützung aktivieren, auch eine zusätzliche docker-compose.vs.debug.g.yml Datei zum Debuggen der Anwendung. Sie können sich diese Datei im Ordner "obj\Docker\" im Hauptlösungsordner ansehen.
Abbildung 6-11. Docker-Compose-Dateien in Visual Studio 2019
Docker-Compose-Projektdateistruktur :
- Dockerignore - wird verwendet, um Dateien zu ignorieren
- docker-compose.yml – verwendet zum Verfassen von Microservices
- docker-compose.override.yml – verwendet zum Konfigurieren der Microservices-Umgebung
Sie können die Docker-Compose-Dateien mit einem beliebigen Editor bearbeiten, z. B. Visual Studio Code oder Sublime, und die Anwendung mit dem Befehl "docker-compose up" ausführen.
In der Konvention enthält die docker-compose.yml Datei Ihre Basiskonfiguration und andere statische Einstellungen. Dies bedeutet, dass sich die Dienstkonfiguration nicht je nach der Bereitstellungsumgebung ändern sollte, auf die Sie abzielen.
Die datei docker-compose.override.yml enthält, wie der Name schon sagt, Konfigurationseinstellungen, die die Basiskonfiguration außer Kraft setzen, z. B. die Konfiguration, die von der Bereitstellungsumgebung abhängt. Sie können auch mehrere Überschreibdateien mit unterschiedlichen Namen haben. Die Override-Dateien enthalten in der Regel zusätzliche Informationen, die von der Anwendung benötigt werden und spezifisch für eine bestimmte Umgebung oder Bereitstellung sind.
Anzielen mehrerer Umgebungen
Ein typischer Anwendungsfall ist, wenn Sie mehrere Verfassendateien definieren, sodass Sie auf mehrere Umgebungen abzielen können, z. B. Produktion, Staging, CI oder Entwicklung. Um diese Unterschiede zu unterstützen, können Sie Die Konfiguration zum Verfassen in mehrere Dateien aufteilen, wie in Abbildung 6-12 dargestellt.
Abbildung 6-12. Mehrere Docker-Compose-Dateien überschreiben Werte in der Basisdatei docker-compose.yml
Sie können mehrere Docker-compose*-.yml Dateien kombinieren, um verschiedene Umgebungen zu verarbeiten. Sie beginnen mit der Basisdatei docker-compose.yml. Diese Basisdatei enthält die Basis- oder statischen Konfigurationseinstellungen, die sich je nach Umgebung nicht ändern. Die eShopOnContainers-App verfügt beispielsweise über die folgende docker-compose.yml Datei (vereinfacht mit weniger Diensten) als Basisdatei.
#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
Die Werte in der Basisdatei docker-compose.yml datei sollten sich aufgrund unterschiedlicher Zielbereitstellungsumgebungen nicht ändern.
Wenn Sie sich z. B. auf die Webmvc-Dienstdefinition konzentrieren, können Sie sehen, wie diese Informationen unabhängig von der Umgebung, auf die Sie abzielen könnten, ähnlich sind. Sie haben die folgenden Informationen:
Der Dienstname: webmvc.
Das benutzerdefinierte Image des Containers: eshop/webmvc.
Der Befehl zum Erstellen des benutzerdefinierten Docker-Images, der angibt, welche Dockerfile verwendet werden soll.
Abhängigkeiten von anderen Diensten, sodass dieser Container erst gestartet wird, wenn die anderen Abhängigkeitscontainer gestartet wurden.
Sie können zusätzliche Konfigurationen haben, aber der wichtige Punkt ist, dass Sie in der Basisdatei docker-compose.yml nur die Informationen festlegen möchten, die in allen Umgebungen üblich sind. Anschließend sollten Sie in der docker-compose.override.yml oder ähnlichen Dateien für die Produktion oder Staging die konfiguration platzieren, die für jede Umgebung spezifisch ist.
In der Regel wird die docker-compose.override.yml für Ihre Entwicklungsumgebung verwendet, wie im folgenden Beispiel von 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"
In diesem Beispiel macht die Entwicklungsüberschreibungskonfiguration einige Ports für den Host verfügbar, definiert Umgebungsvariablen mit Umleitungs-URLs und gibt Verbindungszeichenfolgen für die Entwicklungsumgebung an. Diese Einstellungen sind nur für die Entwicklungsumgebung vorgesehen.
Wenn Sie docker-compose up
ausführen (oder es aus Visual Studio starten), liest der Befehl die Überschreibungen automatisch so aus, als würden beide Dateien zusammengeführt werden.
Angenommen, Sie möchten eine andere Compose-Datei für die Produktionsumgebung mit unterschiedlichen Konfigurationswerten, Ports oder Verbindungsstrings. Sie können eine weitere Außerkraftsetzungsdatei erstellen, z. B. eine Datei docker-compose.prod.yml
mit unterschiedlichen Einstellungen und Umgebungsvariablen. Diese Datei kann in einem anderen Git-Repository gespeichert oder von einem anderen Team verwaltet und gesichert werden.
Durchführen einer Bereitstellung mit einer bestimmten Außerkraftsetzungsdatei
Wenn Sie mehrere Außerkraftsetzungsdateien oder eine Außerkraftsetzungsdatei mit einem anderen Namen verwenden möchten, können Sie die Option "-f" mit dem Befehl "docker-compose" verwenden und die Dateien angeben. Compose führt Dateien in der Reihenfolge zusammen, wie sie auf der Kommandozeile angegeben werden. Im folgenden Beispiel sehen Sie, wie eine Bereitstellung mit Außerkraftsetzungsdateien durchgeführt wird.
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
Verwenden von Umgebungsvariablen in Docker-Compose-Dateien
Es ist praktisch, insbesondere in Produktionsumgebungen, Konfigurationsinformationen aus Umgebungsvariablen abzurufen, wie wir in früheren Beispielen gezeigt haben. Sie können auf eine Umgebungsvariable in Ihren Docker-Compose-Dateien verweisen, indem Sie die Syntax ${MY_VAR} verwenden. Die folgende Zeile aus einer docker-compose.prod.yml Datei zeigt, wie auf den Wert einer Umgebungsvariable verwiesen wird.
IdentityUrl=http://${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}:5105
Umgebungsvariablen werden je nach Hostumgebung (Linux, Windows, Cloudcluster usw.) auf unterschiedliche Weise erstellt und initialisiert. Ein praktischer Ansatz besteht jedoch darin, eine env-Datei zu verwenden. Die Docker-Compose-Dateien unterstützen das Deklarieren von Standardumgebungsvariablen in der env-Datei. Diese Werte für die Umgebungsvariablen sind die Standardwerte. Sie können jedoch von den Werten außer Kraft gesetzt werden, die Sie möglicherweise in jeder Ihrer Umgebungen definiert haben (Hostbetriebssystem oder Umgebungsvariablen aus Ihrem Cluster). Sie platzieren diese env-Datei in dem Ordner, in dem der Befehl docker-compose ausgeführt wird.
Das folgende Beispiel zeigt eine env-Datei wie die env-Datei für die eShopOnContainers-Anwendung.
# .env file
ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal
ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP=10.121.122.92
Docker-compose erwartet, dass jede Zeile in einer .env-Datei im Format <variable>=<Wert> enthalten ist.
Die in der Laufzeitumgebung festgelegten Werte überschreiben immer die in der env-Datei definierten Werte. Auf ähnliche Weise überschreiben auch die über Befehlszeilenargumente übergebenen Werte die in der env-Datei festgelegten Standardwerte.
Weitere Ressourcen
Übersicht über Docker Compose
https://docs.docker.com/compose/overview/Mehrere Compose-Dateien
https://docs.docker.com/compose/multiple-compose-files/
Erstellen optimierter ASP.NET Core Docker-Images
Wenn Sie Docker und .NET auf Quellen im Internet erkunden, finden Sie Dockerfiles, die die Einfachheit des Erstellens eines Docker-Images veranschaulichen, indem Sie Ihre Quelle in einen Container kopieren. Diese Beispiele schlagen vor, dass Sie mithilfe einer einfachen Konfiguration ein Docker-Image mit der Umgebung haben können, die mit Ihrer Anwendung verpackt ist. Das folgende Beispiel zeigt eine einfache Dockerfile in dieser Weise.
FROM mcr.microsoft.com/dotnet/sdk:8.0
WORKDIR /app
ENV ASPNETCORE_URLS http://+:80
EXPOSE 80
COPY . .
RUN dotnet restore
ENTRYPOINT ["dotnet", "run"]
Eine Dockerfile-Datei wie diese funktioniert. Sie können Ihre Bilder jedoch erheblich optimieren, insbesondere Ihre Produktionsbilder.
Sie starten im Container- und im Microservicesmodell ständig Container. Es wird kein inaktiver Container neu gestartet, wenn ein Container ganz normal verwendet wird, da der Container verwerfbar ist. Orchestrators (wie Kubernetes und Azure Service Fabric) erstellen neue Instanzen von Images. Das bedeutet, dass Sie eine Optimierung durch Vorkompilierung der Anwendung vornehmen müssten, wenn diese erstellt wird, damit der Instanziierungsprozess schneller wird. Wenn der Container gestartet wird, sollte er einsatzbereit sein. Verwenden Sie während der Laufzeit nicht die dotnet restore
und dotnet build
CLI-Befehle zur Wiederherstellung und Kompilierung, wie in den Blogbeiträgen zu .NET und Docker beschrieben.
Das .NET-Team hat wichtige Arbeit ausgeführt, um .NET und ASP.NET Core zu einem containeroptimierten Framework zu machen. Nicht nur .NET ist ein einfaches Framework mit geringem Speicherbedarf; das Team hat sich auf optimierte Docker-Images für drei Hauptszenarien konzentriert und sie in der Docker Hub-Registrierung bei dotnet/veröffentlicht, beginnend mit Version 2.1:
- Entwicklung: Die Priorität ist die Möglichkeit, Änderungen schnell zu durchlaufen und zu debuggen, und die Größe ist sekundär.
- Build: Die Priorität besteht darin, die Anwendung zu kompilieren, und das Image enthält Binärdateien und andere Abhängigkeiten, um Binärdateien zu optimieren.
- Produktion: Der Fokus liegt im schnellen Bereitstellen und Starten von Containern, sodass diese Images auf die Binärdateien und Inhalte beschränkt sind, die zum Ausführen der Anwendung erforderlich sind.
Das .NET-Team bietet einige grundlegende Varianten in dotnet/, z. B.:
- sdk: für Entwicklungs- und Buildszenarien
- aspnet: für ASP.NET Produktionsszenarien
- Laufzeit: für .NET-Produktionsszenarien
- runtime-deps: für Produktionsszenarios mit eigenständigen Anwendungen
Für einen schnelleren Start legen Laufzeitimages auch automatisch aspnetcore_urls auf Port 80 fest und verwenden Ngen zum Erstellen eines systemeigenen Imagecaches von Assemblys.
Weitere Ressourcen
Erstellen optimierter Docker-Images mit ASP.NET Corehttps://learn.microsoft.com/archive/blogs/stevelasker/building-optimized-docker-images-with-asp-net-core
Erstellen von Docker-Images für .NET-Anwendungenhttps://learn.microsoft.com/dotnet/core/docker/building-net-docker-images