Containerisera en .NET-app med dotnet publish

Containrar har många funktioner och fördelar, till exempel att vara en oföränderlig infrastruktur, tillhandahålla en bärbar arkitektur och möjliggöra skalbarhet. Avbildningen kan användas för att skapa containrar för din lokala utvecklingsmiljö, privata moln eller offentliga moln. I den här självstudien får du lära dig hur du containeriserar ett .NET-program med hjälp av kommandot dotnet publish .

Förutsättningar

Installera följande krav:

Utöver dessa förutsättningar rekommenderar vi att du är bekant med Worker Services i .NET.

Skapa .NET-app

Du behöver en .NET-app för att containerisera, så börja med att skapa en ny app från en mall. Öppna terminalen, skapa en arbetsmapp (exempelkatalog) om du inte redan har gjort det och ändra kataloger så att du är i den. I arbetsmappen kör du följande kommando för att skapa ett nytt projekt i en underkatalog med namnet Worker:

dotnet new worker -o Worker -n DotNet.ContainerImage

Mappträdet ser ut så här:

📁 sample-directory
    └──📂 Worker
        ├──appsettings.Development.json
        ├──appsettings.json
        ├──DotNet.ContainerImage.csproj
        ├──Program.cs
        ├──Worker.cs
        └──📂 obj
            ├── DotNet.ContainerImage.csproj.nuget.dgspec.json
            ├── DotNet.ContainerImage.csproj.nuget.g.props
            ├── DotNet.ContainerImage.csproj.nuget.g.targets
            ├── project.assets.json
            └── project.nuget.cache

Kommandot dotnet new skapar en ny mapp med namnet Worker och genererar en arbetstjänst som när den körs loggar ett meddelande varje sekund. Från terminalsessionen ändrar du kataloger och navigerar till mappen Worker . dotnet run Använd kommandot för att starta appen.

dotnet run
Building...
info: DotNet.ContainerImage.Worker[0]
      Worker running at: 10/18/2022 08:56:00 -05:00
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: .\Worker
info: DotNet.ContainerImage.Worker[0]
      Worker running at: 10/18/2022 08:56:01 -05:00
info: DotNet.ContainerImage.Worker[0]
      Worker running at: 10/18/2022 08:56:02 -05:00
info: DotNet.ContainerImage.Worker[0]
      Worker running at: 10/18/2022 08:56:03 -05:00
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
Attempting to cancel the build...

Arbetsmallen loopar på obestämd tid. Använd kommandot Avbryt Ctrl+C för att stoppa det.

Lägg till NuGet-paket

NuGet-paketet Microsoft.NET.Build.Containers krävs för närvarande för att publicera icke-webbprojekt som en container. Om du vill lägga till Microsoft.NET.Build.Containers NuGet-paketet i arbetsmallen kör du följande dotnet add package-kommando :

dotnet add package Microsoft.NET.Build.Containers

Dricks

Om du skapar en webbapp och använder .NET SDK 7.0.300 eller senare krävs inte paketet – SDK:t innehåller samma funktioner direkt.

Ange containeravbildningens namn

Det finns olika konfigurationsalternativ när du publicerar en app som en container.

Som standard är containeravbildningen namnet på AssemblyName projektet. Om namnet är ogiltigt som ett containeravbildningsnamn kan du åsidosätta det genom att ange ett ContainerRepository som visas i följande projektfil:

<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
    <ContainerRepository>dotnet-worker-image</ContainerRepository>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
  </ItemGroup>
</Project>

Mer information finns i ContainerRepository.

Som standard är containeravbildningen namnet på AssemblyName projektet. Om namnet är ogiltigt som ett containeravbildningsnamn kan du åsidosätta det genom att ange ett (ContainerImageName föråldrat) eller önskat ContainerRepository som det visas i följande projektfil:

<Project Sdk="Microsoft.NET.Sdk.Worker">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <UserSecretsId>dotnet-DotNet.ContainerImage-2e40c179-a00b-4cc9-9785-54266210b7eb</UserSecretsId>
    <ContainerImageName>dotnet-worker-image</ContainerImageName>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
    <PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.401" />
  </ItemGroup>
</Project>

Mer information finns i ContainerImageName.

Publicera .NET-app

Om du vill publicera .NET-appen som en container använder du följande dotnet-publiceringskommando :

