Condividi tramite


Containerizzare un'app .NET con dotnet publish

I contenitori hanno molte funzionalità e vantaggi, ad esempio un'infrastruttura non modificabile, offrono un'architettura portabile e consentono la scalabilità. L'immagine può essere usata per creare contenitori per l'ambiente di sviluppo locale, il cloud privato o il cloud pubblico. Questa esercitazione illustra come inserire in contenitori un'applicazione .NET usando il comando dotnet publish senza l'uso di un Dockerfile. Esamina inoltre come configurare l'immagine del contenitore e l'esecuzione di, e come ripulire le risorse.

Mancia

Se si è interessati a usare un Dockerfile per inserire in contenitori l'app .NET, vedere esercitazione : Containerizzare un'app .NET.

Prerequisiti

Installare i prerequisiti seguenti:

  • .NET 8+ SDK
    Se è installato .NET, usare il comando dotnet --info per determinare quale SDK si sta usando.

Se si prevede di eseguire il contenitore in locale, è necessario un runtime del contenitore compatibile con Open Container Initiative (OCI), ad esempio:

  • Docker Desktop: il runtime per contenitori più comune.
  • Podman: alternativa open source senza daemon a Docker.

Importante

.NET SDK crea immagini del contenitore senza Docker. Docker o Podman sono necessari solo se si vuole eseguire l'immagine in locale. Per impostazione predefinita, quando si pubblichi l'app .NET come immagine del contenitore, viene inserita in un runtime del contenitore locale. In alternativa, è possibile salvare l'immagine come tarball o eseguirne il push direttamente in un registro contenitori senza usare alcun runtime del contenitore.

Oltre a questi prerequisiti, è consigliabile acquisire familiarità con i servizi Worker in .NET, poiché il progetto di esempio è un worker.

Creare un'app .NET

Hai bisogno di un'app .NET da containerizzare, quindi inizia creando una nuova app da un modello. Apri il terminale, crea una cartella di lavoro (sample-directory) se non l'hai già fatto e cambia directory per accedervi. Nella cartella di lavoro eseguire il comando seguente per creare un nuovo progetto in una sottodirectory denominata Worker:

dotnet new worker -o Worker -n DotNet.ContainerImage

La tua struttura di cartelle è simile alla seguente struttura:

📁 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

Il comando dotnet new crea una nuova cartella denominata Worker e genera un servizio di lavoro che, quando viene eseguito, registra un messaggio ogni secondo. Dalla sessione del terminale, cambia directory e accedi alla cartella Worker. Usare il comando dotnet run per avviare l'app.

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...

Il modello di lavoro esegue cicli illimitati. Usare il comando cancel CTRL+C per arrestarlo.

Impostare il nome dell'immagine del contenitore

Durante la pubblicazione di un'app come contenitore sono disponibili diverse opzioni di configurazione. Per impostazione predefinita, il nome dell'immagine del contenitore è il AssemblyName del progetto. Se tale nome non è valido come nome dell'immagine del contenitore, è possibile eseguirne l'override specificando un ContainerRepository come illustrato nel file di progetto seguente:

<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.2" />
  </ItemGroup>
</Project>

Per ulteriori riferimenti, consultare ContainerRepository.

Pubblicare un'app .NET

Per pubblicare l'app .NET come contenitore, usare il seguente comando dotnet publish:

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

Il comando precedente del .NET CLI pubblica l'app in un contenitore:

  • Puntare su Linux come sistema operativo (--os linux).
  • Specificare un'architettura x64 (--arch x64)

Importante

Per pubblicare il contenitore in locale, è necessario disporre di un daemon conforme a OCI attivo in esecuzione. Se non è in esecuzione quando si tenta di pubblicare l'app come contenitore, si verifica un errore simile al seguente:

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

Il comando dotnet publish genera un output simile all'output di esempio:

Restore complete (0.2s)
  DotNet.ContainerImage succeeded (2.6s) → bin\Release\net9.0\linux-x64\publish\

Questo comando compila la tua applicazione worker nella cartella publish ed invia l'immagine del contenitore al daemon Docker locale di default. Se stai usando Podman, un alias

Pubblicare un'app .NET in un archivio tarball

Un file tarball (o tar) è un file che contiene altri file. Termina di solito con l'estensione di file composta *.tar.gz per indicare che si tratta di un archivio compresso. Questi tipi di file vengono usati per distribuire software o per creare backup. In questo caso, il tarball creato viene usato per distribuire un'immagine del container.

Per pubblicare un'app .NET come contenitore in un tarball, usare il comando seguente:

dotnet publish --os linux --arch x64 \
    /t:PublishContainer \
    -p ContainerArchiveOutputPath=./images/container-image.tar.gz

Il comando precedente pubblica l'app come contenitore in un tarball:

  • Impostare Linux come sistema operativo (--os linux).
  • Specificare un'architettura x64 (--arch x64).
  • Impostazione della proprietà ContainerArchiveOutputPath su ./images/container-image.tar.gz.

Il comando non richiede un daemon conforme a OCI in esecuzione. Per altre informazioni, vedere ContainerArchiveOutputPath.

Caricare il tarball

Un caso d'uso comune per l'esportazione in un tarball riguarda le organizzazioni orientate alla sicurezza. Creano contenitori, li esportano come tarball e quindi utilizzano strumenti di scansione di sicurezza sui tarball. Questo approccio semplifica la conformità in quanto evita le complessità dell'analisi di un sistema attivo.

Il tarball contiene l'intero contenitore, che può quindi essere caricato usando lo strumento appropriato:

  • Docker: docker load -i ./images/container-image.tar.gz
  • Podman: podman load -i ./images/container-image.tar.gz

Pubblicare un'app .NET nel registro di contenitori

I registri contenitori sono servizi che archiviano e gestiscono le immagini del contenitore. Vengono usati per archiviare e distribuire immagini del contenitore in più ambienti. È possibile pubblicare un'app .NET come contenitore in un registro contenitori usando il comando seguente:

dotnet publish --os linux --arch x64 \
    /t:PublishContainer \
    -p ContainerRegistry=ghcr.io

Il codice precedente pubblica l'app come container in un registro di container.

  • Puntare su Linux come sistema operativo (--os linux).
  • Specificare un'architettura x64 (--arch x64).
  • Impostazione della proprietà ContainerRegistry su ghcr.io.

Per altre informazioni, vedere ContainerRegistry.

Pulire le risorse

In questo articolo, hai pubblicato un worker .NET come immagine container. Se si vuole, eliminare questa risorsa. Usare il comando docker images per visualizzare un elenco di immagini installate.

docker images

Si consideri l'output di esempio seguente:

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

Consiglio

I file di immagine possono essere di grandi dimensioni. In genere, si rimuoverebbero i contenitori temporanei creati durante il test e lo sviluppo dell'app. In genere si mantengono le immagini di base con il runtime installato se si prevede di creare altre immagini in base a tale runtime.

Per eliminare l'immagine, copiare l'ID immagine ed eseguire il comando docker image rm:

docker image rm 25aeb97a2e21

Passaggi successivi