-
C#关于Docker容器化——ASP.NET Core应用打包
第六部分:容器化与微服务开发
-
Docker容器化——ASP.NET Core应用打包
实例介绍
之前部署ASP.NET Core应用时,需要在服务器上安装.NET SDK、配置环境变量、设置IIS,每次部署都要重复这些步骤,耗时耗力,而且容易出现“在我机器上能运行,在服务器上不能运行”的问题。换成Docker容器化后,将应用和依赖vb.net教程C#教程python教程SQL教程access 2010教程
打包成镜像,部署时只需运行容器,几分钟就能完成部署,而且环境一致,不会出现兼容性问题,部署效率提升90%。这节就带你从零实现ASP.NET Core应用的Docker容器化,包括Dockerfile编写、镜像构建、容器运行、多阶段构建、Docker Compose编排,覆盖容器化的核心场景。
需求分析
Docker容器化要解决“环境一致性、快速部署、资源隔离、弹性扩展、多环境部署”的问题,具体需求如下:
1.环境一致性:应用和依赖打包成镜像,运行在任何支持Docker的环境中,环境一致;
2.快速部署:镜像可快速复制、部署,几分钟就能完成应用部署;
3.资源隔离:每个容器独立运行,资源隔离,互不影响;
4.弹性扩展:根据请求数量快速扩展容器实例,支持高并发场景;
5.多环境部署:支持开发、测试、生产环境,通过环境变量配置;
6.镜像仓库:将镜像推送到Docker Hub、Azure Container Registry等镜像仓库,方便共享和部署;
7.多阶段构建:减小镜像体积,只包含运行时依赖,不包含开发工具;
8.Docker Compose:编排多个容器(如ASP.NET Core应用、SQL Server、Redis),一键启动整个应用栈;
9.监控与日志:集成Docker监控工具(如Docker Stats、Prometheus),查看容器资源使用情况、日志;
10.安全:最小权限原则,使用非root用户运行容器,限制容器资源访问;
代码实现
前置条件:Docker Desktop(Windows/macOS)或Docker Engine(Linux);.NET 8 SDK;ASP.NET Core应用(如之前创建的MauiTodoList后端API);
场景1:Dockerfile编写——ASP.NET Core应用打包
编写Dockerfile,将ASP.NET Core应用打包成Docker镜像。
步骤1:创建ASP.NET Core应用
如果没有现成的ASP.NET Core应用,可使用以下命令创建:
bash
dotnet new webapi -n AspNetCoreDockerDemo
cd AspNetCoreDockerDemo
dotnet run
访问http://localhost:5000/weatherforecast,确认应用正常运行;
步骤2:编写Dockerfile
在项目根目录创建Dockerfile文件,内容如下:
dockerfile
# 阶段1:构建应用(使用SDK镜像,包含开发工具)
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# 复制项目文件
COPY ["AspNetCoreDockerDemo.csproj", "."]
# 还原NuGet包
RUN dotnet restore "./AspNetCoreDockerDemo.csproj"
# 复制所有源代码
COPY . .
# 构建应用,输出到publish目录
RUN dotnet build "./AspNetCoreDockerDemo.csproj" -c Release -o /app/build
# 发布应用
RUN dotnet publish "./AspNetCoreDockerDemo.csproj" -c Release -o /app/publish /p:UseAppHost=false
# 阶段2:运行应用(使用ASP.NET Core运行时镜像,只包含运行时依赖)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
# 复制发布后的应用文件
COPY --from=build /app/publish .
# 暴露应用端口(ASP.NET Core默认监听8080端口)
EXPOSE 8080
# 设置环境变量,指定应用运行端口
ENV ASPNETCORE_URLS=http://+:8080
# 使用非root用户运行容器(安全最佳实践)
RUN useradd -m appuser
USER appuser
# 启动应用
ENTRYPOINT ["dotnet", "AspNetCoreDockerDemo.dll"]
场景2:镜像构建与容器运行
构建Docker镜像,运行容器,测试应用是否正常运行。
步骤1:构建Docker镜像
在项目根目录运行以下命令,构建Docker镜像:
bash
docker build -t aspnetcoredockerdemo:v1 .
-t aspnetcoredockerdemo:v1:为镜像打标签,aspnetcoredockerdemo是镜像名称,v1是版本号;
.:指定Dockerfile所在目录(当前目录);
步骤2:查看Docker镜像
bash
docker images
会看到刚构建的aspnetcoredockerdemo:v1镜像;
步骤3:运行Docker容器
bash
docker run -d -p 5000:8080 --name aspnetcore-app aspnetcoredockerdemo:v1
-d:后台运行容器;
-p 5000:8080:端口映射,将主机的5000端口映射到容器的8080端口;
--name aspnetcore-app:为容器指定名称;
aspnetcoredockerdemo:v1:使用的镜像名称和版本号;
步骤4:测试应用
访问http://localhost:5000/weatherforecast,确认应用正常运行;
步骤5:查看容器日志
bash
docker logs aspnetcore-app
查看容器的运行日志,确认应用启动情况;
步骤6:停止和删除容器
bash
docker stop aspnetcore-app
docker rm aspnetcore-app
场景3:多阶段构建——减小镜像体积
使用多阶段构建,减小Docker镜像体积,只包含运行时依赖,不包含开发工具。
步骤1:多阶段构建Dockerfile说明
阶段1(build):使用SDK镜像,包含开发工具,用于构建和发布应用;
阶段2(base):使用ASP.NET Core运行时镜像,只包含运行时依赖,用于运行应用;
COPY --from=build /app/publish .:将阶段1构建的应用文件复制到阶段2的镜像中;
步骤2:对比镜像体积
单阶段构建(使用SDK镜像运行应用):镜像体积约1GB;
多阶段构建(使用运行时镜像运行应用):镜像体积约200MB,减小80%;
场景4:Docker Compose——多容器编排
使用Docker Compose编排多个容器(如ASP.NET Core应用、SQL Server、Redis),一键启动整个应用栈。
步骤1:创建Docker Compose文件
在项目根目录创建docker-compose.yml文件,内容如下:
yaml
version: '3.8'
services:
# ASP.NET Core应用服务
aspnetcore-app:
build: .
ports:
- "5000:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ConnectionStrings__DefaultConnection=Server=sqlserver;Database=AspNetCoreDockerDemoDb;User Id=sa;Password=YourStrong@Passw0rd;TrustServerCertificate=True;
depends_on:
- sqlserver
- redis
networks:
- app-network
# SQL Server数据库服务
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=YourStrong@Passw0rd
ports:
- "1433:1433"
volumes:
- sqlserver-data:/var/opt/mssql
networks:
- app-network
# Redis缓存服务
redis:
image: redis:latest
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- app-network
# 数据卷,用于持久化SQL Server和Redis数据
volumes:
sqlserver-data:
redis-data:
# 自定义网络,让容器之间可以通过服务名通信
networks:
app-network:
driver: bridge
步骤2:启动应用栈
在项目根目录运行以下命令,启动所有容器:
bash
docker-compose up -d
-d:后台运行所有容器;
步骤3:查看容器状态
bash
docker-compose ps
查看所有容器的运行状态;
步骤4:测试应用
访问http://localhost:5000/weatherforecast,确认应用正常运行;
应用会连接SQL Server数据库和Redis缓存;
步骤5:停止应用栈
bash
docker-compose down
停止并删除所有容器,保留数据卷;
如果要删除数据卷,使用docker-compose down -v;
场景5:镜像推送——Docker Hub或Azure Container Registry
将构建的Docker镜像推送到镜像仓库,方便共享和部署。
步骤1:推送镜像到Docker Hub
登录Docker Hub:docker login;
为镜像打标签(格式:Docker Hub用户名/镜像名称:版本号):
bash
docker tag aspnetcoredockerdemo:v1 yourdockerhubusername/aspnetcoredockerdemo:v1
推送镜像到Docker Hub:
bash
docker push yourdockerhubusername/aspnetcoredockerdemo:v1
步骤2:推送镜像到Azure Container Registry
1.创建Azure容器注册表(ACR):在Azure门户中创建容器注册表,获取登录服务器名称(如myacr2026.azurecr.io);
2.登录ACR:docker login myacr2026.azurecr.io;
3.为镜像打标签:
bash
docker tag aspnetcoredockerdemo:v1 myacr2026.azurecr.io/aspnetcoredockerdemo:v1
6.推送镜像到ACR:
bash
docker push myacr2026.azurecr.io/aspnetcoredockerdemo:v1
逐行讲解
场景1:Dockerfile核心代码
1.FROM指令:
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build:使用.NET 8 SDK镜像作为构建阶段的基础镜像,命名为build;
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base:使用.NET 8 ASP.NET Core运行时镜像作为运行阶段的基础镜像,命名为base;
2.WORKDIR指令:
WORKDIR /src:设置工作目录为/src,后续命令都在该目录下执行;
3.COPY指令:
COPY ["AspNetCoreDockerDemo.csproj", "."]:复制项目文件到工作目录,先复制项目文件再还原NuGet包,可利用Docker缓存(如果项目文件未修改,直接使用缓存的NuGet包);
COPY . .:复制所有源代码到工作目录;
4.RUN指令:
RUN dotnet restore "./AspNetCoreDockerDemo.csproj":还原NuGet包;
RUN dotnet build "./AspNetCoreDockerDemo.csproj" -c Release -o /app/build:构建应用,输出到/app/build目录;
RUN dotnet publish "./AspNetCoreDockerDemo.csproj" -c Release -o /app/publish /p:UseAppHost=false:发布应用,输出到/app/publish目录,/p:UseAppHost=false表示不生成可执行文件,使用dotnet命令运行应用;
5.EXPOSE指令:
EXPOSE 8080:声明容器暴露的端口,方便外部访问;
6.ENV指令:
ENV ASPNETCORE_URLS=http://+:8080:设置环境变量,指定应用运行在8080端口;
7.USER指令:
RUN useradd -m appuser:创建非root用户appuser;
USER appuser:使用appuser用户运行容器,遵循最小权限原则,提高安全性;
8.ENTRYPOINT指令:
oENTRYPOINT ["dotnet", "AspNetCoreDockerDemo.dll"]:容器启动时执行的命令,运行ASP.NET Core应用;
场景4:Docker Compose核心代码
1.services:定义多个服务(如ASP.NET Core应用、SQL Server、Redis);
2.build:指定Dockerfile所在目录,自动构建镜像;
3.ports:端口映射,将主机端口映射到容器端口;
4.environment:设置环境变量,如数据库连接字符串、SQL Server密码;
5.depends_on:指定服务依赖,如ASP.NET Core应用依赖SQL Server和Redis,确保SQL Server和Redis先启动;
6.volumes:数据卷,用于持久化SQL Server和Redis数据,容器删除后数据不会丢失;
7.networks:自定义网络,让容器之间可以通过服务名通信(如ASP.NET Core应用可以通过sqlserver访问SQL Server数据库);
基础知识拓展
-
Docker核心概念
镜像(Image):只读的模板,包含应用和依赖,用于创建容器;
容器(Container):镜像的运行实例,独立运行,资源隔离;
仓库(Repository):存储镜像的地方,如Docker Hub、Azure Container Registry;
Dockerfile:文本文件,包含构建镜像的指令;
Docker Compose:用于编排多个容器的工具,通过YAML文件定义服务; -
Docker镜像分层存储
Docker镜像采用分层存储,每个指令(如FROM、COPY、RUN)创建一个新层;
层是只读的,多个镜像可以共享相同的层,减小镜像体积;
容器是在镜像的基础上添加一个可写层,容器的修改都在可写层中,不影响镜像; -
Docker网络模式
桥接模式(bridge):默认网络模式,容器之间可以通过IP地址通信,需要端口映射才能被外部访问;
主机模式(host):容器直接使用主机的网络,不需要端口映射,性能高,但安全性低;
无网络模式(none):容器没有网络,只能通过文件共享与主机通信;
自定义网络:用户创建的网络,容器之间可以通过服务名通信,方便编排多个容器; -
Docker数据持久化
数据卷(Volume):Docker管理的存储卷,数据存储在主机的指定目录,容器删除后数据不会丢失;
绑定挂载(Bind Mount):将主机的目录或文件挂载到容器中,数据存储在主机的指定位置;
tmpfs挂载:数据存储在主机的内存中,容器删除后数据丢失,适合存储临时数据; -
Docker安全最佳实践
1.最小权限原则:使用非root用户运行容器,限制容器资源访问;
2.使用官方镜像:使用Docker Hub或Azure Container Registry的官方镜像,避免使用未知来源的镜像;
3.定期更新镜像:定期更新镜像,修复安全漏洞;
4.限制容器资源:使用--memory、--cpus参数限制容器的内存和CPU使用;
5.禁用不必要的功能:禁用容器的特权模式,避免容器获取主机的root权限;
总结
Docker容器化的核心是环境一致性、快速部署、资源隔离、弹性扩展,让你轻松打包、部署、运行ASP.NET Core应用,无需担心环境配置、兼容性问题。关键要点:
1.Dockerfile:编写构建镜像的指令,多阶段构建减小镜像体积;
2.镜像构建:使用docker build命令构建镜像,打标签方便管理;
3.容器运行:使用docker run命令运行容器,端口映射让外部访问;
4.Docker Compose:编排多个容器,一键启动整个应用栈;
5.镜像仓库:将镜像推送到Docker Hub或Azure Container Registry,方便共享和部署;
6.安全:最小权限原则,使用非root用户运行容器,限制容器资源访问;
比如这个Docker容器化ASP.NET Core应用,部署时只需运行容器,几分钟就能完成部署,而且环境一致,不会出现“在我机器上能运行,在服务器上不能运行”的问题,部署效率提升90%。掌握Docker容器化,你就能轻松构建云原生应用,实现应用的快速部署、弹性扩展!
本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49485.html










