Skip to content

ASP.NET项目Docker构建指南 ​

目标:在 30 分钟内完成任意 ASP.NET Web 项目(含前端与数据库)的标准化 Docker 部署。 核心策略:流程固定化、配置模板化、快速复用。


📋 部署检查清单 ​

在开始部署前,请确保环境满足以下要求:

  • [ ] 环境:Docker Engine ≥ 24.x + Docker Compose v2。
  • [ ] 源码:包含后端代码及前端构建产物(dist 目录)。
  • [ ] 数据库:明确使用容器内 SQL Server 还是外部数据库。
  • [ ] 网络:提前规划宿主机端口,避免与现有服务冲突。
  • [ ] 域名:如需外网访问,请提前完成域名解析及 Hub 反代规划。

1. 标准目录结构 ​

推荐使用以下结构组织代码与部署配置,实现“配置即代码”与数据隔离。

text
project-root/
├── server/                    # 后端 API 源码
│   └── API/
│       ├── Dockerfile         # ✅ 后端镜像构建定义
│       └── appsettings.json   # 生产环境配置文件
├── admin/                     # 前端源码 (Vue/React 等)
│   └── dist/                  # ✅ 前端编译产物 (构建后生成)
├── deploy/                    # ✅ 容器化部署配置 (核心)
│   ├── nginx/
│   │   ├── nginx.conf         # Nginx 全局优化配置
│   │   └── conf.d/
│   │       └── app.conf       # 站点反代与动静分离配置
│   ├── logs/nginx/            # 挂载运行日志
│   └── data/mssql/            # 挂载 SQL Server 持久化数据
└── docker-compose.yml         # ✅ 多服务编排定义

快速初始化命令:

bash
mkdir -p deploy/nginx/conf.d deploy/logs/nginx deploy/data/mssql

2. 后端 Dockerfile (多阶段构建) ​

如果你使用 Visual Studio / Rider 等 IDE,也可以先生成项目默认的 Docker 支持,再按本文模板做标准化收敛。最终应以仓库中的 Dockerfile 与 docker-compose.yml 为准,而不是依赖本地 IDE 向导配置。

采用多阶段构建,确保最终镜像仅包含运行所需的 Runtime,体积最小化。

dockerfile
# ========================================
# ASP.NET Web API 镜像构建(多阶段)
# 适用于:.NET 6/7/8 项目
# ========================================

# --- 阶段 1: 构建 (Build) ---
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
# 执行还原与发布 (替换为实际项目路径)
RUN dotnet restore "Server/API/API.csproj" \
    && dotnet publish "Server/API/API.csproj" -c Release -o /app/publish --no-restore

# --- 阶段 2: 运行 (Runtime) ---
FROM mcr.microsoft.com/dotnet/aspnet:8.0

# 优化:切换国内镜像源并安装字体 (解决 PDF/图片生成中的乱码)
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g;s|security.debian.org|mirrors.aliyun.com|g' \
       /etc/apt/sources.list.d/debian.sources \
    && apt-get update \
    && apt-get install -y --no-install-recommends fonts-dejavu-core \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=build /app/publish .

# 生产环境环境变量
ENV ASPNETCORE_URLS=http://0.0.0.0:5000 \
    ASPNETCORE_ENVIRONMENT=Production \
    TZ=Asia/Shanghai

EXPOSE 5000
# 替换为实际的输出 DLL 名称
ENTRYPOINT ["dotnet", "API.dll"]

修改要点:

  • 替换 Server/API/API.csproj 为实际项目路径。
  • 替换 API.dll 为实际输出文件。
  • 根据项目需求调整 SDK/Runtime 版本。

2.1 .dockerignore 模板 ​

为了避免把 .git、bin/、obj/、前端依赖等无关文件打进构建上下文,建议同时维护一份 .dockerignore:

text
**/.dockerignore
**/.git
**/.gitignore
**/.vs
**/.vscode
**/bin
**/obj
**/node_modules
**/docker-compose*
**/Dockerfile*
README.md

经验建议:Dockerfile 管的是“怎么构建镜像”,.dockerignore 管的是“哪些文件根本不要进构建上下文”。这两个文件应成对维护。


3. Nginx 配置模板 ​

3.1 全局配置 (deploy/nginx/nginx.conf) ​

包含 Gzip 压缩、字符集优化及大文件上传限制。

nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 全局 UTF-8 (解决中文乱码)
    charset utf-8;
    charset_types text/plain text/css text/xml application/json;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;

    sendfile on;
    keepalive_timeout 65;
    client_max_body_size 50m; # 调整上传限制

    # Gzip 压缩优化
    gzip on;
    gzip_types text/plain application/json text/css application/javascript;

    include /etc/nginx/conf.d/*.conf;
}

3.2 站点配置 (deploy/nginx/conf.d/app.conf) ​

nginx
server {
    listen 80;
    server_name _;

    # 前端静态资源托管 (Vue/React SPA)
    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # 后端 API 反向代理
    location /api/ {
        # 注意:使用 docker-compose 中定义的后端服务名
        proxy_pass http://app-api:5000/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 60s;
    }
}

4. Docker Compose 编排 ​

yaml
version: '3.8'

networks:
  app-net:
    driver: bridge

services:
  # 1. 数据库:SQL Server 2019
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2019-latest
    container_name: app-sqlserver
    environment:
      - ACCEPT_EULA=Y
      - MSSQL_SA_PASSWORD=YourStrong!Pass123 # 请修改为强密码
      - MSSQL_PID=Developer
      - TZ=Asia/Shanghai
    volumes:
      - ./deploy/data/mssql:/var/opt/mssql
    ports:
      - '14333:1433' # 宿主机映射端口
    networks:
      - app-net
    healthcheck:
      test: [CMD-SHELL, "bash -c 'echo > /dev/tcp/127.0.0.1/1433' || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    restart: unless-stopped

  # 2. 后端:ASP.NET Core API
  app-api:
    build:
      context: .
      dockerfile: Server/API/Dockerfile
    container_name: app-api
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - TZ=Asia/Shanghai
    depends_on:
      sqlserver:
        condition: service_healthy # 确保数据库就绪后再启动 API
    networks:
      - app-net
    restart: unless-stopped

  # 3. 前端 + Nginx 反代
  app-nginx:
    image: nginx:1.25-alpine
    container_name: app-nginx
    ports:
      - '18080:80' # 内网暴露端口,由 Hub 接入
    volumes:
      - ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./deploy/nginx/conf.d:/etc/nginx/conf.d:ro
      - ./admin/dist:/usr/share/nginx/html:ro # 挂载前端产物
      - ./deploy/logs/nginx:/var/log/nginx
    depends_on:
      - app-api
    networks:
      - app-net
    restart: unless-stopped

5. 快速部署流程 (30 分钟) ​

5.1 准备与构建 (5 分钟) ​

  1. 代码准备:克隆项目并进入根目录。
  2. 前端编译:cd admin && npm run build。
  3. 创建目录:执行上文的 mkdir 命令。

5.2 配置调整 (10 分钟) ​

  1. 修改 Dockerfile:确认项目路径与 DLL 名称。
  2. 修改 docker-compose.yml:调整服务名、端口及数据库密码。
  3. 配置数据库:修改 appsettings.json 中的连接字符串。
    • 容器内连接:Server=app-sqlserver,1433;User Id=sa;Password=...

5.3 启动与验证 (15 分钟) ​

  1. 启动:docker compose up -d --build。
  2. 验证 API:curl http://127.0.0.1:18080/api/health。
  3. 接入 Hub:在全局网关 Nginx 中添加对应的 proxy_pass http://127.0.0.1:18080/ 配置。

6. 常用运维命令 ​

bash
# 1. 启停与状态
docker compose ps              # 查看运行状态
docker compose logs -f app-api # 实时查看后端日志
docker compose restart        # 重启所有服务

# 2. 更新发布
docker compose build app-api   # 仅重新构建后端镜像
docker compose up -d app-api   # 平滑更新单个服务

# 3. 容器内调试
docker exec -it app-api bash   # 进入 API 容器执行命令
docker exec -it app-sqlserver /opt/mssql-tools/bin/sqlcmd \
  -S localhost -U sa -P 'YourStrong!Pass123' # 连接数据库

7. 常见故障排除 ​

问题可能原因解决方案
502 Bad GatewayAPI 容器未启动或端口不通检查 docker compose ps 及后端日志
前端 404/空白Nginx root 挂载路径错误确认 admin/dist 路径与 volumes 一致
数据库连接超时网络隔离或防火墙拦截确保服务在同一 networks 下,使用服务名访问
中文乱码Nginx 字符集配置缺失确保 nginx.conf 中包含 charset utf-8
上传文件失败Nginx 大小限制调大 client_max_body_size 参数

方舟 · Ark