以下是 完整、清晰、可执行 的 .NET 8 API + Angular 16 + MySQL 使用 Docker Compose 发布的详细步骤,基于你提供的项目结构和配置要求:
✅ 最终目标
| 服务 | 宿主机端口 | 容器内端口 | 说明 |
|---|---|---|---|
| .NET 8 API(Backend) | 5000 |
80(容器内) |
后端服务 |
| Angular 前端(Frontend) | 6000 |
80(Nginx 容器) |
静态站点托管 |
| MySQL 数据库 | 3306 |
3306 |
数据库服务 |
- 数据库密码:
Wz@273509239 - 前后端通过 Nginx 反向代理通信,避免 CORS
- 一键部署:
docker-compose up
📁 项目目录结构(补充后)
bash
MES/
├── docker-compose.yml # 主编排文件
├── .env # 环境变量(含数据库密码)
│
├── MES.Backend/
│ ├── MES.API/
│ │ ├── Program.cs
│ │ ├── appsettings.json
│ │ ├── appsettings.Production.json
│ │ ├── Dockerfile # 新增:.NET 构建镜像
│ │ └── ...
│ ├── MES.Application/
│ ├── MES.Core/
│ ├── MES.Infrastructure/
│ └── MES.sln
│
├── MES.Frontend/
│ ├── src/
│ ├── angular.json # 确保 outputPath: "dist/MES-Frontend"
│ ├── package.json
│ ├── Dockerfile # 新增:Angular 打包 + Nginx
│ └── ...
│
└── nginx/
└── nginx.conf # 新增:Nginx 配置反向代理
步骤一:创建 .env 文件(安全存储密码)
在
MES/根目录下创建.env
env
MYSQL_ROOT_PASSWORD=your_password
ASPNETCORE_ENVIRONMENT=Production
步骤二:配置 .NET 8 API
1. 创建 MES.Backend/MES.API/Dockerfile
Dockerfile
# 使用 .NET SDK 构建
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app
# 复制项目文件并还原 NuGet 包
COPY MES.sln .
COPY MES.Backend/*.csproj ./MES.Backend/
COPY MES.Backend/MES.API/*.csproj ./MES.Backend/MES.API/
COPY MES.Backend/MES.Application/*.csproj ./MES.Backend/MES.Application/
COPY MES.Backend/MES.Core/*.csproj ./MES.Backend/MES.Core/
COPY MES.Backend/MES.Infrastructure/*.csproj ./MES.Backend/MES.Infrastructure/
RUN dotnet restore "MES.Backend/MES.API/MES.API.csproj"
# 复制所有代码并发布
COPY . .
WORKDIR /app/MES.Backend/MES.API
RUN dotnet publish -c Release -o /app/out --no-restore
# 运行时镜像
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build /app/out .
# 监听容器内的 80 端口
EXPOSE 80
# 设置环境变量
ENV ASPNETCORE_URLS=http://*:80
ENV ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
ENTRYPOINT ["dotnet", "MES.API.dll"]
⚠️ 注意:确保
Program.cs中没有硬编码 URL。使用默认 Kestrel 配置即可。
2. 修改 appsettings.Production.json(连接 MySQL)
json
{
"ConnectionStrings": {
"DefaultConnection": "Server=mysql-db;Port=3306;Database=MESDB;User=root;Password=your_password;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
步骤三:配置 Angular 16 前端
1. 检查 angular.json 输出路径
确保 architect → build → options → outputPath 是:
json
"outputPath": "dist/MES-Frontend"
否则请修改为一致。
2. 创建 MES.Frontend/Dockerfile
Dockerfile
# Stage 1: 构建 Angular 应用
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build -- --configuration=production
# Stage 2: 使用 Nginx 托管构建结果
FROM nginx:alpine
COPY --from=builder /app/dist/MES-Frontend /usr/share/nginx/html
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
3. 创建 nginx/nginx.conf
nginx
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
# 托管前端页面
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
# 代理 API 请求到 .NET 后端(通过 Docker 内部网络)
location /api/ {
proxy_pass http://mes-api:80/api/;
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;
}
# SignalR WebSocket 支持(如有)
location /hub/ {
proxy_pass http://mes-api:80/hub/;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
}
💡 前端代码中请求
/api/users将被自动转发到后端
4. 设置生产环境 API 地址
编辑:src/environments/environment.prod.ts
ts
export const environment = {
production: true,
apiUrl: '/api'
};
在服务中使用:
ts
this.http.get(`${environment.apiUrl}/users`)
步骤四:创建 docker-compose.yml
在
MES/根目录创建
yaml
version: '3.8'
# 加载环境变量
env_file:
- .env
services:
mysql-db:
image: mysql:8.0
container_name: mysql-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: MESDB
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
# 可选:初始化脚本
# - ./MES.Backend/MES.API/configure.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- mes-network
mes-api:
build:
context: ./MES.Backend/MES.API
dockerfile: Dockerfile
container_name: mes-api
ports:
- "5000:80" # 容器80 → 宿主机5000
environment:
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
- ConnectionStrings__DefaultConnection=Server=mysql-db;Port=3306;Database=MESDB;User=root;Password=${MYSQL_ROOT_PASSWORD};
depends_on:
- mysql-db
restart: unless-stopped
networks:
- mes-network
mes-frontend:
build:
context: ./MES.Frontend
dockerfile: Dockerfile
container_name: mes-frontend
ports:
- "6000:80" # 容器80 → 宿主机6000
depends_on:
- mes-api
restart: unless-stopped
networks:
- mes-network
volumes:
mysql_data:
networks:
mes-network:
driver: bridge
🔧 步骤五:启动服务
打开终端,在 MES/ 目录下运行:
bash
docker-compose up --build
首次运行会:
- 构建 .NET 镜像
- 构建 Angular+Nginx 镜像
- 启动 MySQL 并设置密码
- 启动 API 和前端
🌐 访问地址:
- 前端:http://localhost:6000
- 后端 API:http://localhost:5000/swagger(如果启用了 Swagger)
- 数据库:
localhost:3306,用户root,密码your_password
✅ 验证是否成功
- 打开浏览器 →
http://localhost:6000 - 页面正常加载 ✅
- 登录或调用数据接口 → 返回 JSON 数据 ✅
- 查看控制台无跨域错误(CORS)✅
- 数据库已创建
MESDB,表结构按需初始化 ✅
🛡️ 生产建议(进阶)
| 项目 | 建议 |
|---|---|
| HTTPS | 使用 Nginx + SSL 证书(Let's Encrypt) |
| 日志 | 挂载日志卷或将日志输出到 stdout |
| 数据持久化 | 确保 mysql_data 卷存在 |
| 自动迁移 | 在 .NET 中启用 IMigrationRunner 或使用 EF CLI |
| CI/CD | GitHub Actions 自动构建推送至服务器 |
🎉 总结
你已完成以下关键操作:
✅ 使用 Docker 统一管理三端服务
✅ 后端暴露端口 5000,前端 6000
✅ 数据库密码安全注入 ${MYSQL_ROOT_PASSWORD}
✅ 前后端分离但无缝通信(Nginx 代理)
✅ 一键部署命令:docker-compose up --build
📦 现在你的 MES 系统已经可以发布上线!