在 Docker 容器中创建第一个 ASP.NET Core 应用程序
在本教程中,我将从一开始就在Docker 容器中创建我的第一个 ASP.NET Core 应用程序。然后稍后我将直接从容器运行应用程序,以便可以通过添加容器的 url 在浏览器中访问它。

创建一个新的 ASP.NET Core 应用
首先打开 Visual Studio 并创建一个新的 Web 应用程序。
将您的应用程序命名为FirstDockerApp,并确保选中“将解决方案和项目放在同一目录中”的选项。
接下来,选择名为ASP.NET Core Web App的模板,这将创建一个基于 ASP.NET Core Razor Pages 的基本应用程序。
是时候在 Visual Studio 中运行应用程序了。你可以看到它是一个只有 2 个页面的基本应用程序——“主页”和“隐私”。
在 Windows、Mac、Linux 中安装 Docker
如果您使用的是 Windows 或 Mac 操作系统,那么您应该安装 Docker Desktop。Docker Desktop包括在 Docker 容器上创建和部署应用程序所需的一切。在 Windows 10 中安装期间,您可能还会收到安装 WSL 2 的提示。因此,请确保您还安装了 WSL 2。
在 Linux 中安装是通过 sudo 命令完成的。
请访问docker 链接页面下载 docker desktop 并了解如果您在 Linux 中运行哪些 sudo 命令。
安装 docker desktop 后,您将在任务栏中看到 docker desktop running 图标。我在下图中显示了这一点。
Windows 和 WSL 2
对于 Windows 用户,他们还必须安装 WSL 2,请参阅适用于 Windows 10 的 Linux 安装指南的 Windows 子系统。在此链接中,只需转到子标题“下载 Linux 内核更新包”并安装“适用于 x64 机器的 WSL2 Linux 内核更新包”。通常,在 Windows 中安装 docker Desktop期间,您会收到在系统中安装 WSL 2 的提示,因此如果您当时已经完成了此操作,那么您将不必在此处再次执行此操作。
我在笔记本电脑上使用 Windows 10 家庭版,docker 运行顺畅,没有任何问题。我已经从我的笔记本电脑创建了所有类型的 docker 项目,所以如果有人告诉你 docker 不能在 Windows 10 家庭中工作,请忽略。
接下来,右键单击工具栏中的 docker Desktop图标,然后转到设置菜单。在这里确保检查基于 WS 2 的引擎。见下图:
是时候运行 docker version 命令并检查 docker 是否正常工作了。因此,如果您在 Windows 中打开命令提示符,如果您在 Mac 中打开终端,或者如果您在 Linux 中打开命令行,然后在其上运行以下给出的命令并按 Enter:
docker version
它将向您显示安装在您的 PC 中的 docker 客户端和服务器版本。我在下面显示了我的命令提示符窗口的屏幕截图。
Docker 最初是为 Linux 操作系统构建的。Linux 本身是一个非常流行的操作系统,因此微软开发了 WSL 2,它是一个兼容层,用于在 Windows 10 和 Windows Server 2019 上本地运行 Linux 二进制可执行文件。
简而言之,WSL 2 帮助 Docker 在 Windows 中运行。
在 Windows 10 专业版和企业版上安装 Hyper-V
Hyper-V 是一种 Microsoft 技术,用于创建虚拟机,并在单个物理服务器上运行和管理多个操作系统。请注意,家庭版中没有 Hyper-V,因此如果您是家庭用户,则只需跳过此部分。
如果您使用的是 Windows 10 专业版或企业版,则可以启用 Hyper-V。请参阅此链接以了解如何操作。
好吧,那么 Docker 中的 Hyper-V 有什么用?
Dockers 提供 2 种类型的容器——Windows 和 Linux。使用 WSL 2,您可以在 docker 中创建 Linux 容器,而使用 Hyper-V,您可以在 docker 中创建 Windows 容器。因此,这意味着在 Windows 10 专业版和企业版中(前提是您启用了 Hyper-V),您可以在 docker 中创建 Linux 和 Windows 容器。
如果您使用的是 Window 10 Home(像我一样),那么您只能在 docker 中创建 Linux 容器。
在 docker Desktop中选择容器类型非常简单,右键单击任务栏中的 docker Desktop图标,然后选择“切换到 Linux 容器”或“切换到 Windows 容器”选项。同样,如果您使用的是 Window 10 Home(像我一样),那么您无需执行任何操作,因为 Linux 容器将自动被选中,而Switch to Windows 容器将被禁用/显示为灰色。
我强烈建议您在 docker 中使用 Linux 容器,因为这些容器也可以在 Windows 操作系统上运行。另一方面,Windows 容器不会在 Linux 操作系统中运行。我在本教程中的所有代码以及其他代码都是在 docker 的 Linux 容器上编写的。所以不要害怕尝试。
面向 ASP.NET Core 开发人员的重要 Docker 命令
现在让我们快速浏览一下我们将在本教程中使用的一些重要的 docker 命令。
用于管理容器的 Docker 命令
在命令提示符下运行docker ps,它将显示 docker 环境中所有正在运行的容器,以及它们的详细信息,例如容器 ID(随机 15 个字符长)、容器包含的镜像、命令告诉 docker 容器在镜像中执行了什么,状态,创建时间等等。我在下图中显示了docker ps命令的输出,您可以看到 3 个容器正在我的 docker 环境中运行。
由于您将第一次运行此命令,因此您不会看到任何容器名称。
容器可以处于运行状态或退出状态。因此,为了查看所有容器(正在运行 + 已退出),您需要将–all添加到 docker ps 命令。
docker ps --all
您还可以查看 docker Desktop中的所有容器。打开 docker Desktop并单击左侧部分Containers / Apps以查看所有容器。正在运行的容器将显示为绿色,而退出的容器将显示为灰色。
docker create – 创建一个容器
使用以下命令创建 Docker 容器:
docker create --name containername imagename
这里的“containername”是你想给容器起的名字,“imagename”是你本地 docker 环境中存在的镜像的名字。由于您没有要在容器内运行的镜像,因此现在运行此命令会给您一个错误,指出不存在具有给定名称的镜像。
稍后我将为我们的 ASP.NET Core 应用程序创建一个 docker 镜像。
docker start – 启动/运行容器
创建容器后,您需要启动它(即将其状态更改为运行),这可以通过以下命令完成:
docker start containername
docker stop – 停止正在运行的容器
您可以使用 stop 命令停止正在运行的容器:
docker stop containername
docker run命令是一个创建新容器并运行它的命令。下面的运行命令会创建一个具有镜像“myimage”的新容器并运行它。
docker run testc
发布“-p”命令
-p选项可以添加到“run”命令中,以将容器的端口与主机端口绑定。例如,以下命令将运行一个带有名为“myimage”的镜像的容器,以便将容器端口 8080 绑定到主机的端口 5000:
docker run -p 5000:8080 myimage
如果镜像“myimage”包含一个 ASP.NET Core 应用程序,那么您将能够通过在浏览器上调用 url – http://localhost:5000来访问它。
docker rm – 删除一个容器
可以通过运行docker rm命令删除容器。这将删除一个容器并释放其在硬盘上的存储空间。以下给定命令将删除名为 testc 的容器。
docker rm testc
另请注意,所有停止的包含都可以通过一个命令删除,该命令是:
docker system prune
您还可以从 docker Desktop运行、停止和删除docker contains。
docker logs – 容器的日志
您还可以查看容器的日志以进行调试。以下命令显示 id 为“ca0cdb8201ff”的容器的日志。
docker logs ca0cdb8201ff
用于管理镜像的 Docker 命令
Docker 镜像是在 Dockerfile 的帮助下构建的,Dockerfile 是一个基于文本的文件,其中包含如何组装镜像的说明。稍后我将讨论 Dockerfile。
Docker 有很多命令来管理镜像,让我们讨论一些重要的。
docker image ls – 列出镜像
以下命令将列出所有 docker 镜像。
docker image ls
下面给出的屏幕截图显示了我的 docker 环境中的镜像。
如果您现在在命令提示符下运行此命令,那么您可能不会看到任何镜像,因为您的docker 环境中没有任何镜像。我稍后将为我们刚刚创建的 ASP.NET Core 应用程序创建镜像。
docker image build
使用 build 命令从 Dockerfile 构建 docker 镜像。请参阅下面的构建命令。
docker build -t myimage -f Dockerfile .
这将从Dockerfile创建一个名为myimage的镜像。注意“。” 在最后签名,指定使用当前文件夹查找 Dockerfile。因此,要运行此命令,请确保首先转到 Dockerfile 的文件夹(通过使用“cd”命令)然后运行它。
“-t”用于命名和可选地以“名称:标签”格式的标签。我们也可以编写相同的构建命令:
docker build -t myimage:v1 -f Dockerfile .
这里 v1 是镜像的版本。您可以用任何类似的东西标记镜像。
docker build -t myimage:x -f Dockerfile .
docker build -t myimage:y -f Dockerfile .
docker build -t myimage:latest -f Dockerfile .
“-f”用于指定 Dockerfile。默认情况下,docker 将查找名称为“Dockerfile”的 Dockerfile。因此,您可以在没有 -f 的情况下简单地编写上述构建命令:
docker build -t myimage:v1 .
注意“。” 最后,它告诉 docker server 在当前位置查找 Dockerfile 文件。
如果您的 Dockerfile 有其他名称,那么您的命令将如下所示:
docker build -t myimage:x -f mydoc .
这里mydoc是我的 Dockerfile 的名称。
docker image pull
pull命令从注册表中拉取镜像或存储库。默认注册表是 docker hub。docker hub 中给出了一个 hello world 图像,检查它的链接。现在让我们将此镜像拉到我们的本地系统。
运行以下拉取命令从 docker hub 拉取 hello world 镜像。
docker pull hello-world
镜像将在几秒钟内被拉出,您将看到它的摘要和状态,请查看下面的屏幕截图。
接下来,运行docker image ls命令,它将在列表中显示该镜像名称。
docker 镜像推送
您还可以使用push命令将镜像推送到 docker hub 。下面的命令将“myimage”推送到 docker hub。
docker push myimage
注意 – 为此,您需要在 docker hub 网站上拥有一个帐户。它是完全免费的,所以你必须这样做。
删除 docker 镜像
该docker image rm命令将从本地环境的镜像。以下命令将从我们的系统中删除“hello-world”镜像。
docker image rm hello-world
删除所有未使用的镜像
您可以通过docker image prune命令从系统中删除所有未使用的镜像。
docker image prune
Dockerfile 和 Docker 镜像
Dockerfile是一个基于文本的文件(但没有扩展名)。它包含说明如何组装 docker 镜像的说明。在 Visual Studio 中,您可以通过在解决方案资源管理器中右键单击应用程序名称,然后选择Add ➤Docker Support轻松创建Dockerfile。
接下来,您将看到一个新窗口,要求您选择目标操作系统。
您可以选择其中任何一个,但请注意,对于 Windows 10 家庭版,它应该仅适用于 Linux。因此,由于我的操作系统是 Windows 10 家庭版,我将选择 Linux。此外,linux 操作系统要好得多,因为基于 linux 的 docker 镜像也可以在 windows 操作系统上运行。因此,单击 OK 按钮,您的 dockerfile 将在 Visual Studio 中创建并打开。
当 Visual Studio 创建 Dockerfile 时,它会在后台执行一些操作:
- 1. 检查 Docker Descktop是否已安装并运行。
- 2. 从 Microsoft Container Registry (mcr) 拉取 ASP.NET Core 和 Dot NET SDK 的镜像。我们的应用程序需要这些镜像才能在容器中运行。
- 3. 构建我们的应用镜像,这个镜像名称将是“firstdockerapp”。
- 4. 为镜像创建一个名为“FirstDockerApp”的容器。
你可以在 VS 的输出窗口中看到所有这些操作的日志。这个窗口可以从VS 的View > Output菜单打开。请参阅下面我的输出窗口的屏幕截图。
只需阅读它,您就会发现 docker build 和 docker run 命令。这意味着 VS 做了两件重要的事情:
1. 为我们的应用构建镜像,命名为“firstdockerapp”。您可以在 docker desktop 中看到此镜像。我在下图中显示了这一点:
2. 为这个镜像创建并运行了一个容器。此容器名称为“FirstDockerApp”。您可以验证此容器是否在 docker Desktop中运行。见下图:
ASP.NET Core Dockerfile 结构
创建的Dockerfile具有以下代码:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["FirstDockerApp.csproj", ""]
RUN dotnet restore "./FirstDockerApp.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "FirstDockerApp.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "FirstDockerApp.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FirstDockerApp.dll"]
Dockerfile 告诉如何为我们的 ASP.NET Core 应用程序构建镜像。Docker 镜像是按层或阶段构建的。我们首先选择一个包含所需元素的基础镜像,然后将自己的应用程序复制到它上面。可以有任意数量的阶段,完全由我们决定要创建多少个阶段。
由于这是一个小应用程序,因此我只需要 4 个阶段。
第一阶段
Dockerfile 的前 4 行创建了一个基本阶段。
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
在这里,我选择了将从 Microsoft Container Registry (mcr) 复制的基本镜像,如下所示。
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base
“AS base”用于命名这个阶段。该名称可以在随后的FROM指令中用于引用它。
接下来,看看WORKDIR指令是如何用于设置镜像内的当前工作目录的。在这个工作方向内,将执行 docker 命令。此目录设置为app。
WORKDIR /app
EXPOSE指令告诉容器在运行时监听指定的网络端口。这意味着可以从指定端口上的其他 Docker 容器内部访问该容器,但不能从 Docker 外部访问该容器。
这里暴露了端口 80 和 443。
EXPOSE 80
EXPOSE 443
协议也可以像 TCP 或 UDP 一样指定,默认为 TCP,不需要指定。如果要指定 UDP 协议,请这样做:
EXPOSE 80/udp
第二阶段
第二阶段包含以下代码:
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /src
COPY ["FirstDockerApp.csproj", ""]
RUN dotnet restore "./FirstDockerApp.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "FirstDockerApp.csproj" -c Release -o /app/build
现在我从 dot net sdk 镜像创建另一个阶段——mcr.microsoft.com/dotnet/sdk:5.0-buster-slim
并将其命名为“build”—— AS build
。
接下来,我将镜像内的工作目录设置为src。
WORKDIR /src
在此之后,我使用COPY指令将FirstDockerApp.csproj文件从应用程序复制到镜像的src目录内部。
COPY ["FirstDockerApp.csproj", ""]
因此,镜像上的FirstDockerApp.csproj位置将是src/FirstDockerApp.csproj。
在下一行中,我执行了dotnet restore以恢复应用程序的依赖项。这些依赖项在 csproj 文件中指定,因此提供了文件的位置。另请注意,NuGet 用于在工作目录中的镜像中恢复这些依赖项。
RUN dotnet restore "./FirstDockerApp.csproj"
请参阅 – ./FirstDockerApp.csproj,它有一个“.” 首先。它告诉查看当前工作目录,即“src”。所以 docker 可以得到 .csproj 文件的路径为src/FirstDockerApp.csproj。
接下来,使用COPY 。. 指令(有 2 个点)。
第一个点表示从应用程序的当前方向复制。第二个点表示复制到镜像的当前目录。
记住我已经将工作目录设置为“src”,所以这个命令,所有的文件都会被复制到容器的“src”目录中。
之后更改将工作目录设置为 src。
WORKDIR "/src/."
然后执行将构建我的应用程序的dotnet build 操作。
RUN dotnet build "FirstDockerApp.csproj" -c Release -o /app/build
-c Release -o /app/build指令说明了两件事:
- 1.将构建配置设置为发布。
- 2. 应用程序构建的二进制文件应放在镜像中的app/build文件夹中。
第三阶段
在这个阶段,我将我的应用程序及其依赖项发布到镜像中的文件夹以部署到容器。此文件夹在镜像中指定为app/publish。
这里我首先提到了“build”阶段(也就是第二个阶段),并给它起了个名字“publish”,然后进行了app的发布。这大大简化了镜像的创建。
FROM build AS publish
RUN dotnet publish "FirstDockerApp.csproj" -c Release -o /app/publish
第四阶段
第四阶段代码如下:
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FirstDockerApp.dll"]
在这个阶段,我从之前的阶段/层构建我们的最终镜像。
首先,我使用FROM 基本指令来指代“基本”阶段(即第一阶段) 。
FROM base AS final
然后将镜像内的工作目录设置为“app”。
WORKDIR /app
接下来是 COPY 指令。
COPY --from=publish /app/publish .
COPY 接受一个标志–from=可用于引用先前的构建阶段(此处为发布阶段),然后将 /app/publish 文件夹从该阶段复制到容器的当前工作目录。上一行设置的当前工作目录是“app”。
–from是非常有帮助的,因为我已经出版的应用程序(在另一阶段)和我的这个阶段(这将建立镜像)应从前一阶段包含编译后的文件。
最后,我使用ENTRYPOINT命令指定从docker镜像启动容器时应该运行哪个可执行文件。这里我要执行FirstDockerApp.dll文件。
ENTRYPOINT ["dotnet", "FirstDockerApp.dll"]
好吧,这就是 Dockerfile 的全部内容,我还没有准备好从 dockerfile 构建我的镜像。
.dockerignore
您还将看到一个名为.dockerignore的文件与Dockerfile一起自动创建。.dockerignore文件允许您为构建docker镜像时 Docker 应忽略的文件和文件夹指定模式。
您可以通过单击Dockerfile 前面的箭头符号来查看此文件。
打开 dockerignore 文件,找到以下模式。
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
每行给出了许多模式。
“**”表示匹配任何内容。因此**/.classpath意味着忽略扩展名为 .classpath 且位于应用程序中任何位置的文件。
它将匹配此文件的以下路径:
a.classpath
b.classpath
ab.classpath
a/some/xy.classpath
a/name.classpath
wwwroot/a/b/c/d/e.classpath
etc…
从 Visual Studio 运行 Dockerized 应用程序
正如我在上一节中已经说过的,当您创建 Dockerfile 时,Visual Studio 会自动为我们的应用程序创建一个镜像和容器。
您还将看到一个新的Docker Run选项被添加到 Visual Studio,以便您现在可以在 docker 容器而不是 IIS Express 中运行您的应用程序。检查下图。
现在运行您的应用程序,Visual Studio 将在 docker 容器中运行它。一旦应用程序在浏览器中打开,VS 就会打开一个容器窗口,显示应用程序正在运行的 docker 容器、docker 镜像、容器日志等。如果容器中出现问题,这些信息对于调试非常有用。请参阅下图,其中我显示了此容器窗口的屏幕截图。
我的应用程序在 URL – https://localhost:49165/处打开。在您的情况下,端口可能会有所不同。Visual Studio 所做的是它与 Container 的公开端口连接并从那里运行应用程序。
现在关闭 Visual Studio 并在浏览器上打开相同的 url – https://localhost:49165/。这次应用程序不会在浏览器中打开。
现在我将容器的一个端口绑定到主机(这是我们的浏览器),这将允许您通过在浏览器上调用它来运行应用程序,并且不需要 Visual Studio 来运行这个应用程序。
发布命令 (-p) 将 Container 的端口绑定到 Host
-p命令可以添加到“docker run”命令中,以将容器的端口与主机端口绑定。
让我们使用 Dockerfile 为我们的应用程序构建一个新镜像。在您的命令提示符下,转到 dockerfile 的目录并运行以下命令。
docker build -t fda -f Dockerfile .
这将创建一个名为fda的新镜像。我在下面给定的镜像中显示了这一点:
接下来运行以下命令创建一个容器,并将容器的 80 端口绑定到主机上的 5005 端口。
docker run -p 5005:80 fda
现在在浏览器中打开 url – http://localhost:5005/,您的应用程序将完美打开。我在下面的图片中展示了这一点。

