Condividi tramite


Aspire e Visual Studio Code i contenitori di sviluppo

L'estensione Dev Containers consente ai team di sviluppo di sviluppare all'interno di un ambiente in contenitori Visual Studio Code in cui tutte le dipendenze sono preconfigurate. Con Aspire la versione 9.1, è stata introdotta una logica per supportare meglio il lavoro con Aspire all'interno di un ambiente Dev Container configurando automaticamente il port forwarding.

Prima Aspire della versione 9.1, è possibile usare Aspire all'interno di un contenitore di sviluppo, ma è stata richiesta una configurazione più manuale.

Contenitori di sviluppo vs. GitHub Codespaces

L'uso di contenitori di sviluppo in Visual Studio Code è simile all'uso di GitHub Codespaces. Con la versione Aspire 9.1, il supporto per i contenitori di sviluppo in Visual Studio Code e GitHub Codespaces è stato migliorato. Anche se le esperienze sono simili, esistono alcune differenze. Per altre informazioni sull'uso di Aspire con GitHub Codespaces, vedere Aspire e GitHub Codespaces.

Guida introduttiva all'uso del repository di modelli

Per configurare i contenitori di sviluppo in Visual Studio Code, usare il file _.devcontainer/devcontainer.json nel repository. Il modo più semplice per iniziare consiste nel creare un nuovo repository dal repository dei modelli. Tenere in considerazione i passaggi seguenti:

  1. Creare un nuovo repository usando il modello.

    Creare un nuovo repository.

    Dopo aver specificato i dettagli e aver selezionato Crea repository, il repository viene creato e visualizzato in GitHub.

  2. Clonare il repository nella workstation per sviluppatori locale usando il comando seguente:

    git clone https://github.com/<org>/<username>/<repository>
    
  3. Aprire il repository in Visual Studio Code. Dopo alcuni istanti Visual Studio Code rileva il file .devcontainer/devcontainer.json e chiede di aprire il repository all'interno di un contenitore. Selezionare l'opzione più appropriata per il flusso di lavoro.

    Richiedi di aprire il repository all'interno di un contenitore.

    Dopo alcuni istanti, l'elenco dei file diventa visibile e la compilazione locale del contenitore di sviluppo verrà completata.

    Compilazione del contenitore di sviluppo completata.

  4. Aprire una nuova finestra del terminale in Visual Studio Code (Ctrl+Shift+`) e creare un nuovo Aspire progetto usando la dotnet riga di comando.

    dotnet new aspire-starter -n HelloAspire
    

    Dopo alcuni istanti, il progetto verrà creato e le dipendenze iniziali verranno ripristinate.

  5. Aprire il file ProjectName.AppHost/AppHost.cs nell'editor e selezionare il pulsante Esegui nell'angolo superiore destro della finestra dell'editor.

    Pulsante Esegui nell'editor.

    Visual Studio Code compila e avvia Aspire AppHost e apre automaticamente il Aspire dashboard. Poiché gli endpoint ospitati nel contenitore utilizzano per la prima volta un certificato autofirmato, quando si accede a un endpoint per uno specifico contenitore di sviluppo, si verifica un errore di certificato.

    Errore del certificato del browser.

    È previsto l'errore del certificato. Dopo aver confermato che l'URL richiesto corrisponde al dashboard nel contenitore di sviluppo, è possibile ignorare questo avviso.

    Aspire il dashboard in esecuzione in Dev Container.

    Aspire configura automaticamente le porte inoltrate in modo che quando si selezionano gli endpoint nel Aspire dashboard vengano sottoposto a tunneling in processi e contenitori annidati all'interno del contenitore di sviluppo.

  6. Eseguire il commit delle modifiche nel GitHub repository

    Dopo aver creato correttamente il Aspire progetto e aver verificato che venga avviato ed è possibile accedere al dashboard, è consigliabile eseguire il commit delle modifiche nel repository.

Configurazione manuale di devcontainer.json

La procedura dettagliata precedente illustra il processo semplificato di creazione di un contenitore di sviluppo usando il Aspire modello Dev Container. Se si dispone già di un repository esistente e si vuole usare la funzionalità Dev Container con Aspire, aggiungere un filedevcontainer.json alla cartella .devcontainer all'interno del repository:

└───📂 .devcontainer
     └─── devcontainer.json

Il repository di modelli contiene una copia del file devcontainer.json che è possibile usare come punto di partenza, che deve essere sufficiente per Aspire. Di seguito JSON è riportata la versione più recente del file .devcontainer/devcontainer.json dal modello:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
    "name": "Aspire",
    // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
    "image": "mcr.microsoft.com/devcontainers/dotnet:dev-10.0-noble",
    "features": {
        "ghcr.io/devcontainers/features/docker-in-docker:2": {},
        "ghcr.io/devcontainers/features/powershell:1": {}
    },

    "hostRequirements": {
        "cpus": 8,
        "memory": "32gb",
        "storage": "64gb"
    },

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // "forwardPorts": [5000, 5001],
    // "portsAttributes": {
    //		"5001": {
    //			"protocol": "https"
    //		}
    // }

    // Use 'postCreateCommand' to run commands after the container is created.
    // "postCreateCommand": "dotnet restore",
    "onCreateCommand": "curl -sSL https://aspire.dev/install.sh | bash",
    "postStartCommand": "dotnet dev-certs https --trust",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-dotnettools.csdevkit",
                "GitHub.copilot-chat",
                "GitHub.copilot"
            ]
        }
    }
    // Configure tool-specific properties.
    // "customizations": {},

    // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
    // "remoteUser": "root"
}

Scenari di container di sviluppo

Il modello di contenitore di sviluppo di base Aspire funziona bene per scenari semplici, ma potrebbe essere necessaria una configurazione aggiuntiva a seconda dei requisiti specifici. Le sezioni seguenti forniscono esempi per vari scenari comuni.

Solo app senza .NET stato

Per progetti semplici Aspire che usano .NET solo risorse di progetto senza contenitori esterni o orchestrazione complessa, è possibile usare una configurazione minima di Dev Container:

{
  "name": "Aspire - Simple",
  "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
  "onCreateCommand": "dotnet new install Aspire.ProjectTemplates --force",
  "postStartCommand": "dotnet dev-certs https --trust",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit"
      ]
    }
  }
}

Questa configurazione minima è adatta alle Aspire app che orchestrano solo .NET i servizi senza dipendenze esterne.

Aggiunta di Node.js risorse

Se la tua app Aspire include risorse Node.js, aggiungi la funzionalità Node.js al contenitore di sviluppo.

{
  "name": "Aspire with Node.js",
  "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/node:1": {
      "version": "lts"
    }
  },
  "onCreateCommand": "dotnet new install Aspire.ProjectTemplates --force",
  "postStartCommand": "dotnet dev-certs https --trust",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit",
        "ms-vscode.vscode-typescript-next"
      ]
    }
  }
}

Questa configurazione fornisce sia .NET che Node.js funzionalità di sviluppo all'interno dello stesso ambiente contenitore.

Orchestrazione dei container con Docker-in-Docker

Quando l'app Aspire orchestra le risorse del contenitore, è necessario Dockeril supporto di -in-Docker (DinD). Ecco una configurazione di base:

{
  "name": "Aspire with Containers",
  "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {
      "version": "latest",
      "enableNonRootDocker": true,
      "moby": true
    }
  },
  "hostRequirements": {
    "cpus": 4,
    "memory": "16gb",
    "storage": "32gb"
  },
  "onCreateCommand": "dotnet new install Aspire.ProjectTemplates --force",
  "postStartCommand": "dotnet dev-certs https --trust",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit",
        "ms-azuretools.vscode-docker"
      ]
    }
  }
}

Rete avanzata dei contenitori

Se si verificano problemi di rete tra contenitori o è necessario il supporto IPv6, è possibile aggiungere una configurazione di rete aggiuntiva:

{
  "name": "Aspire with Advanced Networking",
  "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {
      "version": "latest",
      "enableNonRootDocker": true,
      "moby": true
    }
  },
  "runArgs": [
    "--sysctl",
    "net.ipv6.conf.all.disable_ipv6=0",
    "--sysctl",
    "net.ipv6.conf.default.forwarding=1",
    "--sysctl",
    "net.ipv6.conf.all.forwarding=1"
  ],
  "hostRequirements": {
    "cpus": 8,
    "memory": "32gb",
    "storage": "64gb"
  },
  "onCreateCommand": "dotnet new install Aspire.ProjectTemplates --force",
  "postStartCommand": "dotnet dev-certs https --trust",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit",
        "ms-azuretools.vscode-docker"
      ]
    }
  }
}

Importante

Docker-in-Docker considerazioni:

  • Docker-in-Docker richiede un'allocazione di risorse superiore, tra cui un aumento della CPU, della memoria e dell'archiviazione.
  • La configurazione di rete avanzata precedente include le impostazioni di inoltro IPv6 che potrebbero essere necessarie per scenari di comunicazione da contenitore a contenitore complessi.
  • Questa configurazione funziona con Docker Desktop, ma potrebbe avere limitazioni con Rancher Desktop.
  • La connettività di rete tra contenitori potrebbe richiedere una configurazione aggiuntiva a seconda del caso d'uso specifico.

Dapr esempi di integrazione

Per le app Aspire che si integrano con Dapr, è possibile configurare i componenti Dapr nel Dev Container. Per altre informazioni, vedere AspireDapr Integrazione.

Configurazione di base Dapr

{
  "name": "Aspire with Dapr",
  "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {
      "enableNonRootDocker": true
    },
    "ghcr.io/dapr/cli/dapr-cli:0": {}
  },
  "onCreateCommand": "dotnet new install Aspire.ProjectTemplates --force",
  "postCreateCommand": "dotnet dev-certs https --trust && dapr init",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit",
        "ms-azuretools.vscode-dapr"
      ]
    }
  }
}

Dapr con back-end esterni

Per scenari più complessi Dapr che usano back-end esterni (Redis, PostgreSQL), è possibile usare Docker Compose:

{
  "name": "Aspire with Dapr and Backends",
  "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/docker-in-docker:2": {
      "enableNonRootDocker": true
    },
    "ghcr.io/dapr/cli/dapr-cli:0": {}
  },
  "runArgs": [
    "--sysctl",
    "net.ipv6.conf.all.disable_ipv6=0"
  ],
  "onCreateCommand": "dotnet new install Aspire.ProjectTemplates --force",
  "postCreateCommand": [
    "dotnet dev-certs https --trust",
    "docker compose up -d",
    "dapr init"
  ],
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-dotnettools.csdevkit",
        "ms-azuretools.vscode-dapr",
        "ms-azuretools.vscode-docker"
      ]
    }
  }
}

Considerazioni comuni

Quando si usano contenitori di sviluppo con Aspire, tenere presenti le considerazioni seguenti:

Requisiti delle risorse

  • App di base.NET: le risorse del contenitore Dev Standard sono sufficienti per scenari semplici.
  • Orchestrazione dei contenitori: sono consigliate almeno 8 CPU, 32 GB di memoria e 64 GB di spazio di archiviazione.
  • Scenari complessi con Dapr/Kubernetes: per ottenere prestazioni ottimali è consigliabile un'allocazione di risorse più elevata.

Networking

  • La configurazione IPv6 può essere necessaria per la comunicazione da contenitore a contenitore.
  • Il port forwarding viene gestito automaticamente dalla Aspire versione 9.1 e versioni successive.
  • La connettività del servizio esterno dipende dalla configurazione del runtime del contenitore.

Prestazioni

  • Docker-in-Docker gli scenari comportano un sovraccarico delle prestazioni rispetto a quello nativo Docker.
  • Prendere in considerazione l'uso di Docker al di fuori di Docker (DooD) per i flussi di lavoro di produzione.
  • Gli scenari di sviluppo e distribuzione locali possono richiedere configurazioni diverse.

sicurezza

  • I contenitori di sviluppo vengono eseguiti con privilegi elevati quando si usa Docker-in-Docker.
  • L'attendibilità del certificato SSL viene gestita automaticamente nella maggior parte degli scenari.
  • Prendere in considerazione le implicazioni per la sicurezza quando si espongono le porte negli ambienti cloud.

Vedere anche