使用 ASP.NET Core 的 Visual Studio Tools for DockerVisual Studio Tools for Docker with ASP.NET Core

Visual Studio 2017 及更高版本支持构建、调试和运行面向 .NET Core 且已容器化的 ASP.NET Core 应用。Visual Studio 2017 and later versions support building, debugging, and running containerized ASP.NET Core apps targeting .NET Core. Windows 和 Linux 容器均受支持。Both Windows and Linux containers are supported.

查看或下载示例代码如何下载View or download sample code (how to download)

系统必备Prerequisites

安装和设置Installation and setup

如需安装 Docker,请先通过用于 Windows 的 Docker:安装须知了解相关信息。For Docker installation, first review the information at Docker for Windows: What to know before you install. 然后安装用于 Windows 的 DockerNext, install Docker For Windows.

Docker for Windows 中的共享驱动器必须配置为支持卷映射和调试。Shared Drives in Docker for Windows must be configured to support volume mapping and debugging. 右键单击系统托盘中的 Docker 图标,单击“设置”,然后选择“共享驱动器”。Right-click the System Tray's Docker icon, select Settings, and select Shared Drives. 选择 Docker 存储文件的驱动器。Select the drive where Docker stores files. 单击“应用”。Click Apply.

为容器选择本地驱动器 C 作为共享驱动器的对话框

提示

未配置共享驱动器时,Visual Studio 2017 15.6 及更高版本会发出提示。Visual Studio 2017 versions 15.6 and later prompt when Shared Drives aren't configured.

向 Docker 容器添加项目Add a project to a Docker container

若要容器化 ASP.NET Core 项目,项目必须面向 .NET Core。To containerize an ASP.NET Core project, the project must target .NET Core. 同时支持 Linux 和 Windows 容器。Both Linux and Windows containers are supported.

向项目添加 Docker 支持后,可选择 Windows 或 Linux 容器。When adding Docker support to a project, choose either a Windows or a Linux container. Docker 主机必须运行类型相同的容器。The Docker host must be running the same container type. 要更改正在运行的 Docker 实例中的容器类型,请右键单击系统托盘中的 Docker 图标,再选择“切换到 Windows 容器...”或“切换到 Linux 容器...”。To change the container type in the running Docker instance, right-click the System Tray's Docker icon and choose Switch to Windows containers... or Switch to Linux containers....

新应用New app

使用“ASP.NET Core Web 应用”项目模板新建应用时,请选中“启用 Docker 支持”复选框:When creating a new app with the ASP.NET Core Web Application project templates, select the Enable Docker Support check box:

“启用 Docker 支持”复选框

如果目标框架是 .NET Core,可通过 OS 下拉列表选择容器类型。If the target framework is .NET Core, the OS drop-down allows for the selection of a container type.

现有应用Existing app

对于面向 .NET Core 的 ASP.NET Core 项目,可通过两个选项使用工具添加 Docker 支持。For ASP.NET Core projects targeting .NET Core, there are two options for adding Docker support via the tooling. 在 Visual Studio 中打开项目,然后选择以下选项之一:Open the project in Visual Studio, and choose one of the following options:

  • 从“项目”菜单中选择“Docker 支持”。Select Docker Support from the Project menu.
  • 右键单击“解决方案资源管理器”中的项目,然后选择“添加” > “Docker 支持”。Right-click the project in Solution Explorer and select Add > Docker Support.

Visual Studio Tools for Docker 不支持向面向.NET Framework 的现有 ASP.NET Core 项目添加 Docker。The Visual Studio Tools for Docker don't support adding Docker to an existing ASP.NET Core project targeting .NET Framework.

Dockerfile 概述Dockerfile overview

Dockerfile,用作创建最终 Docker 映像的方案,添加到项目根目录。A Dockerfile, the recipe for creating a final Docker image, is added to the project root. 请参阅 Dockerfile 引用,了解其中的命令。Refer to Dockerfile reference for an understanding of the commands within it. 此特定 Dockerfile 使用多阶段生成,该生成包含四个不同的命名生成阶段:This particular Dockerfile uses a multi-stage build with four distinct, named build stages:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 AS base
WORKDIR /app
EXPOSE 59518
EXPOSE 44364

FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build
WORKDIR /src
COPY HelloDockerTools/HelloDockerTools.csproj HelloDockerTools/
RUN dotnet restore HelloDockerTools/HelloDockerTools.csproj
COPY . .
WORKDIR /src/HelloDockerTools
RUN dotnet build HelloDockerTools.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish HelloDockerTools.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "HelloDockerTools.dll"]

前面的 Dockerfile 基于 microsoft/dotnet 映像。The preceding Dockerfile is based on the microsoft/dotnet image. 此基础映像包括 ASP.NET Core 运行时和 NuGet 包。This base image includes the ASP.NET Core runtime and NuGet packages. 对该包进行了实时 (JIT) 编译,以提高启动性能。The packages are just-in-time (JIT) compiled to improve startup performance.

如果选中了新建项目对话框的“为 HTTPS 配置”复选框,则 Dockerfile 公开两个端口。When the new project dialog's Configure for HTTPS check box is checked, the Dockerfile exposes two ports. 一个端口用于 HTTP 流量;另一个端口用于 HTTPS。One port is used for HTTP traffic; the other port is used for HTTPS. 如果未选中该复选框,则为 HTTP 流量公开单个端口 (80)。If the check box isn't checked, a single port (80) is exposed for HTTP traffic.

FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY HelloDockerTools/HelloDockerTools.csproj HelloDockerTools/
RUN dotnet restore HelloDockerTools/HelloDockerTools.csproj
COPY . .
WORKDIR /src/HelloDockerTools
RUN dotnet build HelloDockerTools.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish HelloDockerTools.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "HelloDockerTools.dll"]

前面的 Dockerfile 基于 microsoft/aspnetcore 映像。The preceding Dockerfile is based on the microsoft/aspnetcore image. 此基础映像包括 ASP.NET Core NuGet 包,对该包进行了实时编译 (JIT),以提高启动性能。This base image includes the ASP.NET Core NuGet packages, which are just-in-time (JIT) compiled to improve startup performance.

向应用添加容器业务流程协调程序支持Add container orchestrator support to an app

Visual Studio 2017 版本 15.7 或更早版本支持 Docker Compose 作为唯一的容器业务流程解决方案。Visual Studio 2017 versions 15.7 or earlier support Docker Compose as the sole container orchestration solution. 可通过“添加” > “Docker 支持”添加 Docker Compose。The Docker Compose artifacts are added via Add > Docker Support.

Visual Studio 2017 版本 15.8 或更高版本仅在获得指示时添加业务流程解决方案。Visual Studio 2017 versions 15.8 or later add an orchestration solution only when instructed. 右键单击“解决方案资源管理器”中的项目,然后选择“添加” > “容器业务流程协调程序支持”。Right-click the project in Solution Explorer and select Add > Container Orchestrator Support. 提供了以下两个不同的选择:Docker ComposeService FabricTwo different choices are offered: Docker Compose and Service Fabric.

Docker ComposeDocker Compose

Visual Studio Tools for Docker 通过以下文件向解决方案添加 docker-compose 项目:The Visual Studio Tools for Docker add a docker-compose project to the solution with the following files:

  • docker-compose.dcproj – 表示项目的文件。docker-compose.dcproj – The file representing the project. 包括 <DockerTargetOS> 元素,用于指定要使用的操作系统。Includes a <DockerTargetOS> element specifying the OS to be used.
  • .dockerignore – 列出在生成生成上下文时要排除的文件和目录模式。.dockerignore – Lists the file and directory patterns to exclude when generating a build context.
  • docker-compose.yml – 基本 Docker Compose 文件,用于定义要分别通过 docker-compose builddocker-compose run 生成和运行的映像集合。docker-compose.yml – The base Docker Compose file used to define the collection of images built and run with docker-compose build and docker-compose run, respectively.
  • docker compose.override.yml – 一个可选文件,通过 Docker Compose 读取,包含服务的配置替代。docker-compose.override.yml – An optional file, read by Docker Compose, with configuration overrides for services. Visual Studio 执行 docker-compose -f "docker-compose.yml" -f "docker-compose.override.yml" 以合并这些文件。Visual Studio executes docker-compose -f "docker-compose.yml" -f "docker-compose.override.yml" to merge these files.

docker-compose.yml 文件引用在项目运行时创建的映像的名称:The docker-compose.yml file references the name of the image that's created when the project runs:

version: '3.4'

services:
  hellodockertools:
    image: ${DOCKER_REGISTRY}hellodockertools
    build:
      context: .
      dockerfile: HelloDockerTools/Dockerfile