dotnet publish --os linux --arch x64 /t:PublishContainer -c Release

Föregående .NET CLI-kommando publicerar appen som en container:

  • Rikta in sig på Linux som operativsystem (--os linux).
  • Ange en x64-arkitektur (--arch x64).
  • Använda versionskonfigurationen (-c Release).

Viktigt!

Om du vill skapa containern lokalt måste docker-daemonen köras. Om den inte körs när du försöker publicera appen som en container får du ett fel som liknar följande:

..\build\Microsoft.NET.Build.Containers.targets(66,9): error MSB4018:
   The "CreateNewImage" task failed unexpectedly. [..\Worker\DotNet.ContainerImage.csproj]

Dricks

Beroende på vilken typ av app du använder i container kan kommandoradsväxlarna (alternativen) variera. Argumentet krävs till exempel /t:PublishContainer bara för .NET-appar som inte är webbappar, till exempel console och worker mallar. För webbmallar ersätter du /t:PublishContainer argumentet med -p:PublishProfile=DefaultContainer. Mer information finns i .NET SDK container builds, issue #141.

Kommandot genererar utdata som liknar exempelutdata:

Determining projects to restore...
  All projects are up-to-date for restore.
  DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\DotNet.ContainerImage.dll
  DotNet.ContainerImage -> .\Worker\bin\Release\net8.0\linux-x64\publish\
  Building image 'dotnet-worker-image' with tags latest on top of base image mcr.microsoft.com/dotnet/aspnet:8.0
  Pushed container 'dotnet-worker-image:latest' to Docker daemon
Determining projects to restore...
  All projects are up-to-date for restore.
  DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\DotNet.ContainerImage.dll
  DotNet.ContainerImage -> .\Worker\bin\Release\net7.0\linux-x64\publish\
  Building image 'dotnet-worker-image' with tags 1.0.0 on top of base image mcr.microsoft.com/dotnet/aspnet:7.0
  Pushed container 'dotnet-worker-image:1.0.0' to Docker daemon

Det här kommandot kompilerar arbetsappen till publiceringsmappen och skickar containern till ditt lokala Docker-register.

Konfigurera containeravbildning

Du kan styra många aspekter av den genererade containern via MSBuild-egenskaper. Om du kan använda ett kommando i en Dockerfile för att ange en konfiguration kan du göra samma sak via MSBuild.

Kommentar

De enda undantagen till detta är RUN kommandon. På grund av hur containrar skapas kan de inte emuleras. Om du behöver den här funktionen måste du använda en Dockerfile för att skapa dina containeravbildningar.

ContainerArchiveOutputPath

Från och med .NET 8 kan du skapa en container direkt som ett tar.gz arkiv. Den här funktionen är användbar om arbetsflödet inte är enkelt och kräver att du till exempel kör ett genomsökningsverktyg över dina bilder innan du push-överför dem. När arkivet har skapats kan du flytta det, skanna det eller läsa in det i en lokal Docker-verktygskedja.

Om du vill publicera i ett arkiv lägger du till egenskapen i ContainerArchiveOutputPath kommandot dotnet publish , till exempel:

dotnet publish \
  -p PublishProfile=DefaultContainer \
  -p ContainerArchiveOutputPath=./images/sdk-container-demo.tar.gz

Du kan ange antingen ett mappnamn eller en sökväg med ett specifikt filnamn. Om du anger mappnamnet blir $(ContainerRepository).tar.gzfilnamnet som genereras för avbildningsarkivfilen . Dessa arkiv kan innehålla flera taggar inuti dem, bara när en enda fil skapas för alla ContainerImageTags.

Namngivningskonfiguration för containeravbildningar

Containeravbildningar följer en specifik namngivningskonvention. Avbildningens namn består av flera delar, registret, valfri port, lagringsplats och valfri tagg och familj.

REGISTRY[:PORT]/REPOSITORY[:TAG[-FAMILY]]

Tänk till exempel på det fullständigt kvalificerade mcr.microsoft.com/dotnet/runtime:8.0-alpine avbildningsnamnet:

  • mcr.microsoft.com är registret (och representerar i det här fallet Microsoft-containerregistret).
  • dotnet/runtime är lagringsplatsen (men vissa anser att detta user/repositoryär ).
  • 8.0-alpine är taggen och familjen (familjen är en valfri specificerare som hjälper till att skilja os-paketering).

