1. 项目概述:为什么选择Docker部署Spring Boot + Vue项目?
现代Web应用开发中,前后端分离架构已成为主流模式。Spring Boot作为Java生态中最流行的后端框架,与Vue.js这个渐进式前端框架的组合,能够高效构建企业级应用。但在实际部署时,环境配置差异、依赖冲突等问题常常让开发者头疼。
Docker容器化技术通过标准化应用运行环境,完美解决了"在我机器上能跑"的经典问题。将Spring Boot后端和Vue前端分别容器化后,可以实现:
- 环境一致性:开发、测试、生产环境完全一致
- 快速部署:镜像一次构建,随处运行
- 资源隔离:避免端口冲突和依赖污染
- 弹性扩展:便于后续集群化部署
我在多个生产项目中采用这种部署方案,相比传统部署方式,上线效率提升60%以上,且几乎消除了环境导致的故障。
2. 环境准备与工具选型
2.1 基础环境配置
推荐使用以下环境组合:
- 操作系统:Ubuntu 20.04 LTS(生产环境)或Windows 10/11 WSL2(开发环境)
- Docker Engine:20.10+ 版本
- Docker Compose:v2.17+
- JDK:17(Spring Boot 3.x兼容版本)
- Node.js:16.x LTS(Vue 3.x推荐版本)
注意:避免在Windows直接安装Docker Desktop,推荐通过WSL2集成。若遇到"virtualization support not detected"错误,需在BIOS中开启VT-x/AMD-V虚拟化支持。
2.2 项目结构规划
典型的前后端分离项目结构应如下组织:
project-root/ ├── backend/ # Spring Boot项目 │ ├── src/ │ ├── Dockerfile │ └── pom.xml ├── frontend/ # Vue项目 │ ├── public/ │ ├── src/ │ ├── Dockerfile │ └── package.json └── docker-compose.yml # 编排配置文件这种结构清晰隔离前后端代码,便于独立开发和部署。
3. Spring Boot后端容器化
3.1 编写高效的Dockerfile
后端Dockerfile示例:
# 第一阶段:构建 FROM maven:3.8.6-eclipse-temurin-17 AS build WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests # 第二阶段:运行 FROM eclipse-temurin:17-jre-jammy WORKDIR /app COPY --from=build /app/target/*.jar app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]关键优化点:
- 使用多阶段构建减小镜像体积(从~500MB降至~150MB)
- 先单独复制pom.xml下载依赖,利用Docker缓存加速构建
- 使用官方JRE基础镜像而非JDK,减少不必要的工具
3.2 生产环境最佳实践
- JVM参数调优:
ENTRYPOINT ["java", "-Xms512m", "-Xmx1024m", "-XX:+UseG1GC", "-jar", "app.jar"]- 健康检查配置:
HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:8080/actuator/health || exit 1- 时区设置:
ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone4. Vue前端容器化
4.1 前端Dockerfile设计
# 构建阶段 FROM node:16-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 生产阶段 FROM nginx:1.23-alpine COPY --from=build /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80重要提示:使用alpine基础镜像可使最终镜像从~200MB降至~20MB
4.2 Nginx性能优化配置
nginx.conf示例:
server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; # 开启gzip压缩 gzip on; gzip_types text/plain text/css application/json application/javascript text/xml; # 缓存控制 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, no-transform"; } } # API代理配置 location /api { proxy_pass http://backend:8080; proxy_set_header Host $host; } }5. 使用Docker Compose编排服务
5.1 基础编排配置
docker-compose.yml示例:
version: '3.8' services: backend: build: ./backend ports: - "8080:8080" environment: - SPRING_PROFILES_ACTIVE=prod networks: - app-network restart: unless-stopped frontend: build: ./frontend ports: - "80:80" depends_on: - backend networks: - app-network restart: unless-stopped networks: app-network: driver: bridge5.2 生产级增强配置
- 资源限制:
services: backend: deploy: resources: limits: cpus: '1' memory: 1G- 日志管理:
logging: driver: "json-file" options: max-size: "10m" max-file: "3"- 健康检查:
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval: 30s timeout: 5s retries: 36. 部署流程与持续集成
6.1 本地开发测试流程
- 构建并启动服务:
docker-compose up --build -d- 查看运行日志:
docker-compose logs -f backend- 执行单元测试:
docker-compose run backend mvn test6.2 CI/CD集成建议
GitLab CI示例:
stages: - build - test - deploy build-backend: stage: build image: maven:3.8.6-eclipse-temurin-17 script: - mvn package -DskipTests artifacts: paths: - backend/target/*.jar build-frontend: stage: build image: node:16 script: - npm install - npm run build artifacts: paths: - frontend/dist deploy-prod: stage: deploy image: docker:20.10 services: - docker:dind script: - docker-compose -f docker-compose.prod.yml up -d --build only: - main7. 常见问题排查指南
7.1 容器启动失败排查
- 查看容器日志:
docker logs <container_id> --tail 100 -f- 进入容器调试:
docker exec -it <container_id> sh- 端口冲突处理:
netstat -tulnp | grep 8080 kill <pid> # 或修改应用端口7.2 典型错误解决方案
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| 前端无法访问API | CORS限制 | 配置后端CORS或通过Nginx代理 |
| 静态资源404 | Nginx配置错误 | 检查dist目录映射和try_files配置 |
| 数据库连接失败 | 网络隔离 | 确保数据库服务在同一个Docker网络 |
| 内存溢出 | JVM配置不足 | 调整-Xmx参数或容器内存限制 |
7.3 性能优化技巧
- 镜像构建加速:
# 使用BuildKit引擎 DOCKER_BUILDKIT=1 docker build .- 多阶段构建缓存:
RUN --mount=type=cache,target=/root/.m2 mvn package- 使用.dockerignore:
.git **/node_modules **/target *.iml8. 进阶部署方案
8.1 集群化部署准备
- 容器注册中心:
docker run -d -p 5000:5000 --restart always --name registry registry:2- 镜像标记与推送:
docker tag frontend localhost:5000/frontend:1.0 docker push localhost:5000/frontend:1.08.2 Kubernetes部署示例
deployment.yaml片段:
apiVersion: apps/v1 kind: Deployment metadata: name: backend spec: replicas: 3 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: backend image: your-registry/backend:1.0 ports: - containerPort: 8080 resources: limits: cpu: "1" memory: 1Gi8.3 监控方案集成
- Prometheus监控:
# Spring Boot配置 management: endpoints: web: exposure: include: health,info,prometheus metrics: tags: application: ${spring.application.name}- Grafana仪表板:
docker run -d -p 3000:3000 --name=grafana grafana/grafana在实际生产部署中,建议先在小规模环境验证所有配置,再逐步滚动更新到整个集群。对于高可用要求严格的场景,可以考虑结合Redis缓存会话数据,使用Nginx做负载均衡,并配置数据库主从复制。