在前面的示例中,应用在“调试”模式下运行时,image: hellodockertools 生成映像 hellodockertools:devIn the preceding example, image: hellodockertools generates the image hellodockertools:dev when the app runs in Debug mode. 应用在“发布”模式下运行时,生成 hellodockertools:latest 映像。The hellodockertools:latest image is generated when the app runs in Release mode.

如果将映像推送到注册表,则需要添加 Docker Hub 用户名(如 dockerhubusername/hellodockertools)作为映像名称的前缀名。Prefix the image name with the Docker Hub username (for example, dockerhubusername/hellodockertools) if the image is pushed to the registry. 或者,更改映像名称,使其包含专用注册表 URL(如 privateregistry.domain.com/hellodockertools),具体取决于所用配置。Alternatively, change the image name to include the private registry URL (for example, privateregistry.domain.com/hellodockertools) depending on the configuration.

如果根据生成配置需要不同行为(例如,调试或发布),请添加特定于配置的 docker-compose 文件。If you want different behavior based on the build configuration (for example, Debug or Release), add configuration-specific docker-compose files. 这些文件应根据生成配置进行命名(例如,docker-compose.vs.debug.yml 和 docker compose.vs.release.yml)并放置在与 docker-compose-override.yml 文件相同的位置。The files should be named according to the build configuration (for example, docker-compose.vs.debug.yml and docker-compose.vs.release.yml) and placed in the same location as the docker-compose-override.yml file.

使用特定于配置的替代文件,可以为调试和发布生成配置指定不同的配置设置(如环境变量或入口点)。Using the configuration-specific override files, you can specify different configuration settings (such as environment variables or entry points) for Debug and Release build configurations.

Service FabricService Fabric

除了基础必备组件外,Service Fabric 业务流程解决方案还需要以下必备组件:In addition to the base Prerequisites, the Service Fabric orchestration solution demands the following prerequisites:

Service Fabric 不支持在 Windows 上的本地开发群集中运行 Linux 容器。Service Fabric doesn't support running Linux containers in the local development cluster on Windows. 如果项目已在使用 Linux 容器,Visual Studio 会提示切换到 Windows 容器。If the project is already using a Linux container, Visual Studio prompts to switch to Windows containers.

Visual Studio Tools for Docker 执行以下任务:The Visual Studio Tools for Docker do the following tasks:

  • 向解决方案添加 <project_name>Application Service Fabric 应用程序项目。Adds a <project_name>Application Service Fabric Application project to the solution.

  • 向 ASP.NET Core 项目添加 Dockerfile 和 .dockerignore 文件。Adds a Dockerfile and a .dockerignore file to the ASP.NET Core project. 如果 ASP.NET Core 项目中已存在 Dockerfile,则其重命名为 Dockerfile.original。If a Dockerfile already exists in the ASP.NET Core project, it's renamed to Dockerfile.original. 创建类似于以下形式的新 Dockerfile:A new Dockerfile, similar to the following, is created:

    # See https://aka.ms/containerimagehelp for information on how to use Windows Server 1709 containers with Service Fabric.
    # FROM microsoft/aspnetcore:2.0-nanoserver-1709
    FROM microsoft/aspnetcore:2.0-nanoserver-sac2016
    ARG source
    WORKDIR /app
    COPY ${source:-obj/Docker/publish} .
    ENTRYPOINT ["dotnet", "HelloDockerTools.dll"]
    
  • <IsServiceFabricServiceProject> 元素添加到 ASP.NET Core 项目的 .csproj 文件:Adds an <IsServiceFabricServiceProject> element to the ASP.NET Core project's .csproj file:

    <IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
    
  • 向 ASP.NET Core 项目添加 PackageRoot 文件夹。Adds a PackageRoot folder to the ASP.NET Core project. 该文件夹包含服务清单和新服务的设置。The folder includes the service manifest and settings for the new service.

有关详细信息,请参阅将 Windows 容器中的 .NET 应用部署到 Azure Service FabricFor more information, see Deploy a .NET app in a Windows container to Azure Service Fabric.

调试Debug