Vissa egenskaper som beskrivs i följande avsnitt motsvarar hantering av delar av det genererade avbildningsnamnet. Tänk på följande tabell som mappar relationen mellan avbildningsnamnet och byggegenskaperna:

Del av bildnamn MSBuild-egenskap Exempelvärden
REGISTRY[:PORT] ContainerRegistry mcr.microsoft.com:443
PORT ContainerPort :443
REPOSITORY ContainerRepository dotnet/runtime
TAG ContainerImageTag 8.0
FAMILY ContainerFamily -alpine
Del av bildnamn MSBuild-egenskap Exempelvärden
REGISTRY[:PORT] ContainerRegistry mcr.microsoft.com:443
PORT ContainerPort :443
REPOSITORY ContainerImageName dotnet/runtime
TAG ContainerImageTag 8.0

I följande avsnitt beskrivs de olika egenskaper som kan användas för att styra den genererade containeravbildningen.

ContainerBaseImage

Egenskapen för containerbasavbildningen styr avbildningen som används som grund för avbildningen. Som standard härleds följande värden baserat på egenskaperna för projektet:

  • Om projektet är fristående används avbildningen mcr.microsoft.com/dotnet/runtime-deps som basavbildning.
  • Om projektet är ett ASP.NET Core-projekt används avbildningen mcr.microsoft.com/dotnet/aspnet som basavbildning.
  • Annars används bilden mcr.microsoft.com/dotnet/runtime som basavbildning.

Taggen för avbildningen härleds till den numeriska komponenten i den valda TargetFramework. Ett projekt som riktar sig till net6.0 resulterar till exempel i taggen 6.0 för den härledda basavbildningen, och ett net7.0-linux projekt använder taggen 7.0 och så vidare.

Om du anger ett värde här bör du ange det fullständigt kvalificerade namnet på bilden som ska användas som bas, inklusive eventuella taggar som du föredrar:

<PropertyGroup>
    <ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:8.0</ContainerBaseImage>
</PropertyGroup>
<PropertyGroup>
    <ContainerBaseImage>mcr.microsoft.com/dotnet/runtime:7.0</ContainerBaseImage>
</PropertyGroup>

ContainerFamily

Från och med .NET 8 kan du använda ContainerFamily egenskapen MSBuild för att välja en annan familj med Microsoft-tillhandahållna containeravbildningar som basavbildning för din app. När det här värdet anges läggs det till i slutet av den valda TFM-specifika taggen, vilket ändrar taggen som anges. Om du till exempel vill använda Alpine Linux-varianterna av .NET-basavbildningarna kan du ange ContainerFamily till alpine:

<PropertyGroup>
    <ContainerFamily>alpine</ContainerFamily>
</PropertyGroup>

Den föregående projektkonfigurationen resulterar i en slutlig tagg för 8.0-alpine en .NET 8-målapp.

Det här fältet är fritt format och kan ofta användas för att välja olika operativsystemdistributioner, standardpaketkonfigurationer eller någon annan smak av ändringar i en basavbildning. Det här fältet ignoreras när ContainerBaseImage har angetts. Mer information finns i .NET-containeravbildningar.

ContainerRuntimeIdentifier

Egenskapen för containerkörningsidentifierare styr operativsystemet och arkitekturen som används av containern om ContainerBaseImage stöder mer än en plattform. Till exempel stöder linux-x64avbildningen mcr.microsoft.com/dotnet/runtime för närvarande , linux-armoch win10-x64linux-arm64 bilder bakom samma tagg, så verktygen behöver ett sätt att få veta vilken av dessa versioner som du tänker använda. Som standard är detta inställt på värdet RuntimeIdentifier för det som du valde när du publicerade containern. Den här egenskapen behöver sällan anges explicit – använd -r i stället alternativet för kommandot dotnet publish . Om den valda avbildningen inte stöder den RuntimeIdentifier du har valt resulterar det i ett fel som beskriver de RuntimeIdentifiers som avbildningen stöder.

Du kan alltid ange ContainerBaseImage egenskapen till ett fullständigt kvalificerat avbildningsnamn, inklusive taggen, för att undvika att behöva använda den här egenskapen alls.

