文章元信息
- 作者:刚子
- 系列名称:.NET 8 现代Web开发实战指南
- 原文链接:https://www.codeobservatory.cn/post/dotnet-8-web-development-part8-docker-container-deployment
- 关键词:Docker, 容器化部署, Dockerfile, .NET 8 部署, CI/CD, Linux 容器, 微服务基础
- 摘要:本文作为系列教程的终章,将带你跨越“在我的机器上能跑”的鸿沟。通过实战 Docker 容器化技术,手把手教你编写高效的 Dockerfile,构建镜像并启动容器,彻底解决环境配置不一致的难题,实现一键式交付部署。
一、前言:彻底终结“在我的机器上能跑”
作为一名架构师,我听过最多的一句话就是:“在我本地明明是好的,怎么一到服务器就挂了?”
这通常是因为开发环境和生产环境的差异(比如 .NET 版本不一致、缺组件、系统不同)。Docker 的出现彻底解决了这个问题。
Docker 就像一个“集装箱”。你把你的应用程序、运行环境、配置文件统统打包进这个箱子里。无论你把这个箱子搬到 Windows 服务器、Linux 服务器还是云平台上,里面的东西都不会变,运行效果也完全一致。
二、核心概念:镜像与容器
很多新手搞不清这两个词,刚子用一个通俗的比喻:
- 镜像 (Image):是模具(比如做月饼的模子)。它是静态的,只读的,定义了软件长什么样。
- 容器 (Container):是月饼。通过模具(镜像)倒出来的实物。它是动态的,可读写的,是真正跑起来的进程。
我们部署的过程,就是:编写 Dockerfile -> 构建镜像 -> 运行容器。
三、实战第一步:安装 Docker
如果你的电脑还没装 Docker,请根据你的操作系统下载安装:
- Windows: 下载 Docker Desktop for Windows。
- macOS: 下载 Docker Desktop for Mac。
安装完成后,打开终端输入 docker --version,如果显示版本号,说明安装成功。
【配图建议 1】 位置:Docker 安装验证之后。 内容:终端截图,显示
docker --version的输出结果(例如Docker version 24.0.6...)。 Alt文本:终端验证 Docker 安装成功的截图。
四、编写 Dockerfile:给集装箱写说明书
Dockerfile 是一个文本文件,里面写满了指令,告诉 Docker 怎么把你的代码打包成镜像。
在项目根目录(也就是 .csproj 所在的目录)新建一个文件,命名为 Dockerfile(注意没有后缀名)。
4.1 标准 .NET 8 Dockerfile 模板
写入以下内容(刚子为你精心优化的多阶段构建模板):
# === 第一阶段:构建阶段 ===
# 使用微软官方的 .NET 8 SDK 镜像作为基础环境
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# 1. 复制项目文件并还原依赖
# 利用 Docker 缓存机制:如果 csproj 没变,下次构建直接跳过还原步骤,大幅提速
COPY ["MyTodoApp.csproj", "./"]
RUN dotnet restore "MyTodoApp.csproj"
# 2. 复制所有源代码并编译发布
COPY . .
RUN dotnet publish "MyTodoApp.csproj" -c Release -o /app/publish
# === 第二阶段:运行阶段 ===
# 使用更轻量的 Runtime 镜像(不含 SDK,体积小很多,更安全)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
# 3. 暴露端口(告知 Docker 这个容器会使用 80 端口)
EXPOSE 80
# 4. 从构建阶段把编译好的文件拷贝过来
COPY --from=build /app/publish .
# 5. 设置启动命令
ENTRYPOINT ["dotnet", "MyTodoApp.dll"]
刚子敲黑板:
注意看,这里用了两个 FROM。这就是多阶段构建。
- 第一阶段用 SDK(很大,约 1GB)来编译代码。
- 第二阶段只用 Runtime(很小,约 200MB)来运行代码。 最终生成的镜像只包含第二阶段的内容,体积大大减小,这在生产环境中非常重要!
五、构建镜像:打造你的“模具”
打开终端,确保路径在项目根目录,执行以下命令:
docker build -t my-todo-app:v1 .
命令解析:
docker build:构建命令。-t my-todo-app:v1:给镜像打标签,名字叫my-todo-app,版本号v1。.:最后这个点不能少,表示使用当前目录作为上下文。
第一次构建会比较慢,因为要下载基础镜像。稍等片刻,看到 Successfully built xxx 就成功了。
【配图建议 2】 位置:构建命令执行之后。 内容:终端截图,展示 Docker 构建的详细日志步骤,最后显示
Successfully tagged my-todo-app:v1。 Alt文本:Docker 成功构建 .NET 8 应用镜像的终端日志截图。
六、运行容器:让应用跑起来
镜像有了,现在我们要把它跑起来。
执行以下命令:
docker run -d -p 8080:80 --name my-running-app my-todo-app:v1
命令解析:
docker run:运行容器。-d:后台运行。-p 8080:80:端口映射。把宿主机(你的电脑)的 8080 端口映射到容器内部的 80 端口。--name my-running-app:给容器起个名字,方便管理。my-todo-app:v1:使用的镜像名。
现在,打开浏览器访问 http://localhost:8080/swagger。
恭喜!你的应用已经在 Docker 容器里运行了!
【配图建议 3】 位置:运行命令之后。 内容:浏览器截图,访问 localhost:8080/swagger 正常显示接口列表。 Alt文本:应用在 Docker 容器内成功运行并访问 Swagger 界面的截图。
七、总结与预告
在这篇文章中,我们掌握了最现代的 Docker 容器化部署。它像集装箱一样,屏蔽了底层环境的差异,是云原生时代的首选。
但现实世界是复杂的。很多企业依然在大量使用 Windows Server,或者追求极致性能的 Linux 服务器。Docker 虽好,但并非唯一解。
接下来的两篇补充指南,刚子将带你解锁另外两种硬核的交付方式:
- Windows IIS 部署:适合传统企业环境,图形化操作,简单直观。
- Linux Nginx 部署:适合互联网应用,性能极致,是架构师的进阶必修课。
交付之路,我们继续!