在工具栏的调试下拉列表中选择“Docker”,然后开始调试应用。Select Docker from the debug drop-down in the toolbar, and start debugging the app. “输出”窗口的“Docker”视图显示发生的以下操作:The Docker view of the Output window shows the following actions taking place:

  • 已获取 microsoft/dotnet 运行时映像的 2.1-aspnetcore-runtime 标记(如果缓存中尚不存在)。The 2.1-aspnetcore-runtime tag of the microsoft/dotnet runtime image is acquired (if not already in the cache). 该映像可安装 ASP.NET Core 和.NET Core 运行时及其关联的库。The image installs the ASP.NET Core and .NET Core runtimes and associated libraries. 在生产环境中针对运行 ASP.NET Core 应用对其进行了优化。It's optimized for running ASP.NET Core apps in production.
  • ASPNETCORE_ENVIRONMENT 环境变量设置为容器内的 DevelopmentThe ASPNETCORE_ENVIRONMENT environment variable is set to Development within the container.
  • 公开了两个动态分配的端口:分别用于 HTTP 和 HTTPS。Two dynamically assigned ports are exposed: one for HTTP and one for HTTPS. 可以使用 docker ps 命令查询分配给本地主机的端口。The port assigned to localhost can be queried with the docker ps command.
  • 应用已复制到容器。The app is copied to the container.
  • 默认浏览器使用动态分配端口启动,带有附加到容器的调试程序。The default browser is launched with the debugger attached to the container using the dynamically assigned port.

最终得到的应用的 Docker 映像标记为“开发”。The resulting Docker image of the app is tagged as dev. 该映像基于 microsoft/dotnet 基础映像的 2.1-aspnetcore-runtime 标记。The image is based on the 2.1-aspnetcore-runtime tag of the microsoft/dotnet base image. 在“包管理器控制台”(PMC) 窗口中运行 docker images 命令。Run the docker images command in the Package Manager Console (PMC) window. 显示了计算机上的映像:The images on the machine are displayed:

REPOSITORY        TAG                     IMAGE ID      CREATED         SIZE
hellodockertools  dev                     d72ce0f1dfe7  30 seconds ago  255MB
microsoft/dotnet  2.1-aspnetcore-runtime  fcc3887985bb  6 days ago      255MB
  • 已获取 microsoft/aspnetcore 运行时映像(如果缓存中尚不存在)。The microsoft/aspnetcore runtime image is acquired (if not already in the cache).
  • ASPNETCORE_ENVIRONMENT 环境变量设置为容器内的 DevelopmentThe ASPNETCORE_ENVIRONMENT environment variable is set to Development within the container.
  • 端口 80 公开,并映射到 localhost 的动态分配端口。Port 80 is exposed and mapped to a dynamically assigned port for localhost. 该端口由 Docker 主机确定,并且可以使用 docker ps 进行查询。The port is determined by the Docker host and can be queried with the docker ps command.
  • 应用已复制到容器。The app is copied to the container.
  • 默认浏览器使用动态分配端口启动,带有附加到容器的调试程序。The default browser is launched with the debugger attached to the container using the dynamically assigned port.

最终得到的应用的 Docker 映像标记为“开发”。The resulting Docker image of the app is tagged as dev. 该映像基于 microsoft/aspnetcore 基础映像。The image is based on the microsoft/aspnetcore base image. 在“包管理器控制台”(PMC) 窗口中运行 docker images 命令。Run the docker images command in the Package Manager Console (PMC) window. 显示了计算机上的映像:The images on the machine are displayed:

REPOSITORY            TAG  IMAGE ID      CREATED        SIZE
hellodockertools      dev  5fafe5d1ad5b  4 minutes ago  347MB
microsoft/aspnetcore  2.0  c69d39472da9  13 days ago    347MB

备注

因为“调试”配置使用卷装载提供迭代体验,因此,开发映像中缺少应用内容。The dev image lacks the app contents, as Debug configurations use volume mounting to provide the iterative experience. 要推送映像,请使用“发布”配置。To push an image, use the Release configuration.

在 PMC 中运行 docker ps 命令。Run the docker ps command in PMC. 请注意,应用使用容器运行:Notice the app is running using the container:

CONTAINER ID        IMAGE                  COMMAND                   CREATED             STATUS              PORTS                   NAMES
baf9a678c88d        hellodockertools:dev   "C:\\remote_debugge..."   21 seconds ago      Up 19 seconds       0.0.0.0:37630->80/tcp   dockercompose4642749010770307127_hellodockertools_1

编辑并继续Edit and continue