<PropertyGroup>
    <ContainerRuntimeIdentifier>linux-arm64</ContainerRuntimeIdentifier>
</PropertyGroup>

Mer information om körningsidentifierare som stöds av .NET finns i RID-katalogen.

ContainerRegistry

Egenskapen containerregister styr målregistret, den plats som den nyligen skapade avbildningen kommer att push-överföras till. Som standard skickas den till den lokala Docker-daemonen, men du kan också ange ett fjärrregister. När du använder ett fjärrregister som kräver autentisering autentiserar du med hjälp av de välkända docker login mekanismerna. Mer information finns i autentisera till containerregister för mer information. Ett konkret exempel på hur du använder den här egenskapen finns i följande XML-exempel:

<PropertyGroup>
    <ContainerRegistry>registry.mycorp.com:1234</ContainerRegistry>
</PropertyGroup>

Det här verktyget stöder publicering till alla register som stöder Docker Registry HTTP API V2. Detta inkluderar följande register explicit (och sannolikt många mer implicit):

Information om hur du arbetar med dessa register finns i registerspecifika anteckningar.

ContainerRepository

Containerlagringsplatsen är namnet på själva avbildningen, dotnet/runtime till exempel eller my-app. Som standard AssemblyName används projektet.

<PropertyGroup>
    <ContainerRepository>my-app</ContainerRepository>
</PropertyGroup>

ContainerImageName

Containeravbildningens namn styr namnet på själva avbildningen, dotnet/runtime till exempel eller my-app. Som standard AssemblyName används projektet.

<PropertyGroup>
    <ContainerImageName>my-app</ContainerImageName>
</PropertyGroup>

Kommentar

Från och med .NET 8 ContainerImageName är inaktuell till förmån för ContainerRepository.

Bildnamn består av ett eller flera snedstrecksavgränsade segment, som var och en bara kan innehålla alfanumeriska gemener, punkter, understreck och bindestreck, och måste börja med en bokstav eller siffra. Andra tecken resulterar i ett fel som utlöses.

ContainerImageTag(s)

Egenskapen containeravbildningstagg styr taggarna som genereras för avbildningen. Om du vill ange en enskild tagganvändning ContainerImageTag och för flera taggar använder du ContainerImageTags.

Viktigt!

När du använder ContainerImageTagsfår du flera bilder, en per unik tagg.

Taggar används ofta för att referera till olika versioner av en app, men de kan också referera till olika operativsystemdistributioner eller till och med olika konfigurationer.

Från och med .NET 8, när en tagg inte anges är lateststandardvärdet .

Som standard Version används projektet som taggvärde.

Om du vill åsidosätta standardvärdet anger du något av följande:

<PropertyGroup>
    <ContainerImageTag>1.2.3-alpha2</ContainerImageTag>
</PropertyGroup>

Om du vill ange flera taggar använder du en semikolonavgränsad uppsättning taggar i ContainerImageTags egenskapen, ungefär som att ange flera TargetFrameworks:

<PropertyGroup>
    <ContainerImageTags>1.2.3-alpha2;latest</ContainerImageTags>
</PropertyGroup>

Taggar kan bara innehålla upp till 127 alfanumeriska tecken, punkter, understreck och bindestreck. De måste börja med ett alfanumeriskt tecken eller ett understreck. Alla andra formulär resulterar i ett fel som utlöses.

Kommentar

När du använder ContainerImageTagsavgränsas taggarna med ett ; tecken. Om du anropar dotnet publish från kommandoraden (vilket är fallet med de flesta CI/CD-miljöer) måste du yttre omsluta värdena i en enda ' och inre radbrytning med dubbla citattecken ", till exempel (='"tag-1;tag-2"'). Överväg följande dotnet publish kommando:

dotnet publish -p ContainerImageTags='"1.2.3-alpha2;latest"'

Detta resulterar i att två bilder genereras: my-app:1.2.3-alpha2 och my-app:latest.

Dricks

Om du har problem med egenskapen ContainerImageTags kan du överväga att omfångssöka en miljövariabel ContainerImageTags i stället:

ContainerImageTags='1.2.3;latest' dotnet publish

ContainerLabel

Containeretiketten lägger till en metadataetikett i containern. Etiketter påverkar inte containern vid körning, men används ofta för att lagra version och redigera metadata för användning av säkerhetsskannrar och andra infrastrukturverktyg. Du kan ange valfritt antal containeretiketter.