docker日志
要获取容器的日志,请使用下面给出的 2 个docker logs 命令中的任何一个:
docker logs container-id
docker logs container-name
让我们看看运行fda镜像的容器日志。所以首先运行 docker ps 命令,它将显示所有正在运行的容器。
docker ps
复制运行 fda 镜像的 docker 容器的容器 ID(在我的例子中是 d302558bf826)。
然后为此容器 ID 运行 docker logs 命令。
docker logs d302558bf826
该命令将向您显示容器的日志。请参阅下图,它显示了容器运行“fda”镜像的日志。

通过打开 docker desktop 并检查容器/应用程序部分,可以看到容器名称。然后复制任何容器名称并运行docker logs containername命令来检查它的日志。
这些日志对于检查容器是否正常工作非常有帮助。它们可以帮助您调试可能影响容器的任何问题。
Docker 容器中的 Bash 会话 – “docker exec -it bash”
假设您想在现有容器中运行任意命令,例如ls命令,它将显示容器内的所有文件和目录。在这种情况下,您使用docker exec命令在容器内启动 bash 会话。
我的容器 id 是“d302558bf826”(运行 docker ps以获取容器 id)。要启动 bash 会话,命令将是:
docker exec -it d302558bf826 bash
然后你会看到一个文本——“ root@d302558bf826 :/app#”。因此,运行ls命令,它将显示 docker 容器内的所有文件和目录。
您还可以通过cd ..向上移动一个目录,并通过cd app命令移动到名为app的目录中。
检查下图,我在其中展示了这个 bash 会话。
其他命令命令是:
clear – 清除屏幕。
exit – 退出 bash 会话。
您可以通过单击下面给出的下载链接下载源代码。
结论
在本 Docker 教程中,您学习了如何在 Docker 中创建和运行ASP.NET Core 应用程序。我介绍了 Dockerfile 并从中为应用程序创建了 Docker 镜像。后来我从 Docker 容器中托管了该应用程序,并在没有使用 Visual Studio 的情况下从那里运行它。我希望你喜欢这个教程。
常见问题FAQ
- 程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
- 请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!