对静态文件和 Razor 视图的更改会自动更新,无需执行编译步骤。Changes to static files and Razor views are automatically updated without the need for a compilation step. 进行更改,保存并在浏览器中刷新,以查看更新。Make the change, save, and refresh the browser to view the update.

必须在容器内编译和重启 Kestrel,才能修改代码文件。Code file modifications require compilation and a restart of Kestrel within the container. 更改后,按 CTRL+F5 执行过程,并在容器内启动应用。After making the change, use CTRL+F5 to perform the process and start the app within the container. 未重新生成或停止 Docker 容器。The Docker container isn't rebuilt or stopped. 在 PMC 中运行 docker ps 命令。Run the docker ps command in PMC. 请注意,截至 10 分钟前,原始容器仍在运行:Notice the original container is still running as of 10 minutes ago:

CONTAINER ID        IMAGE                  COMMAND                   CREATED             STATUS              PORTS                   NAMES
baf9a678c88d        hellodockertools:dev   "C:\\remote_debugge..."   10 minutes ago      Up 10 minutes       0.0.0.0:37630->80/tcp   dockercompose4642749010770307127_hellodockertools_1

发布 Docker 映像Publish Docker images

完成应用的开发和调试循环后,Visual Studio Tools for Docker 可帮助创建应用的生产映像。Once the develop and debug cycle of the app is completed, the Visual Studio Tools for Docker assist in creating the production image of the app. 将配置下拉列表更改为“发布”,然后生成应用。Change the configuration drop-down to Release and build the app. 该工具从 Docker Hub 中获取 compile/publish 映像(如果缓存中尚不存在)。The tooling acquires the compile/publish image from Docker Hub (if not already in the cache). 生成了具有“latest”标签的映像,可以将其推送到专用注册表或 Docker Hub。An image is produced with the latest tag, which can be pushed to the private registry or Docker Hub.

在 PMC 中运行 docker images 命令,查看映像列表。Run the docker images command in PMC to see the list of images. 显示了类似下面的输出:Output similar to the following is displayed:

REPOSITORY        TAG                     IMAGE ID      CREATED             SIZE
hellodockertools  latest                  e3984a64230c  About a minute ago  258MB
hellodockertools  dev                     d72ce0f1dfe7  4 minutes ago       255MB
microsoft/dotnet  2.1-sdk                 9e243db15f91  6 days ago          1.7GB
microsoft/dotnet  2.1-aspnetcore-runtime  fcc3887985bb  6 days ago          255MB
REPOSITORY                  TAG     IMAGE ID      CREATED         SIZE
hellodockertools            latest  cd28f0d4abbd  12 seconds ago  349MB
hellodockertools            dev     5fafe5d1ad5b  23 minutes ago  347MB
microsoft/aspnetcore-build  2.0     7fed40fbb647  13 days ago     2.02GB
microsoft/aspnetcore        2.0     c69d39472da9  13 days ago     347MB

自 .NET Core 2.1 起,前面的输出中列出的 microsoft/aspnetcore-buildmicrosoft/aspnetcore 映像替换为 microsoft/dotnet 映像。The microsoft/aspnetcore-build and microsoft/aspnetcore images listed in the preceding output are replaced with microsoft/dotnet images as of .NET Core 2.1. 有关详细信息,请参阅 Docker 存储库迁移公告For more information, see the Docker repositories migration announcement.

备注

docker images 命令返回存储库名称和标记标识为 <none> (上面未列出)的中间映像。The docker images command returns intermediary images with repository names and tags identified as <none> (not listed above). 这些未命名映像由多阶段生成 Dockerfile 生成。These unnamed images are produced by the multi-stage build Dockerfile. 它们可提高生成最终映像的效率 — 发生更改时,仅重新生成必要的层。They improve the efficiency of building the final image—only the necessary layers are rebuilt when changes occur. 不再需要中间映像时,请使用 docker rmi 命令将其删除。When the intermediary images are no longer needed, delete them using the docker rmi command.

可能希望生产或发布映像的大小比开发映像小。There may be an expectation for the production or release image to be smaller in size by comparison to the dev image. 由于卷映射,调试程序和应用从本地计算机运行,而不在容器内运行。Because of the volume mapping, the debugger and app were running from the local machine and not within the container. 最新映像已打包必要的应用代码,以在主机上运行应用。The latest image has packaged the necessary app code to run the app on a host machine. 因此,增量是应用代码的大小。Therefore, the delta is the size of the app code.

其他资源Additional resources