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 lär du dig hur du containeriserar ett .NET-program med hjälp av kommandot dotnet publish utan att använda en Dockerfile. Dessutom undersöker du hur du konfigurerar containeravbildningen och körningen, samt hur du städar upp resurser.
Tips
Om du är intresserad av att använda en Dockerfile- för att containerisera din .NET-app kan du läsa Självstudie: Containerisera en .NET-app.
Förutsättningar
Installera följande krav:
-
.NET 8+ SDK
Om du har installerat .NET använder du kommandotdotnet --info
för att avgöra vilken SDK du använder.
Om du planerar att köra containern lokalt behöver du ett containersystem som är kompatibelt med Open Container Initiative (OCI), såsom:
- Docker Desktop: Vanligaste containerkörningsmiljö.
- Podman: Ett daemonlöst alternativ med öppen källkod till Docker.
Viktig
.NET SDK skapar containeravbildningar utan Docker. Docker eller Podman behövs bara om du vill köra avbildningen lokalt. När du som standard publicera .NET-appen som en containeravbildning skickas den till en lokal containerkörning. Du kan också spara avbildningen som en tarball- eller skicka den direkt till ett containerregister utan att använda någon containerkörning alls.
Utöver dessa förutsättningar rekommenderar vi att du är bekant med Worker Services i .NET eftersom exempelprojektet är en arbetare.
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 ungefär så här:
📁 sample-directory
└──📂 Worker
├──appsettings.Development.json
├──appsettings.json
├──DotNet.ContainerImage.csproj
├──Program.cs
├──Worker.cs
├──📂 Properties
│ └─── launchSettings.json
└──📂 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 loggar ett meddelande varje sekund när det körs. Från terminalsessionen ändrar du kataloger och navigerar till mappen Worker. Använd kommandot dotnet run
för att starta appen.
dotnet run
Using launch settings from ./Worker/Properties/launchSettings.json...
Building...
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:28 -06: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: 01/06/2025 13:37:29 -06:00
info: DotNet.ContainerImage.Worker[0]
Worker running at: 01/06/2025 13:37:30 -06:00
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
Arbetsmallen slingrar utan stopp. Använd kommandot Avbryt Ctrl+C för att stoppa det.
Ange containeravbildningens namn
Det finns olika konfigurationsalternativ när du publicerar en app som en container. Containeravbildningens namn är som standard projektets AssemblyName
. Om namnet är ogiltigt som ett containeravbildningsnamn kan du åsidosätta det genom att ange en ContainerRepository
som visas i följande projektfil:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net9.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="9.0.1" />
</ItemGroup>
</Project>
Mer information finns i ContainerRepository
.
Publicera .NET-app
Om du vill publicera .NET-appen som en container använder du följande dotnet publish-kommando:
dotnet publish --os linux --arch x64 /t:PublishContainer
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
).
Viktig
Om du vill publicera containern lokalt måste du ha en aktiv OCI-kompatibel daemon som körs. 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]
Kommandot dotnet publish
genererar utdata som liknar exempelutdata:
Restore complete (0.2s)
DotNet.ContainerImage succeeded (2.6s) → bin\Release\net9.0\linux-x64\publish\
Det här kommandot kompilerar din arbetsapp till publicera mapp och skickar containeravbildningen till din lokala Docker-daemon som standard. Om du använder Podman, ett alias
Publicera en .NET-app som en tarboll
En tarball (eller tar-fil) är en fil som innehåller andra filer. Det slutar vanligtvis med en *.tar.gz sammansatt filnamnsändelse för att visa att det är ett komprimerat arkiv. Dessa filtyper används för att distribuera programvara eller för att skapa säkerhetskopior. I det här fallet används den skapade tarballen för att distribuera en containerbild.
Om du vill publicera en .NET-app som en container till en tarball använder du följande kommando:
dotnet publish --os linux --arch x64 \
/t:PublishContainer \
-p ContainerArchiveOutputPath=./images/container-image.tar.gz
Föregående kommando exporterar appen som en container i en tarball.
- Rikta in sig på Linux som operativsystem (
--os linux
). - Ange den x64-arkitektur (
--arch x64
). - Ange egenskapen
ContainerArchiveOutputPath
till./images/container-image.tar.gz
.
Kommandot kräver inte en OCI-kompatibel daemon som körs. Mer information finns i ContainerArchiveOutputPath
.
Läs in tarballen
Ett vanligt användningsfall för export till en tarball är för säkerhetsfokuserade organisationer. De skapar containrar, exporterar dem som tarballs och kör sedan säkerhetsgenomsökningsverktyg över tarballarna. Den här metoden förenklar efterlevnaden eftersom den undviker komplexiteten i genomsökningen av ett realtidssystem.
Tarball innehåller hela containern, som sedan kan läsas in med lämpligt verktyg:
-
Docker:
docker load -i ./images/container-image.tar.gz
-
Podman:
podman load -i ./images/container-image.tar.gz
Publicera .NET-app till containerregister
Containerregister är tjänster som lagrar och hanterar containeravbildningar. De används för att lagra och distribuera containeravbildningar i flera miljöer. Du kan publicera en .NET-app som en container till ett containerregister med hjälp av följande kommando:
dotnet publish --os linux --arch x64 \
/t:PublishContainer \
-p ContainerRegistry=ghcr.io
Föregående kod publicerar appen som en container till ett containerregister:
- Rikta in sig på Linux som operativsystem (
--os linux
). - Ange en specifik x64-arkitektur (
--arch x64
). - Ange egenskapen
ContainerRegistry
tillghcr.io
.
Mer information finns i ContainerRegistry.
Rensa resurser
I den här artikeln har du publicerat en .NET-arbetstjänst som en containerbild. Ta bort den här resursen om du vill. Använd kommandot docker images
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
Tips
Bildfiler kan vara stora. Vanligtvis tar du bort tillfälliga containrar som du skapade när du testade och utvecklade din app. Du brukar behålla basbilderna med runtime installerat om du planerar att bygga andra bilder baserade på det.
Om du vill ta bort avbildningen kopierar du avbildnings-ID:t och kör kommandot docker image rm
:
docker image rm 25aeb97a2e21