.NET Aspire 和 Visual Studio Code 开发容器

开发容器Visual Studio Code扩展为开发团队提供了一种在预配置所有依赖项的容器化环境中进行开发的方法。 在 .NET Aspire 9.1 中,通过自动配置端口转发,添加了一定逻辑,以便更好地支持在开发容器环境中使用 .NET Aspire。

在 9.1 之前 .NET Aspire ,可以在开发容器中使用 .NET Aspire ,但需要更多手动配置。

开发容器与 GitHub Codespaces

使用开发容器 Visual Studio Code 类似于使用 GitHub Codespaces。 随着 9.1 版本的发布,.NET Aspire 增强了对 Visual Studio Code 和 GitHub Codespaces 中 Dev Containers 的支持。 虽然体验相似,但存在一些差异。 有关使用.NET AspireGitHub与 Codespaces 的详细信息,请参阅 .NET Aspire 和 GitHub Codespaces

使用模板存储库快速入门

若要配置 Visual Studio Code开发容器,请使用存储库中的 _.devcontainer/devcontainer.json 文件。 最简单的入门方法是从 模板存储库创建新存储库。 考虑以下步骤:

  1. 使用模板创建新存储库

    创建新存储库。

    提供详细信息并选择 “创建存储库”后,将创建并显示 GitHub存储库。

  2. 使用以下命令将存储库克隆到本地开发人员工作站:

    git clone https://github.com/<org>/<username>/<repository>
    
  3. 在Visual Studio Code中打开存储库。 片刻 Visual Studio Code 后,检测到 .devcontainer/devcontainer.json 文件并提示在容器中打开存储库。 选择最适合工作流的选项。

    提示打开容器内的存储库。

    片刻之后,文件列表将可见,开发容器的本地生成将完成。

    开发容器生成已完成。

  4. 在 (Ctrl+Shift+`) 中Visual Studio Code打开一个新的终端窗口,并使用dotnet命令行创建新.NET.NET Aspire项目。

    dotnet new aspire-starter -n HelloAspire
    

    片刻之后,将创建项目并还原初始依赖项。

  5. 在编辑器中打开 ProjectName.AppHost/Program.cs 文件,然后选择编辑器窗口右上角的运行按钮。

    编辑器中的“运行”按钮。

    Visual Studio Code 生成并启动 .NET Aspire 应用主机,并自动打开 .NET Aspire 仪表板。 由于容器中托管的终结点第一次使用自签名证书,因此访问特定开发容器的终结点时出现证书错误。

    浏览器证书错误。

    证书错误是预期的。 确认请求的 URL 对应于开发容器中的仪表板后,可以忽略此警告。

    .NET.NET Aspire 在开发容器中运行的仪表板。

    .NET Aspire 自动配置转发端口,这样当您在 .NET Aspire 仪表板中点击终结点时,它们会通过隧道被连接到 Dev 容器中的进程和嵌套容器。

  6. 将更改提交到 GitHub 存储库

    成功创建 .NET.NET Aspire 项目并验证它是否启动并可以访问仪表板后,最好将更改提交到存储库。

手动配置 devcontainer.json

前面的演练演示了使用 .NET.NET Aspire 开发容器模板创建开发容器的简化过程。 如果已有一个存储库并且希望结合使用 .NET.NET Aspire开发容器功能,请将 devcontainer.json 文件添加到存储库中的 .devcontainer 文件夹中:

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

模板存储库包含一个 devcontainer.json文件的副本,该文件可以用作起点,这应该足以满足此要求.NET.NET Aspire。 下面 JSON 表示模板中 .devcontainer/devcontainer.json 文件的最新版本:

// 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": ".NET Aspire",
    // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
    "image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
    "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"
}

开发容器场景

基本 .NET.NET Aspire 开发容器模板适用于简单方案,但可能需要根据特定要求进行其他配置。 以下部分提供了各种常见方案的示例。

仅限无状态 .NET 应用

对于仅使用.NET项目资源而不依赖外部容器或复杂编排的简单.NET Aspire项目,您可以使用一个最小的 Dev 容器配置。

{
  "name": ".NET 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"
      ]
    }
  }
}

此最小配置适用于仅协调 .NET 服务且不依赖外部依赖项的 .NET Aspire 应用。

添加 Node.js 资源

.NET Aspire如果应用包含Node.js资源,请将Node.js该功能添加到开发容器:

{
  "name": ".NET 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"
      ]
    }
  }
}

此配置在同一容器环境中提供开发.NETNode.js功能。

使用 Docker-in-Docker 的容器业务流程

当 .NET Aspire 应用编排容器资源时,需要 Docker-in-Docker (DinD) 支持。 下面是基本配置:

{
  "name": ".NET 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"
      ]
    }
  }
}

高级容器网络

如果在容器之间遇到网络问题或需要 IPv6 支持,可以添加其他网络配置:

{
  "name": ".NET 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"
      ]
    }
  }
}

重要

Docker-in-Docker 注意事项:

  • Docker-in-Docker 要求分配更多的资源,包括增加 CPU、内存和存储。
  • 上述高级网络配置包括可能需要用于复杂容器到容器通信方案的 IPv6 转发设置。
  • 此配置适用于 Docker 桌面,但可能会对 Rancher Desktop 有限制。
  • 容器之间的网络连接可能需要其他配置,具体取决于特定的用例。

Dapr 集成示例

对于 .NET Aspire 与 Dapr集成的应用,可以在开发容器中设置 Dapr 组件。 有关详细信息,请参阅 .NET AspireDapr 集成

基本 Dapr 设置

{
  "name": ".NET 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

对于使用外部后端的更复杂的 Dapr 方案(如 Redis 和 PostgreSQL),可以使用 Docker Compose:

{
  "name": ".NET 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"
      ]
    }
  }
}

一般注意事项

使用开发容器 .NET.NET Aspire时,请记住以下注意事项:

资源要求

  • 基本 .NET 应用:标准开发容器资源足以满足简单方案。
  • 容器业务流程:建议至少使用 8 个 CPU、32GB 内存和 64GB 存储。
  • 在涉及Dapr和Kubernetes的复杂场景中:建议进行较高的资源分配,以获得最佳性能。

联网

  • 容器到容器通信可能需要 IPv6 配置。
  • 端口转发由 9.1 及更高版本自动处理 .NET.NET Aspire 。
  • 外部服务连接取决于容器运行时配置。

性能

  • Docker-in-Docker 应用场景相比本机 Docker 会产生性能开销。
  • 请考虑在 Docker(DooD)之外使用 Docker 以进行生产工作流。
  • 本地开发和部署方案可能需要不同的配置。

安全性

  • 在使用 Docker-in-Docker 时,开发容器将以提升的特权运行。
  • 大多数情况下会自动处理 SSL 证书信任。
  • 在云环境中公开端口时,请考虑安全隐患。

另请参阅