Noden ContainerLabel har två attribut:

  • Include: Etikettens nyckel.
  • Value: Värdet för etiketten (detta kan vara tomt).
<ItemGroup>
    <ContainerLabel Include="org.contoso.businessunit" Value="contoso-university" />
</ItemGroup>

En lista över etiketter som skapas som standard finns i standardcontaineretiketter.

Konfigurera containerkörning

Om du vill styra körningen av containern kan du använda följande MSBuild-egenskaper.

ContainerWorkingDirectory

Containerns arbetskatalognod styr arbetskatalogen för containern, katalogen som kommandon körs i om inte annat kommando körs.

Som standard /app används katalogvärdet som arbetskatalog.

<PropertyGroup>
    <ContainerWorkingDirectory>/bin</ContainerWorkingDirectory>
</PropertyGroup>

ContainerPort

Containerporten lägger till TCP- eller UDP-portar i listan över kända portar för containern. Detta gör det möjligt för containerkörningar som Docker att mappa dessa portar till värddatorn automatiskt. Detta används ofta som dokumentation för containern, men kan också användas för att aktivera automatisk portmappning.

Noden ContainerPort har två attribut:

  • Include: Portnumret som ska exponeras.
  • Type: Standardvärden för tcp, giltiga värden är antingen tcp eller udp.
<ItemGroup>
    <ContainerPort Include="80" Type="tcp" />
</ItemGroup>

Från och med .NET 8 härleds den när den ContainerPort inte uttryckligen anges baserat på flera välkända ASP.NET miljövariabler:

  • ASPNETCORE_URLS
  • ASPNETCORE_HTTP_PORTS
  • ASPNETCORE_HTTPS_PORTS

Om dessa miljövariabler finns parsas deras värden och konverteras till TCP-portmappningar. Dessa miljövariabler läse från basavbildningen, om de finns, eller från miljövariablerna som definieras i projektet via ContainerEnvironmentVariable objekt. Mer information finns i ContainerEnvironmentVariable.

ContainerEnvironmentVariable

Med variabelnoden för containermiljön kan du lägga till miljövariabler i containern. Miljövariabler är tillgängliga för appen som körs i containern omedelbart och används ofta för att ändra körningsbeteendet för appen som körs.

Noden ContainerEnvironmentVariable har två attribut:

  • Include: Namnet på miljövariabeln.
  • Value: Värdet för miljövariabeln.
<ItemGroup>
  <ContainerEnvironmentVariable Include="LOGGER_VERBOSITY" Value="Trace" />
</ItemGroup>

Mer information finns i .NET-miljövariabler.

Konfigurera containerkommandon

Som standard startar containerverktygen din app med antingen den genererade AppHost-binärfilen för din app (om din app använder en AppHost) eller dotnet kommandot plus appens DLL.

Du kan dock styra hur appen körs med hjälp av en kombination av ContainerAppCommand, ContainerAppCommandArgs, ContainerDefaultArgsoch ContainerAppCommandInstruction.

Dessa olika konfigurationsplatser finns eftersom olika basavbildningar använder olika kombinationer av containern ENTRYPOINT och COMMAND egenskaperna, och du vill kunna stödja dem alla. Standardvärdena bör vara användbara för de flesta appar, men om du vill anpassa appstartbeteendet bör du:

  • Identifiera binärfilen som ska köras och ange den som ContainerAppCommand
  • Identifiera vilka argument som krävs för att programmet ska kunna köras och ange dem som ContainerAppCommandArgs
  • Identifiera vilka argument (om några) som är valfria och kan åsidosättas av en användare och ange dem som ContainerDefaultArgs
  • Ställ in ContainerAppCommandInstructionDefaultArgs

Mer information finns i följande konfigurationsobjekt.

ContainerAppCommand

Konfigurationsobjektet för appkommandot är appens logiska startpunkt. För de flesta appar är detta AppHost, den genererade körbara binärfilen för din app. Om din app inte genererar en AppHost blir det här kommandot vanligtvis dotnet <your project dll>. Dessa värden tillämpas efter någon ENTRYPOINT i bascontainern, eller direkt om nej ENTRYPOINT har definierats.

