Utvecklingsarbetsflöde för Docker-appar
Dricks
Det här innehållet är ett utdrag från eBook, .NET Microservices Architecture for Containerized .NET Applications, tillgängligt på .NET Docs eller som en kostnadsfri nedladdningsbar PDF som kan läsas offline.
Livscykeln för programutveckling börjar på datorn, som utvecklare, där du kodar programmet med det språk du föredrar och testar det lokalt. Med det här arbetsflödet, oavsett vilket språk, ramverk och plattform du väljer, utvecklar och testar du alltid Docker-containrar, men gör det lokalt.
Varje container (en instans av en Docker-avbildning) innehåller följande komponenter:
- Ett operativsystemval, till exempel en Linux-distribution, Windows Nano Server eller Windows Server Core.
- Filer som lagts till under utveckling, till exempel källkod och binärfiler för program.
- Konfigurationsinformation, till exempel miljöinställningar och beroenden.
Arbetsflöde för att utveckla Docker-containerbaserade program
I det här avsnittet beskrivs arbetsflödet för utveckling av inre loopar för Docker-containerbaserade program. Arbetsflödet i den inre loopen innebär att det inte tar hänsyn till det bredare DevOps-arbetsflödet, som kan omfatta upp till produktionsdistribution, och fokuserar bara på det utvecklingsarbete som utförs på utvecklarens dator. De första stegen för att konfigurera miljön ingår inte, eftersom dessa steg bara utförs en gång.
Ett program består av dina egna tjänster plus ytterligare bibliotek (beroenden). Följande är de grundläggande steg som du vanligtvis utför när du skapar ett Docker-program, enligt bild 5–1.
Utvecklingsprocessen för Docker-appar: 1 – Koda din app, 2 – Skriv Dockerfile/s, 3 – Skapa avbildningar som definierats i Dockerfile/s, 4 – (valfritt) Skriv tjänster i docker-compose.yml-filen, 5 – Kör container eller docker-compose-app, 6 – Testa din app eller dina mikrotjänster, 7 – Push-överföring för lagringsplats och upprepning.
Bild 5-1. Steg för steg-arbetsflöde för att utveckla Docker-containerbaserade appar
I det här avsnittet beskrivs hela processen och varje större steg förklaras genom att fokusera på en Visual Studio-miljö.
När du använder en metod för redigering/CLI-utveckling (till exempel Visual Studio Code plus Docker CLI i macOS eller Windows) behöver du känna till varje steg, vanligtvis mer detaljerat än om du använder Visual Studio. Mer information om hur du arbetar i en CLI-miljö finns i e-boken Containerized Docker Application lifecycle with Microsoft Platforms and Tools (Containerized Docker Application lifecycle with Microsoft Platforms and Tools).
När du använder Visual Studio 2022 hanteras många av dessa steg åt dig, vilket avsevärt förbättrar produktiviteten. Detta gäller särskilt när du använder Visual Studio 2022 och riktar in dig på program med flera containrar. Med bara ett musklick lägger Dockerfile
Visual Studio till exempel filen och docker-compose.yml
till dina projekt med konfigurationen för ditt program. När du kör programmet i Visual Studio skapas Docker-avbildningen och programmet med flera containrar körs direkt i Docker. Du kan även felsöka flera containrar samtidigt. Dessa funktioner ökar din utvecklingshastighet.
Men bara för att Visual Studio gör dessa steg automatiskt betyder det inte att du inte behöver veta vad som händer under med Docker. Därför beskrivs varje steg i följande vägledning.
Steg 1. Börja koda och skapa din första program- eller tjänstbaslinje
Att utveckla ett Docker-program liknar hur du utvecklar ett program utan Docker. Skillnaden är att när du utvecklar för Docker distribuerar och testar du ditt program eller dina tjänster som körs i Docker-containrar i din lokala miljö (antingen en installation av en virtuell Linux-dator av Docker eller direkt Windows om du använder Windows-containrar).
Konfigurera din lokala miljö med Visual Studio
Börja med att kontrollera att Du har Docker Desktop för Windows för Windows installerat, enligt beskrivningen i följande instruktioner:
Kom igång med Docker Desktop för Windows
Dessutom behöver du Visual Studio 2022 version 17.0, med arbetsbelastningen .ASP.NET och webbutveckling installerad, enligt bild 5–2.
Bild 5-2. Välja arbetsbelastningen ASP.NET och webbutveckling under Visual Studio 2022-installationen
Du kan börja koda ditt program i vanlig .NET (vanligtvis i .NET Core eller senare om du planerar att använda containrar) även innan du aktiverar Docker i ditt program och distribuerar och testar i Docker. Vi rekommenderar dock att du börjar arbeta med Docker så snart som möjligt, eftersom det är den verkliga miljön och eventuella problem kan identifieras så snart som möjligt. Detta uppmuntras eftersom Visual Studio gör det så enkelt att arbeta med Docker att det nästan känns transparent – det bästa exemplet när du felsöker program med flera containrar från Visual Studio.
Ytterligare resurser
Kom igång med Docker Desktop för Windows
https://docs.docker.com/docker-for-windows/Visual Studio 2022
https://visualstudio.microsoft.com/downloads/
Steg 2. Skapa en Dockerfile som är relaterad till en befintlig .NET-basavbildning
Du behöver en Dockerfile för varje anpassad avbildning som du vill skapa. du behöver också en Dockerfile för varje container som ska distribueras, oavsett om du distribuerar automatiskt från Visual Studio eller manuellt med Docker CLI (docker run- och docker-compose-kommandon). Om ditt program innehåller en enda anpassad tjänst behöver du en enskild Dockerfile. Om ditt program innehåller flera tjänster (som i en mikrotjänstarkitektur) behöver du en Dockerfile för varje tjänst.
Dockerfile placeras i rotmappen för ditt program eller din tjänst. Den innehåller kommandon som talar om för Docker hur du konfigurerar och kör ditt program eller din tjänst i en container. Du kan skapa en Dockerfile i kod manuellt och lägga till den i projektet tillsammans med dina .NET-beroenden.
Med Visual Studio och dess verktyg för Docker kräver den här uppgiften bara några få musklickningar. När du skapar ett nytt projekt i Visual Studio 2022 finns det ett alternativ med namnet Aktivera Docker-support, enligt bild 5–3.
Bild 5-3. Aktivera Docker-stöd när du skapar ett nytt ASP.NET Core-projekt i Visual Studio 2022
Du kan också aktivera Docker-stöd för ett befintligt ASP.NET Core-webbappsprojekt genom att högerklicka på projektet i Solution Explorer och välja Lägg till>Docker-support..., enligt bild 5–4.
Bild 5-4. Aktivera Docker-stöd i ett befintligt Visual Studio 2022-projekt
Den här åtgärden lägger till en Dockerfile i projektet med den konfiguration som krävs och är endast tillgänglig för ASP.NET Core-projekt.
På liknande sätt kan Visual Studio också lägga till en docker-compose.yml
fil för hela lösningen med alternativet Lägg till > stöd för Container Orchestrator.... I steg 4 utforskar vi det här alternativet mer detaljerat.
Använda en befintlig officiell .NET Docker-avbildning
Du skapar vanligtvis en anpassad avbildning för containern ovanpå en basavbildning som du får från en officiell lagringsplats som Docker Hub-registret . Det är precis vad som händer under täcket när du aktiverar Docker-stöd i Visual Studio. Dockerfile använder en befintlig dotnet/core/aspnet
avbildning.
Tidigare förklarade vi vilka Docker-avbildningar och lagringsplatser som du kan använda, beroende på vilket ramverk och operativsystem du har valt. Om du till exempel vill använda ASP.NET Core (Linux eller Windows) är mcr.microsoft.com/dotnet/aspnet:8.0
avbildningen som ska användas . Därför behöver du bara ange vilken Docker-basavbildning du ska använda för containern. Det gör du genom att lägga FROM mcr.microsoft.com/dotnet/aspnet:8.0
till i Din Dockerfile. Detta utförs automatiskt av Visual Studio, men om du skulle uppdatera versionen uppdaterar du det här värdet.
Om du använder en officiell .NET-avbildningslagringsplats från Docker Hub med ett versionsnummer ser du till att samma språkfunktioner är tillgängliga på alla datorer (inklusive utveckling, testning och produktion).
I följande exempel visas ett Dockerfile-exempel för en ASP.NET Core-container.
FROM mcr.microsoft.com/dotnet/aspnet:8.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", " MySingleContainerWebApp.dll "]
I det här fallet baseras avbildningen på version 8.0 av den officiella ASP.NET Core Docker-avbildningen (multi-arch för Linux och Windows). Det här är inställningen FROM mcr.microsoft.com/dotnet/aspnet:8.0
. (Mer information om den här basavbildningen finns på sidan ASP.NET Core Docker Image .) I Dockerfile måste du också instruera Docker att lyssna på den TCP-port som du ska använda vid körning (i det här fallet port 80, enligt konfigurationen med inställningen EXPONERA).
Du kan ange ytterligare konfigurationsinställningar i Dockerfile, beroende på vilket språk och ramverk du använder. Till exempel uppmanar ENTRYPOINT-raden med ["dotnet", "MySingleContainerWebApp.dll"]
Docker att köra ett .NET-program. Om du använder SDK och .NET CLI (dotnet CLI) för att skapa och köra .NET-programmet skulle den här inställningen vara annorlunda. Slutsatsen är att ENTRYPOINT-linjen och andra inställningar skiljer sig beroende på vilket språk och plattform du väljer för ditt program.
Ytterligare resurser
Skapa Docker-avbildningar för ASP.NET Core-program
https://learn.microsoft.com/dotnet/core/docker/building-net-docker-imagesSkapa containeravbildningar. I den officiella Docker-dokumentationen.
https://docs.docker.com/get-started/docker-concepts/building-images/Hålla dig uppdaterad med .NET Container Images
https://devblogs.microsoft.com/dotnet/staying-up-to-date-with-net-container-images/Använda .NET och Docker Tillsammans – DockerCon 2018 Update
https://devblogs.microsoft.com/dotnet/using-net-and-docker-together-dockercon-2018-update/
Använda lagringsplatser för bild med flera valv
En enda lagringsplats kan innehålla plattformsvarianter, till exempel en Linux-avbildning och en Windows-avbildning. Med den här funktionen kan leverantörer som Microsoft (basavbildningsskapare) skapa en enda lagringsplats som täcker flera plattformar (det vill säga Linux och Windows). Till exempel ger .NET-lagringsplatsen som är tillgänglig i Docker Hub-registret stöd för Linux och Windows Nano Server med samma lagringsplatsnamn.
Om du anger en tagg riktar du in dig på en plattform som är explicit som i följande fall:
mcr.microsoft.com/dotnet/aspnet:8.0-bullseye-slim
Mål: Endast .NET 8-körning i Linuxmcr.microsoft.com/dotnet/aspnet:8.0-nanoserver-ltsc2022
Mål: .NET 8 runtime-only på Windows Nano Server
Men om du anger samma avbildningsnamn, även med samma tagg, använder multi-arch-avbildningarna (som avbildningen aspnet
) Linux- eller Windows-versionen beroende på vilket Docker-värdoperativsystem du distribuerar, som du ser i följande exempel:
mcr.microsoft.com/dotnet/aspnet:8.0
Multi-arch: .NET 8 runtime-only på Linux eller Windows Nano Server beroende på Docker-värdoperativsystemet
På så sätt, när du hämtar en avbildning från en Windows-värd, hämtar den Windows-varianten och hämtar samma avbildningsnamn från en Linux-värd hämtar Linux-varianten.
Flerstegsversioner i Dockerfile
Dockerfile liknar ett batchskript. Ungefär som du skulle göra om du var tvungen att konfigurera datorn från kommandoraden.
Det börjar med en basavbildning som konfigurerar den inledande kontexten, det är som startfilsystemet, som ligger ovanpå värdoperativsystemet. Det är inte ett operativsystem, men du kan se det som "operativsystemet" i containern.
Körningen av varje kommandorad skapar ett nytt lager i filsystemet med ändringarna från föregående, så att det resulterande filsystemet skapas när det kombineras.
Eftersom varje nytt lager "vilar" ovanpå det föregående och den resulterande bildstorleken ökar med varje kommando, kan avbildningarna bli mycket stora om de måste inkludera det SDK som behövs för att skapa och publicera ett program.
Det är här som flerstegsversioner kommer in i diagrammet (från Docker 17.05 och senare) för att göra sin magi.
Huvudidén är att du kan separera Dockerfile-körningsprocessen i steg, där en fas är en första avbildning följt av ett eller flera kommandon, och den sista fasen avgör den slutliga bildstorleken.
Med flerstegsversioner kan du dela upp skapandet i olika "faser" och sedan sammanställa den slutliga avbildningen och endast ta relevanta kataloger från mellanliggande steg. Den allmänna strategin för att använda den här funktionen är:
Använd en bas-SDK-avbildning (spelar ingen roll hur stor), med allt som behövs för att skapa och publicera programmet till en mapp och sedan
Använd en basavbildning, liten, körningsbaserad avbildning och kopiera publiceringsmappen från föregående steg för att skapa en liten slutlig avbildning.
Förmodligen är det bästa sättet att förstå flera steg att gå igenom en Dockerfile i detalj, rad för rad, så låt oss börja med den första Dockerfile som skapades av Visual Studio när du lägger till Docker-stöd i ett projekt och kommer att komma in på några optimeringar senare.
Den första Dockerfile kan se ut ungefär så här:
1 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2 WORKDIR /app
3 EXPOSE 80
4
5 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
6 WORKDIR /src
7 COPY src/Services/Catalog/Catalog.API/Catalog.API.csproj …
8 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.AspNetCore.HealthChecks …
9 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions.HealthChecks …
10 COPY src/BuildingBlocks/EventBus/IntegrationEventLogEF/ …
11 COPY src/BuildingBlocks/EventBus/EventBus/EventBus.csproj …
12 COPY src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj …
13 COPY src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj …
14 COPY src/BuildingBlocks/WebHostCustomization/WebHost.Customization …
15 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions …
16 COPY src/BuildingBlocks/HealthChecks/src/Microsoft.Extensions …
17 RUN dotnet restore src/Services/Catalog/Catalog.API/Catalog.API.csproj
18 COPY . .
19 WORKDIR /src/src/Services/Catalog/Catalog.API
20 RUN dotnet build Catalog.API.csproj -c Release -o /app
21
22 FROM build AS publish
23 RUN dotnet publish Catalog.API.csproj -c Release -o /app
24
25 FROM base AS final
26 WORKDIR /app
27 COPY --from=publish /app .
28 ENTRYPOINT ["dotnet", "Catalog.API.dll"]
Och det här är informationen, rad för rad:
Rad nr 1: Starta en fas med en "liten" runtime-endast basavbildning, anropa den som referens .
Rad 2: Skapa katalogen /app i avbildningen.
Rad 3: Exponera port 80.
Rad nr 5: Påbörja en ny fas med den "stora" avbildningen för att skapa/publicera. Anropa den build som referens.
Rad nr 6: Skapa katalog /src i avbildningen.
Rad 7: Upp till rad 16 kopierar du refererade .csproj-projektfiler för att kunna återställa paket senare.
Rad 17: Återställa paket för Catalog.API-projektet och de refererade projekten.
Rad 18: Kopiera alla katalogträd för lösningen (förutom de filer/kataloger som ingår i .dockerignore-filen ) till katalogen /src i avbildningen.
Rad nr 19: Ändra den aktuella mappen till projektet Catalog.API .
Rad 20: Skapa projektet (och andra projektberoenden) och utdata till katalogen /app i avbildningen.
Rad nr 22: Påbörja en ny fas som fortsätter från bygget. Anropa publiceringen som referens.
Rad 23: Publicera projektet (och beroenden) och utdata till katalogen /app i avbildningen.
Rad nr 25: Påbörja en ny fas som fortsätter från basen och kallar den slutgiltig.
Rad nr 26: Ändra den aktuella katalogen till /app.
Rad nr 27: Kopiera katalogen /app från scenpublicering till den aktuella katalogen.
Rad 28: Definiera kommandot som ska köras när containern startas.
Nu ska vi utforska några optimeringar för att förbättra hela processprestandan som, när det gäller eShopOnContainers, innebär cirka 22 minuter eller mer för att skapa den fullständiga lösningen i Linux-containrar.
Du kommer att dra nytta av Docker layer cache-funktionen, vilket är ganska enkelt: om basavbildningen och kommandona är samma som vissa tidigare utförda, kan den bara använda det resulterande lagret utan att behöva köra kommandona, vilket sparar lite tid.
Så vi fokuserar på byggsteget, raderna 5–6 är mestadels desamma, men raderna 7–17 skiljer sig åt för varje tjänst från eShopOnContainers, så de måste köras varje gång, men om du har ändrat raderna 7–16 till:
COPY . .
Sedan skulle det vara precis samma för varje tjänst, det skulle kopiera hela lösningen och skulle skapa ett större lager men:
Kopieringsprocessen skulle bara köras första gången (och vid återskapande om en fil ändras) och skulle använda cachen för alla andra tjänster och
Eftersom den större bilden förekommer i ett mellanliggande steg påverkar den inte den slutliga bildstorleken.
Nästa viktiga optimering omfattar kommandot restore
som körs på rad 17, vilket också skiljer sig åt för varje eShopOnContainers-tjänst. Om du ändrar den raden till bara:
RUN dotnet restore
Det skulle återställa paketen för hela lösningen, men sedan skulle det göra det bara en gång, i stället för de 15 gångerna med den nuvarande strategin.
Körs dock dotnet restore
bara om det finns en enda projekt- eller lösningsfil i mappen, så att uppnå detta är lite mer komplicerat och sättet att lösa det, utan att gå in på för många detaljer, är detta:
Lägg till följande rader i .dockerignore:
*.sln
, för att ignorera alla lösningsfiler i huvudmappträdet!eShopOnContainers-ServicesAndWebApps.sln
, för att endast inkludera den här lösningsfilen.
/ignoreprojectextensions:.dcproj
Inkludera argumentet tilldotnet restore
, så att det även ignorerar docker-compose-projektet och återställer endast paketen för lösningen eShopOnContainers-ServicesAndWebApps.
För den slutliga optimeringen händer det bara att rad 20 är redundant, eftersom rad 23 också skapar programmet och kommer i huvudsak direkt efter rad 20, så det blir ett annat tidskrävande kommando.
Den resulterande filen är sedan:
1 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
2 WORKDIR /app
3 EXPOSE 80
4
5 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS publish
6 WORKDIR /src
7 COPY . .
8 RUN dotnet restore /ignoreprojectextensions:.dcproj
9 WORKDIR /src/src/Services/Catalog/Catalog.API
10 RUN dotnet publish Catalog.API.csproj -c Release -o /app
11
12 FROM base AS final
13 WORKDIR /app
14 COPY --from=publish /app .
15 ENTRYPOINT ["dotnet", "Catalog.API.dll"]
Skapa basavbildningen från grunden
Du kan skapa en egen Docker-basavbildning från grunden. Det här scenariot rekommenderas inte för någon som börjar med Docker, men om du vill ange de specifika bitarna i din egen basavbildning kan du göra det.
Ytterligare resurser
.NET Core-avbildningar med flera valv.
https://github.com/dotnet/announcements/issues/14Skapa en basavbildning. Officiell Docker-dokumentation.
https://docs.docker.com/develop/develop-images/baseimages/
Steg 3. Skapa dina anpassade Docker-avbildningar och bädda in ditt program eller din tjänst i dem
För varje tjänst i ditt program måste du skapa en relaterad avbildning. Om ditt program består av en enda tjänst eller ett webbprogram behöver du bara en enda avbildning.
Observera att Docker-avbildningarna skapas automatiskt åt dig i Visual Studio. Följande steg behövs bara för redigeraren/CLI-arbetsflödet och förklaras för tydlighetens skull om vad som händer under.
Som utvecklare måste du utveckla och testa lokalt tills du skickar en slutförd funktion eller ändrar till källkontrollsystemet (till exempel till GitHub). Det innebär att du måste skapa Docker-avbildningarna och distribuera containrar till en lokal Docker-värd (virtuell Windows- eller Linux-dator) och köra, testa och felsöka mot dessa lokala containrar.
Om du vill skapa en anpassad avbildning i din lokala miljö med hjälp av Docker CLI och Din Dockerfile kan du använda kommandot docker build, som i bild 5–5.
Bild 5-5. Skapa en anpassad Docker-avbildning
I stället för att köra docker build direkt från projektmappen kan du först generera en distribuerad mapp med de nödvändiga .NET-biblioteken och binärfilerna genom att köra dotnet publish
och sedan använda docker build
kommandot .
Då skapas en Docker-avbildning med namnet cesardl/netcore-webapi-microservice-docker:first
. I det här fallet :first
är en tagg som representerar en specifik version. Du kan upprepa det här steget för varje anpassad avbildning som du behöver skapa för ditt sammansatta Docker-program.
När ett program består av flera containrar (dvs. ett program med flera containrar) kan du också använda docker-compose up --build
kommandot för att skapa alla relaterade avbildningar med ett enda kommando med hjälp av metadata som exponeras i relaterade docker-compose.yml filer.
Du hittar de befintliga avbildningarna i den lokala lagringsplatsen med hjälp av kommandot docker images , som du ser i bild 5-6.
Bild 5-6. Visa befintliga avbildningar med kommandot docker images
Skapa Docker-avbildningar med Visual Studio
När du använder Visual Studio för att skapa ett projekt med Docker-stöd skapar du inte explicit en avbildning. I stället skapas avbildningen åt dig när du trycker på F5 (eller Ctrl+F5) för att köra det dockeriserade programmet eller tjänsten. Det här steget är automatiskt i Visual Studio och du kommer inte att se det hända, men det är viktigt att du vet vad som händer under.
Steg 4. Definiera dina tjänster i docker-compose.yml när du skapar ett Docker-program med flera containrar
Med docker-compose.yml-filen kan du definiera en uppsättning relaterade tjänster som ska distribueras som ett sammansatt program med distributionskommandon. Den konfigurerar även dess beroenderelationer och körningskonfiguration.
Om du vill använda en docker-compose.yml-fil måste du skapa filen i huvud- eller rotlösningsmappen, med innehåll som liknar det i följande exempel:
version: '3.4'
services:
webmvc:
image: eshop/web
environment:
- CatalogUrl=http://catalog-api
- OrderingUrl=http://ordering-api
ports:
- "80:80"
depends_on:
- catalog-api
- ordering-api
catalog-api:
image: eshop/catalog-api
environment:
- ConnectionString=Server=sqldata;Port=1433;Database=CatalogDB;…
ports:
- "81:80"
depends_on:
- sqldata
ordering-api:
image: eshop/ordering-api
environment:
- ConnectionString=Server=sqldata;Database=OrderingDb;…
ports:
- "82:80"
extra_hosts:
- "CESARDLBOOKVHD:10.0.75.1"
depends_on:
- sqldata
sqldata:
image: mcr.microsoft.com/mssql/server:latest
environment:
- SA_PASSWORD=[PLACEHOLDER]
- ACCEPT_EULA=Y
ports:
- "5433:1433"
Viktigt!
Microsoft rekommenderar att du använder det säkraste tillgängliga autentiseringsflödet. Om du ansluter till Azure SQL är hanterade identiteter för Azure-resurser den rekommenderade autentiseringsmetoden.
Den här docker-compose.yml filen är en förenklad och sammanslagen version. Den innehåller statiska konfigurationsdata för varje container (till exempel namnet på den anpassade avbildningen), som alltid krävs och konfigurationsinformation som kan vara beroende av distributionsmiljön, till exempel anslutningssträng. I senare avsnitt får du lära dig hur du delar upp docker-compose.yml-konfigurationen i flera docker-compose-filer och åsidosätter värden beroende på miljö och körningstyp (felsökning eller version).
I docker-compose.yml-filexemplet definieras fyra tjänster: webmvc
tjänsten (ett webbprogram), två mikrotjänster (ordering-api
och basket-api
) och en datakällcontainer, sqldata
, baserat på SQL Server för Linux som körs som en container. Varje tjänst distribueras som en container, så en Docker-avbildning krävs för var och en.
Filen docker-compose.yml anger inte bara vilka containrar som används, utan även hur de konfigureras individuellt. Till exempel containerdefinitionen webmvc
i filen .yml:
Använder en fördefinierad
eshop/web:latest
avbildning. Men du kan också konfigurera avbildningen så att den skapas som en del av docker-compose-körningen med en ytterligare konfiguration baserat på en version: avsnitt i docker-compose-filen.Initierar två miljövariabler (CatalogUrl och OrderingUrl).
Vidarebefordrar den exponerade port 80 på containern till den externa port 80 på värddatorn.
Länkar webbappen till katalogen och beställningstjänsten med inställningen depends_on. Detta gör att tjänsten väntar tills tjänsterna har startats.
Vi kommer att gå tillbaka till docker-compose.yml-filen i ett senare avsnitt när vi beskriver hur du implementerar mikrotjänster och appar med flera containrar.
Arbeta med docker-compose.yml i Visual Studio 2022
Förutom att lägga till en Dockerfile i ett projekt, som vi nämnde tidigare, kan Visual Studio 2017 (från version 15.8 på) lägga till orchestrator-stöd för Docker Compose i en lösning.
När du lägger till stöd för containerorkestrering, som visas i bild 5–7, skapar Visual Studio för första gången Dockerfile för projektet och skapar ett nytt (tjänstavsnitt) projekt i din lösning med flera globala docker-compose*.yml
filer och lägger sedan till projektet i dessa filer. Du kan sedan öppna docker-compose.yml-filerna och uppdatera dem med ytterligare funktioner.
Upprepa den här åtgärden för varje projekt som du vill inkludera i filen docker-compose.yml.
När detta skrivs stöder Visual Studio Docker Compose-orkestratorer .
Bild 5-7. Lägga till Docker-stöd i Visual Studio 2022 genom att högerklicka på ett ASP.NET Core-projekt
När du har lagt till stöd för orchestrator i din lösning i Visual Studio visas även en ny nod (i projektfilen) i docker-compose.dcproj
Solution Explorer som innehåller de tillagda docker-compose.yml-filerna, enligt bild 5–8.
Bild 5-8. Trädnoden docker-compose som lagts till i Solution Explorer för Visual Studio 2022
Du kan distribuera ett program med flera containrar med en enda docker-compose.yml fil med hjälp docker-compose up
av kommandot . Visual Studio lägger dock till en grupp av dem så att du kan åsidosätta värden beroende på miljö (utveckling eller produktion) och körningstyp (version eller felsökning). Den här funktionen förklaras i senare avsnitt.
Steg 5. Skapa och kör docker-programmet
Om ditt program bara har en enda container kan du köra den genom att distribuera den till din Docker-värd (virtuell dator eller fysisk server). Men om ditt program innehåller flera tjänster kan du distribuera det som ett sammansatt program, antingen med ett enda CLI-kommando (docker-compose up)
eller med Visual Studio, som använder det kommandot under täcket. Nu ska vi titta på de olika alternativen.
Alternativ A: Köra ett program med en container
Använda Docker CLI
Du kan köra en Docker-container med hjälp av docker run
kommandot enligt bild 5–9:
docker run -t -d -p 80:5000 cesardl/netcore-webapi-microservice-docker:first
Kommandot ovan skapar en ny containerinstans från den angivna avbildningen varje gång den körs. Du kan använda parametern --name
för att ge containern ett namn och sedan använda (eller använda docker start {name}
container-ID:t eller det automatiska namnet) för att köra en befintlig containerinstans.
Bild 5-9. Köra en Docker-container med kommandot docker run
I det här fallet binder kommandot den interna port 5000 för containern till port 80 för värddatorn. Det innebär att värden lyssnar på port 80 och vidarebefordrar till port 5000 i containern.
Hashen som visas är container-ID:t och tilldelas även ett slumpmässigt läsbart namn om --name
alternativet inte används.
Använda Visual Studio
Om du inte har lagt till stöd för containerorkestrering kan du också köra en enda containerapp i Visual Studio genom att trycka på Ctrl+F5 och du kan även använda F5 för att felsöka programmet i containern. Containern körs lokalt med docker-körning.
Alternativ B: Köra ett program med flera containrar
I de flesta företagsscenarier består ett Docker-program av flera tjänster, vilket innebär att du måste köra ett program med flera containrar enligt bild 5–10.
Bild 5-10. Virtuell dator med Docker-containrar distribuerade
Använda Docker CLI
Om du vill köra ett program med flera containrar med Docker CLI använder docker-compose up
du kommandot . Det här kommandot använder den docker-compose.yml fil som du har på lösningsnivå för att distribuera ett program med flera containrar. Bild 5–11 visar resultatet när du kör kommandot från huvudlösningskatalogen, som innehåller filen docker-compose.yml.
Bild 5-11. Exempelresultat när du kör kommandot docker-compose up
När kommandot docker-compose up körs distribueras programmet och dess relaterade containrar till Docker-värden, enligt bild 5–10.
Använda Visual Studio
Det kan inte bli enklare att köra ett program med flera containrar med Visual Studio 2019. Du trycker bara på Ctrl+F5 för att köra eller F5 för att felsöka, som vanligt, konfigurera docker-compose-projektet som startprojekt. Visual Studio hanterar alla nödvändiga installationer, så att du kan skapa brytpunkter som vanligt och felsöka vad som slutligen blir oberoende processer som körs i "fjärrservrar", med felsökningsprogrammet redan kopplat, precis som det.
Som tidigare nämnts konfigureras projektet i den globala filen (lösningsnivå) docker-compose.yml varje gång du lägger till Stöd för Docker-lösningen i ett projekt i en lösning, vilket gör att du kan köra eller felsöka hela lösningen samtidigt. Visual Studio startar en container för varje projekt som har stöd för Docker-lösningen aktiverat och utför alla interna steg åt dig (dotnet publish, docker build osv.).
Om du vill ta en titt på alla drudgery, ta en titt på filen:
{root solution folder}\obj\Docker\docker-compose.vs.debug.g.yml
Den viktiga punkten här är att det i Visual Studio 2019 finns ytterligare ett Docker-kommando för F5-nyckelåtgärden i Visual Studio 2019. Med det här alternativet kan du köra eller felsöka ett program med flera containrar genom att köra alla containrar som definieras i docker-compose.yml filer på lösningsnivå. Möjligheten att felsöka lösningar med flera containrar innebär att du kan ange flera brytpunkter, varje brytpunkt i ett annat projekt (container) och när du felsöker från Visual Studio stoppas du vid brytpunkter som definierats i olika projekt och körs på olika containrar.
Bild 5-12. Köra appar med flera containrar i Visual Studio 2022
Ytterligare resurser
- Distribuera en ASP.NET container till en fjärransluten Docker-värd
https://learn.microsoft.com/visualstudio/containers/hosting-web-apps-in-docker
En anteckning om att testa och distribuera med orkestrerare
Kommandona docker-compose up och docker run (eller körning och felsökning av containrar i Visual Studio) är tillräckliga för att testa containrar i utvecklingsmiljön. Men du bör inte använda den här metoden för produktionsdistributioner, där du bör rikta orkestrerare som Kubernetes eller Service Fabric. Om du använder Kubernetes måste du använda poddar för att organisera containrar och tjänster för att nätverka dem. Du kan också använda distributioner för att organisera skapande och ändring av poddar.
Steg 6. Testa Docker-programmet med din lokala Docker-värd
Det här steget varierar beroende på vad programmet gör. I ett enkelt .NET-webbprogram som distribueras som en enda container eller tjänst kan du komma åt tjänsten genom att öppna en webbläsare på Docker-värden och navigera till den platsen, enligt bild 5–13. (Om konfigurationen i Dockerfile mappar containern till en port på värden som är något annat än 80 tar du med värdporten i URL:en.)
Bild 5-13. Exempel på att testa ditt Docker-program lokalt med hjälp av localhost
Om localhost inte pekar på Docker-värd-IP(som standard, när du använder Docker CE, bör det) för att navigera till din tjänst, använda IP-adressen för datorns nätverkskort.
Den här URL:en i webbläsaren använder port 80 för det specifika containerexempel som diskuteras. Internt omdirigeras dock begäranden till port 5000, eftersom det var så det distribuerades med kommandot docker run, enligt beskrivningen i ett tidigare steg.
Du kan också testa programmet med curl från terminalen, enligt bild 5-14. I en Docker-installation i Windows är Docker-standardvärdens IP alltid 10.0.75.1 utöver datorns faktiska IP-adress.
Bild 5-14. Exempel på att testa ditt Docker-program lokalt med curl
Testa och felsöka containrar med Visual Studio 2022
När du kör och felsöker containrarna med Visual Studio 2022 kan du felsöka .NET-programmet på ungefär samma sätt som när du kör utan containrar.
Testa och felsöka utan Visual Studio
Om du utvecklar med hjälp av metoden redigerare/CLI är det svårare att felsöka containrar och du vill förmodligen felsöka genom att generera spårningar.
Ytterligare resurser
Snabbstart: Docker i Visual Studio.
https://learn.microsoft.com/visualstudio/containers/container-toolsFelsöka appar i en lokal Docker-container
https://learn.microsoft.com/visualstudio/containers/edit-and-refresh
Förenklat arbetsflöde vid utveckling av containrar med Visual Studio
Arbetsflödet när du använder Visual Studio är i själva verket mycket enklare än om du använder metoden redigerare/CLI. De flesta av de steg som krävs av Docker som är relaterade till Dockerfile och docker-compose.yml filer är dolda eller förenklade av Visual Studio, enligt bild 5–15.
Utvecklingsprocessen för Docker-appar: 1 – Koda din app, 2 – Skriv Dockerfile/s, 3 – Skapa avbildningar som definierats i Dockerfile/s, 4 – (valfritt) Skriv tjänster i docker-compose.yml-filen, 5 – Kör container eller docker-compose-app, 6 – Testa din app eller dina mikrotjänster, 7 – Push-överföring för lagringsplats och upprepning.
Bild 5-15. Förenklat arbetsflöde när du utvecklar med Visual Studio
Dessutom måste du utföra steg 2 (lägga till Docker-stöd i dina projekt) bara en gång. Arbetsflödet liknar därför dina vanliga utvecklingsuppgifter när du använder .NET för annan utveckling. Du behöver veta vad som händer under täcket (avbildningsprocessen, vilka basavbildningar du använder, distribution av containrar osv.) och ibland måste du också redigera Dockerfile- eller docker-compose.yml-filen för att anpassa beteenden. Men det mesta av arbetet förenklas avsevärt med hjälp av Visual Studio, vilket gör dig mycket mer produktiv.
Använda PowerShell-kommandon i en Dockerfile för att konfigurera Windows-containrar
Med Windows-containrar kan du konvertera dina befintliga Windows-program till Docker-avbildningar och distribuera dem med samma verktyg som resten av Docker-ekosystemet. Om du vill använda Windows-containrar kör du PowerShell-kommandon i Dockerfile, som du ser i följande exempel:
FROM mcr.microsoft.com/windows/servercore
LABEL Description="IIS" Vendor="Microsoft" Version="10"
RUN powershell -Command Add-WindowsFeature Web-Server
CMD [ "ping", "localhost", "-t" ]
I det här fallet använder vi en Windows Server Core-basavbildning (FROM-inställningen) och installerar IIS med ett PowerShell-kommando (run-inställningen). På liknande sätt kan du också använda PowerShell-kommandon för att konfigurera ytterligare komponenter som ASP.NET 4.x, .NET Framework 4.6 eller någon annan Windows-programvara. Följande kommando i en Dockerfile konfigurerar till exempel ASP.NET 4.5:
RUN powershell add-windowsfeature web-asp-net45
Ytterligare resurser
- aspnet-docker/Dockerfile. Exempel på PowerShell-kommandon som ska köras från dockerfiles för att inkludera Windows-funktioner.
https://github.com/Microsoft/aspnet-docker/blob/master/4.7.1-windowsservercore-ltsc2016/runtime/Dockerfile