资讯详情

Docker Compose部署多.NET与Vue全栈项目实践

📅 2026/10/31 3:00:01 | 华诺云谱 👁 阅读
Docker Compose部署多.NET与Vue全栈项目实践
1. 项目概述这个项目记录了我用Docker Compose部署多.NET后端API和多Vue前端Web的完整过程。作为一名全栈开发者我经常需要同时管理多个前后端服务传统的部署方式既繁琐又容易出错。通过Docker Compose我实现了2个及以上.NET8后端API和2个及以上Vue前端Web的容器化部署解决了端口隔离、配置统一、Nginx分流等实际问题。这个方案特别适合中小型全栈项目尤其是需要同时运行多个API服务和前端项目的场景。我在实际部署中踩过不少坑最终整理出了这套亲测无坑的完整方案。它不仅支持多数据库扩展还包含了多种实用场景的配置方法。2. 环境准备与工具选型2.1 基础环境要求在开始之前确保你的开发环境满足以下要求Docker 20.10Docker Compose 2.0.NET 8 SDKNode.js 16 (用于Vue开发)推荐使用Linux系统(如Ubuntu 20.04)或WSL2(Windows用户)提示可以通过docker --version和docker compose version命令检查版本。如果版本过低建议先升级。2.2 为什么选择Docker ComposeDocker Compose有以下几个优势特别适合这种多服务部署场景服务编排可以一键启动所有相关容器网络隔离自动创建内部网络服务间通信更安全配置集中所有服务配置都在一个YAML文件中管理环境一致开发、测试、生产环境完全一致3. 项目结构与设计思路3.1 基础项目结构我建议采用以下目录结构project-root/ ├── docker-compose.yml # 主配置文件 ├── nginx/ │ └── nginx.conf # Nginx配置 ├── api1/ # 第一个.NET API项目 │ ├── Dockerfile │ └── ... ├── api2/ # 第二个.NET API项目 │ ├── Dockerfile │ └── ... ├── web1/ # 第一个Vue项目 │ ├── Dockerfile │ └── ... └── web2/ # 第二个Vue项目 ├── Dockerfile └── ...3.2 网络设计我采用了以下网络方案创建一个自定义bridge网络app-network所有容器都加入这个网络通过容器名进行服务发现Nginx作为反向代理对外暴露服务这种设计既保证了服务间通信的安全性又简化了配置。4. 编写Dockerfile4.1 .NET API的Dockerfile每个.NET API项目都需要一个Dockerfile以下是我优化后的版本# 使用官方.NET 8镜像 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src # 复制项目文件并恢复依赖 COPY [Api1/Api1.csproj, Api1/] RUN dotnet restore Api1/Api1.csproj # 复制所有源代码 COPY . . WORKDIR /src/Api1 # 构建发布版本 RUN dotnet build Api1.csproj -c Release -o /app/build RUN dotnet publish Api1.csproj -c Release -o /app/publish # 运行时镜像 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final WORKDIR /app COPY --frombuild /app/publish . ENTRYPOINT [dotnet, Api1.dll]关键点说明使用多阶段构建减小镜像体积先复制.csproj文件再恢复依赖利用Docker缓存生产环境使用aspnet镜像而非sdk镜像4.2 Vue项目的DockerfileVue项目的Dockerfile有所不同# 构建阶段 FROM node:16 AS build WORKDIR /app # 复制依赖文件 COPY package*.json ./ RUN npm install # 复制源代码并构建 COPY . . RUN npm run build # 生产环境 FROM nginx:alpine COPY --frombuild /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80注意事项使用alpine版本的nginx镜像减小体积构建阶段和生产阶段分离需要自定义nginx配置处理前端路由5. Docker Compose配置详解5.1 基础服务配置以下是docker-compose.yml的核心部分version: 3.8 services: api1: build: context: . dockerfile: Api1/Dockerfile container_name: api1 networks: - app-network environment: - ASPNETCORE_ENVIRONMENTProduction - ConnectionStrings__DefaultConnectionServerdb;DatabaseApi1Db;Usersa;PasswordYourStrongPassw0rd; depends_on: - db api2: build: context: . dockerfile: Api2/Dockerfile container_name: api2 networks: - app-network environment: - ASPNETCORE_ENVIRONMENTProduction - ConnectionStrings__DefaultConnectionServerdb;DatabaseApi2Db;Usersa;PasswordYourStrongPassw0rd; depends_on: - db web1: build: context: . dockerfile: Web1/Dockerfile container_name: web1 networks: - app-network depends_on: - api1 web2: build: context: . dockerfile: Web2/Dockerfile container_name: web2 networks: - app-network depends_on: - api2 nginx: image: nginx:alpine container_name: nginx ports: - 80:80 - 443:443 volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf - ./nginx/certs:/etc/nginx/certs networks: - app-network depends_on: - web1 - web2 db: image: mcr.microsoft.com/mssql/server:2022-latest container_name: db environment: - ACCEPT_EULAY - SA_PASSWORDYourStrongPassw0rd - MSSQL_PIDExpress volumes: - sql-data:/var/opt/mssql networks: - app-network ports: - 1433:1433 networks: app-network: driver: bridge volumes: sql-data:5.2 关键配置解析网络配置所有服务都加入app-network使用bridge驱动这是默认且最稳定的选择数据库配置使用SQL Server官方镜像通过volume持久化数据注意SA密码复杂度要求环境变量区分不同环境的配置连接字符串使用__作为层级分隔符依赖管理使用depends_on控制启动顺序但要注意这不能保证服务完全就绪6. Nginx配置与负载均衡6.1 基础Nginx配置nginx.conf的核心内容upstream api1 { server api1:80; } upstream api2 { server api2:80; } server { listen 80; server_name localhost; location /api1/ { proxy_pass http://api1/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /api2/ { proxy_pass http://api2/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /web1/ { alias /usr/share/nginx/html/web1/; try_files $uri $uri/ /web1/index.html; } location /web2/ { alias /usr/share/nginx/html/web2/; try_files $uri $uri/ /web2/index.html; } }6.2 配置要点路由规则通过路径前缀区分不同服务API服务使用proxy_pass转发前端项目需要处理HTML5 History模式性能优化启用gzip压缩设置合理的缓存头限制请求体大小HTTPS配置建议在生产环境启用HTTPS可以使用Lets Encrypt免费证书7. 多数据库扩展方案7.1 支持多种数据库在实际项目中我们可能需要使用不同类型的数据库。Docker Compose可以轻松扩展services: # SQL Server (已配置) db: image: mcr.microsoft.com/mssql/server:2022-latest # ...其他配置 # 添加PostgreSQL postgres: image: postgres:15 environment: - POSTGRES_USERadmin - POSTGRES_PASSWORDsecret - POSTGRES_DBmydb volumes: - postgres-data:/var/lib/postgresql/data networks: - app-network # 添加MongoDB mongo: image: mongo:6 environment: - MONGO_INITDB_ROOT_USERNAMEroot - MONGO_INITDB_ROOT_PASSWORDexample volumes: - mongo-data:/data/db networks: - app-network volumes: postgres-data: mongo-data:7.2 数据库连接配置不同数据库的连接字符串示例# .NET中的连接字符串配置示例 environment: # SQL Server - ConnectionStrings__SqlServerServerdb;DatabaseMyDb;Usersa;PasswordYourStrongPassw0rd; # PostgreSQL - ConnectionStrings__PostgresHostpostgres;Databasemydb;Usernameadmin;Passwordsecret; # MongoDB - ConnectionStrings__Mongomongodb://root:examplemongo:27017/?authSourceadmin8. 实用场景与高级配置8.1 开发环境热重载在开发时我们可以配置volume映射实现代码热更新services: api1: # ...其他配置 volumes: - ./Api1:/app - ~/.nuget:/root/.nuget # 缓存NuGet包 environment: - ASPNETCORE_ENVIRONMENTDevelopment command: dotnet watch run对于Vue项目services: web1: # ...其他配置 volumes: - ./Web1:/app ports: - 8080:8080 # 暴露开发服务器端口 command: npm run serve8.2 健康检查与监控添加健康检查确保服务可用性services: api1: # ...其他配置 healthcheck: test: [CMD, curl, -f, http://localhost/health] interval: 30s timeout: 10s retries: 38.3 日志管理配置日志驱动和选项services: api1: # ...其他配置 logging: driver: json-file options: max-size: 10m max-file: 39. 部署与运维实践9.1 启动与停止服务常用命令# 构建并启动所有服务 docker compose up -d --build # 停止所有服务 docker compose down # 查看日志 docker compose logs -f api1 # 重启单个服务 docker compose restart api19.2 生产环境优化建议资源限制services: api1: deploy: resources: limits: cpus: 1 memory: 512M重启策略services: api1: restart: unless-stopped秘密管理services: api1: secrets: - db_password secrets: db_password: file: ./secrets/db_password.txt10. 常见问题与解决方案10.1 容器启动顺序问题症状应用启动时数据库还未准备好。解决方案在应用代码中添加重试逻辑使用wait-for-it.sh脚本services: api1: # ...其他配置 command: [./wait-for-it.sh, db:1433, --, dotnet, Api1.dll]10.2 端口冲突问题症状端口已被占用导致容器启动失败。解决方案检查并杀死占用端口的进程修改docker-compose.yml中的端口映射services: nginx: ports: - 8080:8010.3 前端路由问题症状刷新页面后出现404。解决方案确保Nginx配置正确处理前端路由location /web1/ { alias /usr/share/nginx/html/web1/; try_files $uri $uri/ /web1/index.html; }10.4 数据库连接问题症状应用无法连接数据库。排查步骤检查数据库容器是否正常运行验证连接字符串是否正确检查网络配置是否在同一网络测试从应用容器内能否ping通数据库容器11. 性能优化技巧11.1 镜像构建优化使用.dockerignore文件排除不必要的文件合理安排Dockerfile指令顺序利用缓存多阶段构建减小最终镜像体积使用alpine等轻量级基础镜像11.2 应用性能优化启用响应压缩配置合理的缓存头实现健康检查端点使用连接池管理数据库连接11.3 网络性能优化使用自定义网络而非默认网络合理配置DNS选项考虑使用host网络模式对性能要求极高的服务监控网络流量识别瓶颈12. 安全最佳实践12.1 容器安全避免使用root用户运行容器定期更新基础镜像限制容器权限扫描镜像中的漏洞12.2 网络安全使用内部网络隔离服务仅暴露必要的端口启用HTTPS加密通信配置防火墙规则12.3 数据安全使用volume持久化重要数据加密敏感数据定期备份数据库安全地管理密钥和密码13. 监控与日志收集13.1 基础监控使用docker stats查看资源使用情况配置Prometheus监控设置Grafana仪表板实现应用性能监控(APM)13.2 日志收集方案ELK Stack (Elasticsearch, Logstash, Kibana)Fluentd ElasticsearchLoki Grafana云服务商的日志服务13.3 告警配置设置资源使用阈值告警服务不可用告警错误日志关键字告警健康检查失败告警14. CI/CD集成14.1 基础CI/CD流程代码提交触发构建运行单元测试构建Docker镜像部署到测试环境人工或自动验证部署到生产环境14.2 GitHub Actions示例name: Build and Deploy on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Login to Docker Hub uses: docker/login-actionv2 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Build and push uses: docker/build-push-actionv3 with: context: . push: true tags: user/app:latest deploy: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Install Docker Compose run: sudo curl -L https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose - name: Deploy run: docker-compose up -d env: DB_PASSWORD: ${{ secrets.DB_PASSWORD }}15. 扩展与定制15.1 多环境配置通过多个compose文件管理不同环境# 开发环境 docker compose -f docker-compose.yml -f docker-compose.dev.yml up # 生产环境 docker compose -f docker-compose.yml -f docker-compose.prod.yml up15.2 自定义网络配置更复杂的网络需求示例networks: frontend: driver: bridge ipam: config: - subnet: 172.20.0.0/16 backend: driver: bridge internal: true15.3 使用扩展字段利用Compose的扩展字段简化配置x-common-env: common-env - TZAsia/Shanghai - LANGC.UTF-8 services: api1: environment: : *common-env - ASPNETCORE_ENVIRONMENTProduction16. 实际案例分享16.1 电商平台部署场景特点3个.NET微服务(用户、商品、订单)2个Vue前端(用户端、管理端)Redis缓存消息队列关键配置services: redis: image: redis:alpine networks: - app-network rabbitmq: image: rabbitmq:management networks: - app-network16.2 企业内部系统场景特点单点登录服务多个业务模块报表服务定时任务特殊配置services: scheduler: image: quartznet/quartznet networks: - app-network depends_on: - db17. 未来演进方向17.1 迁移到Kubernetes当服务规模扩大时可以考虑使用Kompose工具转换Compose文件逐步迁移服务到K8s集群实现蓝绿部署或金丝雀发布17.2 服务网格集成考虑引入Istio或Linkerd管理服务间通信实现mTLS加密细粒度的流量控制17.3 无服务器架构部分服务可以考虑使用Azure Functions或AWS Lambda容器化无服务器功能混合部署模式18. 经验总结与建议在实际部署过程中我总结了以下几点经验配置管理将环境变量和敏感信息通过.env文件或Docker secrets管理不要硬编码在compose文件中。资源监控从一开始就配置好监控和日志收集这在排查问题时能节省大量时间。渐进式部署先部署基础服务(如数据库)再部署依赖它们的应用服务。文档记录详细记录每个服务的配置项和依赖关系团队协作时尤为重要。备份策略特别是数据库volume要有定期备份和恢复测试的流程。安全扫描定期扫描镜像中的漏洞更新基础镜像。性能测试在模拟生产环境流量的情况下测试系统表现提前发现瓶颈。这套方案在我参与的多个项目中都得到了验证确实能够显著简化部署流程提高开发效率。特别是在需要频繁更新和扩展的敏捷开发环境中容器化的优势更加明显。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