Konfigurationen ContainerAppCommand har en enda Include egenskap som representerar kommandot, alternativet eller argumentet som ska användas i kommandot entrypoint:

<ItemGroup Label="ContainerAppCommand Assignment">
  <!-- This is how you would start the dotnet ef tool in your container -->
  <ContainerAppCommand Include="dotnet" />
  <ContainerAppCommand Include="ef" />

  <!-- This shorthand syntax means the same thing, note the semicolon separating the tokens. -->
  <ContainerAppCommand Include="dotnet;ef" />
</ItemGroup>

ContainerAppCommandArgs

Det här appkommandot args-konfigurationsobjektet representerar alla logiskt obligatoriska argument för din app som ska tillämpas på ContainerAppCommand. Som standard genereras ingen för en app. När det är dags tillämpas args på containern när den körs.

Konfigurationen ContainerAppCommandArgs har en enda Include egenskap som representerar alternativet eller argumentet som ska tillämpas på ContainerAppCommand kommandot.

<ItemGroup>
  <!-- Assuming the ContainerAppCommand defined above, 
       this would be the way to force the database to update.
  -->
  <ContainerAppCommandArgs Include="database" />
  <ContainerAppCommandArgs Include="update" />

  <!-- This is the shorthand syntax for the same idea -->
  <ContainerAppCommandArgs Include="database;update" />
</ItemGroup>

ContainerDefaultArgs

Det här standardinställningsobjektet args representerar alla användaröversidosättbara argument för din app. Det här är ett bra sätt att tillhandahålla standardvärden som din app kan behöva köra på ett sätt som gör det enkelt att starta, men ändå enkelt att anpassa.

Konfigurationen ContainerDefaultArgs har en enda Include egenskap som representerar alternativet eller argumentet som ska tillämpas på ContainerAppCommand kommandot.

<ItemGroup>
  <!-- Assuming the ContainerAppCommand defined above, 
       this would be the way to force the database to update.
  -->
  <ContainerDefaultArgs Include="database" />
  <ContainerDefaultArgs Include="update" />

  <!-- This is the shorthand syntax for the same idea -->
  <ContainerDefaultArgs Include="database;update" />
</ItemGroup>

ContainerAppCommandInstruction

Konfigurationen för appkommandoinstruktioner hjälper dig att styra hur ContainerEntrypoint, ContainerEntrypointArgs, ContainerAppCommand, ContainerAppCommandArgsoch ContainerDefaultArgs kombineras för att bilda det slutliga kommandot som körs i containern. Detta beror mycket på om en ENTRYPOINT finns i basavbildningen. Den här egenskapen tar ett av tre värden: "DefaultArgs", "Entrypoint"eller "None".

  • Entrypoint:
    • I det här läget definieras startpunkten av ContainerAppCommand, ContainerAppCommandArgsoch ContainerDefaultArgs.
  • None:
    • I det här läget definieras startpunkten av ContainerEntrypoint, ContainerEntrypointArgsoch ContainerDefaultArgs.
  • DefaultArgs:
    • Det här är det mest komplexa läget – om inget av objekten ContainerEntrypoint[Args] finns används ContainerAppCommand[Args] och ContainerDefaultArgs för att skapa startpunkten och kommandot. Basavbildningens startpunkt för basavbildningar som har hårdkodad till dotnet eller /usr/bin/dotnet hoppas över så att du har fullständig kontroll.
    • Om både ContainerEntrypoint och ContainerAppCommand finns blir det ContainerEntrypoint startpunkten och ContainerAppCommand blir kommandot .

Kommentar

Konfigurationsobjekten ContainerEntrypoint och har blivit inaktuella från och ContainerEntrypointArgs med .NET 8.

Viktigt!

Detta gäller för avancerade användare– de flesta appar behöver inte anpassa sin startpunkt i den här utsträckningen. Mer information och om du vill ange användningsfall för dina scenarier finns i GitHub: .NET SDK container builds discussions( GitHub: .NET SDK container builds discussions).

ContainerUser

Egenskapen för användarkonfiguration styr standardanvändaren som containern körs som. Detta används ofta för att köra containern som en icke-root-användare, vilket är bästa praxis för säkerhet. Det finns några begränsningar för den här konfigurationen att känna till:

  • Den kan ha olika former – användarnamn, linux-användar-ID: er, gruppnamn, linux-grupp-ID username:groupnameoch andra ID-varianter.
  • Det finns ingen verifiering av att den angivna användaren eller gruppen finns på bilden.
  • Att ändra användaren kan ändra appens beteende, särskilt när det gäller saker som filsystembehörigheter .

