1. 环境准备与Docker安装
在Ubuntu系统上部署.NET API应用前,需要确保基础环境配置正确。我推荐使用Ubuntu 22.04 LTS版本,这是目前最稳定的长期支持版本,社区支持完善且与Docker兼容性最佳。
1.1 系统更新与依赖检查
首先通过以下命令更新系统包列表并升级现有软件包:
bash复制sudo apt update && sudo apt upgrade -y
安装Docker所需的依赖工具包:
bash复制sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
验证系统架构(Docker要求64位系统):
bash复制uname -m
# 应显示x86_64或aarch64
1.2 Docker引擎安装
添加Docker官方GPG密钥:
bash复制curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
设置稳定版仓库:
bash复制echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装Docker引擎:
bash复制sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io
验证安装是否成功:
bash复制sudo docker run hello-world
# 看到"Hello from Docker!"表示安装成功
1.3 非root用户权限配置(重要)
为避免每次使用docker命令都需要sudo,将当前用户加入docker组:
bash复制sudo usermod -aG docker $USER
newgrp docker # 立即生效
注意:此操作会使该用户获得等同于root的权限,仅限可信环境使用。生产环境建议保持sudo权限控制。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. .NET SDK环境配置
2.1 安装.NET 8 SDK
微软为Ubuntu提供了官方软件包源,首先注册微软签名密钥:
bash复制wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
安装.NET 8 SDK:
bash复制sudo apt update && sudo apt install -y dotnet-sdk-8.0
验证安装:
bash复制dotnet --list-sdks
# 应显示8.0.x版本
2.2 创建测试项目
新建一个Web API项目用于后续Docker化:
bash复制dotnet new webapi -n DockerizedApi
cd DockerizedApi
测试项目运行:
bash复制dotnet run
# 访问https://localhost:5001/swagger验证
3. Docker化.NET应用
3.1 编写Dockerfile
在项目根目录创建Dockerfile:
dockerfile复制# 使用官方.NET 8运行时镜像作为基础
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
# 使用SDK镜像构建应用
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["DockerizedApi.csproj", "."]
RUN dotnet restore "./DockerizedApi.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "DockerizedApi.csproj" -c Release -o /app/build
# 发布应用
FROM build AS publish
RUN dotnet publish "DockerizedApi.csproj" -c Release -o /app/publish
# 最终阶段
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DockerizedApi.dll"]
3.2 构建Docker镜像
执行构建命令(注意最后的点号):
bash复制docker build -t dockerizedapi .
查看已构建的镜像:
bash复制docker images
# 应看到REPOSITORY列为dockerizedapi的镜像
3.3 运行容器
启动容器并映射端口:
bash复制docker run -d -p 8080:80 --name myapi dockerizedapi
验证容器运行状态:
bash复制docker ps
# 应看到STATUS为Up的容器
测试API访问:
bash复制curl http://localhost:8080/weatherforecast
# 应返回JSON格式的天气数据
4. 生产环境优化配置
4.1 多阶段构建优化
上述Dockerfile已经使用了多阶段构建,这是.NET应用Docker化的最佳实践。它带来的优势:
- 最终镜像只包含运行时必要组件,体积更小
- 构建环境与运行环境隔离,安全性更高
- 可以利用Docker的构建缓存加速后续构建
4.2 健康检查配置
在Dockerfile的final阶段添加健康检查:
dockerfile复制HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/health || exit 1
然后修改Program.cs添加健康检查端点:
csharp复制app.MapHealthChecks("/health");
4.3 日志配置优化
修改Docker运行命令,将日志输出到控制台:
bash复制docker run -d -p 8080:80 --name myapi -e ASPNETCORE_ENVIRONMENT=Production -e ASPNETCORE_URLS=http://+:80 dockerizedapi
在appsettings.Production.json中添加日志配置:
json复制{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
},
"Console": {
"FormatterName": "simple",
"FormatterOptions": {
"SingleLine": true,
"TimestampFormat": "yyyy-MM-dd HH:mm:ss "
}
}
}
}
4.4 资源限制与重启策略
生产环境运行时应设置资源限制:
bash复制docker run -d \
--name myapi \
-p 8080:80 \
--memory=512m \
--cpus=1 \
--restart=unless-stopped \
dockerizedapi
参数说明:
--memory: 限制容器最大内存使用--cpus: 限制容器CPU使用量--restart: 设置容器异常退出时的重启策略
5. 常见问题排查
5.1 构建时NuGet包恢复失败
错误表现:
code复制error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json
解决方案:
- 检查网络连接是否正常
- 尝试在Dockerfile中添加DNS配置:
dockerfile复制RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf
5.2 容器启动后立即退出
可能原因:
- 应用崩溃导致容器退出
- 端口冲突
- 环境变量配置错误
排查步骤:
bash复制# 查看容器日志
docker logs myapi
# 以交互模式运行排查
docker run -it --entrypoint /bin/bash dockerizedapi
5.3 性能优化建议
- 使用
.dockerignore文件排除不必要的文件:
code复制**/.git
**/.vs
**/bin
**/obj
- 构建时使用BuildKit加速:
bash复制DOCKER_BUILDKIT=1 docker build -t dockerizedapi .
- 对于大型项目,考虑使用分层构建缓存:
dockerfile复制# 单独复制项目文件以利用缓存
COPY ["Directory.Build.props", "nuget.config", "./"]
COPY ["src/DockerizedApi/*.csproj", "src/DockerizedApi/"]
RUN dotnet restore "src/DockerizedApi/DockerizedApi.csproj"
6. 进阶部署方案
6.1 使用Docker Compose管理服务
创建docker-compose.yml文件:
yaml复制version: '3.8'
services:
api:
image: dockerizedapi
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:80"
environment:
- ASPNETCORE_ENVIRONMENT=Production
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 3s
retries: 3
启动服务:
bash复制docker compose up -d
6.2 添加反向代理(Nginx)
更新docker-compose.yml:
yaml复制services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- api
api:
# 原有配置不变
创建nginx.conf:
nginx复制events { worker_connections 1024; }
http {
upstream api {
server api:80;
}
server {
listen 80;
location / {
proxy_pass http://api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
6.3 数据库集成示例
添加PostgreSQL服务到docker-compose.yml:
yaml复制services:
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: example
POSTGRES_DB: apidb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres_data:
更新API服务配置:
yaml复制api:
environment:
- ConnectionStrings__DefaultConnection=Host=db;Database=apidb;Username=postgres;Password=example
depends_on:
db:
condition: service_healthy