Standardvärdet för det här fältet varierar beroende på projektets TFM och måloperativsystemet:

  • Om du riktar in dig på .NET 8 eller senare och använder Microsoft Runtime-avbildningarna:
    • på Linux används den rotlösa användaren app (även om den refereras av dess användar-ID)
    • i Windows används den rotlösa användaren ContainerUser
  • Annars används inget standardvärde ContainerUser
<PropertyGroup>
  <ContainerUser>my-existing-app-user</ContainerUser>
</PropertyGroup>

Dricks

Miljövariabeln APP_UID används för att ange användarinformation i containern. Det här värdet kan komma från miljövariabler som definierats i basavbildningen (som microsoft .NET-avbildningar gör), eller så kan du ställa in det själv via syntaxen ContainerEnvironmentVariable .

Du kan dock styra hur appen körs med hjälp ContainerEntrypoint av och ContainerEntrypointArgs.

ContainerEntrypoint

Containerns startpunkt kan användas för att anpassa ENTRYPOINT containerns, vilket är den körbara fil som anropas när containern startas. För versioner som skapar en appvärd anges den som ContainerEntrypointsom standard . För versioner som inte skapar en körbar fil används den dotnet path/to/app.dll som ContainerEntrypoint.

Noden ContainerEntrypoint har ett enda attribut:

  • Include: Kommandot, alternativet eller argumentet som ska användas i ContainerEntrypoint kommandot.

Tänk till exempel på följande exempel på .NET-projektobjektgrupp:

<ItemGroup Label="Entrypoint Assignment">
  <!-- This is how you would start the dotnet ef tool in your container -->
  <ContainerEntrypoint Include="dotnet" />
  <ContainerEntrypoint Include="ef" />

  <!-- This shorthand syntax means the same thing.
       Note the semicolon separating the tokens. -->
  <ContainerEntrypoint Include="dotnet;ef" />
</ItemGroup>

ContainerEntrypointArgs

Containerns startpunkt args-noden styr standardargumenten som tillhandahålls ContainerEntrypointtill . Detta bör användas när ContainerEntrypoint är ett program som användaren kanske vill använda på egen hand. Som standard skapas inga ContainerEntrypointArgs för din räkning.

Noden ContainerEntrypointArg har ett enda attribut:

  • Include: Alternativet eller argumentet som ska tillämpas på ContainerEntrypoint kommandot.

Överväg följande exempel på .NET-projektobjektgrupp:

<ItemGroup>
  <!-- Assuming the ContainerEntrypoint defined above,
       this would be the way to update the database by
       default, but let the user run a different EF command. -->
  <ContainerEntrypointArgs Include="database" />
  <ContainerEntrypointArgs Include="update" />

  <!-- This is the shorthand syntax for the same idea -->
  <ContainerEntrypointArgs Include="database;update" />
</ItemGroup>

Standardcontaineretiketter

Etiketter används ofta för att tillhandahålla konsekventa metadata på containeravbildningar. Det här paketet innehåller några standardetiketter för att uppmuntra till bättre underhåll av de genererade bilderna.

  • org.opencontainers.image.created är inställt på ISO 8601-formatet för aktuell UTC DateTime.

Mer information finns i Implementera konventionella etiketter ovanpå befintlig etikettinfrastruktur.

Rensa resurser

I den här artikeln har du publicerat en .NET-arbetare som en containeravbildning. Ta bort den här resursen om du vill. docker images Använd kommandot för att se en lista över installerade avbildningar.

docker images

Överväg följande exempelutdata:

REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
dotnet-worker-image   1.0.0     25aeb97a2e21   12 seconds ago   191MB

Dricks

Bildfiler kan vara stora. Vanligtvis tar du bort tillfälliga containrar som du skapade när du testade och utvecklade din app. Du brukar ha basavbildningarna med körningen installerad om du planerar att skapa andra avbildningar baserat på den körningen.

Om du vill ta bort avbildningen kopierar du avbildnings-ID:t och kör docker image rm kommandot:

docker image rm 25aeb97a2e21

Nästa steg