
1. 项目概述与背景在现代Web应用开发中前后端分离架构已成为主流模式。Spring Boot作为Java生态中最流行的后端框架与Vue.js这一渐进式前端框架的组合能够快速构建高性能的企业级应用。而Docker容器化技术则为这类应用的部署提供了标准化、可移植的解决方案。我最近在客户项目中成功实施了一套基于Docker的Spring Boot Vue全栈部署方案。相比传统部署方式容器化部署将环境准备时间从2小时缩短到10分钟且完全消除了在我机器上能跑的环境差异问题。下面将完整分享这套经过实战检验的部署方案。2. 环境准备与工具选型2.1 基础环境要求Docker Engine 20.10社区版即可Docker Compose 1.29JDK 11推荐Amazon CorrettoNode.js 14推荐LTS版本Maven 3.6用于后端打包提示生产环境建议使用Docker的稳定版本避免使用edge版本。Windows/macOS用户建议安装Docker DesktopLinux用户可通过官方仓库安装。2.2 项目结构设计典型的前后端分离项目目录结构如下project-root/ ├── backend/ # Spring Boot项目 │ ├── src/ │ ├── pom.xml │ └── Dockerfile ├── frontend/ # Vue项目 │ ├── src/ │ ├── package.json │ └── Dockerfile └── docker-compose.yml # 编排配置文件这种结构清晰分离了前后端代码每个组件都有自己的Dockerfile构建定义最终通过docker-compose进行服务编排。3. 后端Spring Boot容器化3.1 Dockerfile配置# 使用官方OpenJDK基础镜像 FROM amazoncorretto:11-alpine3.17 # 设置工作目录 WORKDIR /app # 复制Maven构建的jar包 COPY target/your-application.jar app.jar # 暴露服务端口 EXPOSE 8080 # 启动命令 ENTRYPOINT [java,-jar,app.jar]关键参数说明alpine版本镜像体积仅约150MB远小于标准Linux镜像使用确定性的JDK版本如11.0.18而非latest标签通过WORKDIR规范容器内路径3.2 优化构建过程在项目根目录执行以下命令构建镜像# 先打包Spring Boot应用 mvn clean package -DskipTests # 构建Docker镜像 docker build -t your-username/backend:1.0.0 -f backend/Dockerfile .构建优化技巧使用.dockerignore文件排除不必要的文件如IDE配置多阶段构建可进一步减小镜像体积版本标签应遵循语义化版本规范4. 前端Vue项目容器化4.1 Dockerfile配置# 构建阶段 FROM node:16-alpine as build-stage WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # 生产阶段 FROM nginx:1.23-alpine COPY --frombuild-stage /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80这个多阶段构建方案第一阶段使用Node镜像编译Vue项目第二阶段使用轻量级Nginx镜像最终镜像仅包含编译后的静态文件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; } location /api { proxy_pass http://backend:8080; proxy_set_header Host $host; } }此配置实现了静态文件服务前端路由支持history模式后端API代理解决跨域5. Docker Compose编排5.1 完整编排文件version: 3.8 services: backend: image: your-username/backend:1.0.0 container_name: backend ports: - 8080:8080 environment: - SPRING_PROFILES_ACTIVEprod networks: - app-network frontend: image: your-username/frontend:1.0.0 container_name: frontend ports: - 80:80 depends_on: - backend networks: - app-network networks: app-network: driver: bridge5.2 关键配置解析网络配置自定义bridge网络使容器可通过服务名通信依赖管理前端服务显式依赖后端服务环境变量传递Spring Boot的profile配置端口映射前端80端口对外暴露后端8080仅在内部访问6. 部署与运维实践6.1 一键部署命令# 启动所有服务后台模式 docker-compose up -d # 查看运行状态 docker-compose ps # 查看日志 docker-compose logs -f6.2 生产环境建议资源限制为容器配置CPU/内存限制deploy: resources: limits: cpus: 0.5 memory: 512M健康检查添加应用健康检查healthcheck: test: [CMD, curl, -f, http://localhost:8080/actuator/health] interval: 30s timeout: 10s retries: 3日志管理配置日志驱动和轮转logging: driver: json-file options: max-size: 10m max-file: 37. 常见问题排查7.1 前端无法访问后端API现象浏览器控制台出现CORS错误解决方案确认nginx配置中的proxy_pass地址正确检查后端服务的CrossOrigin注解配置验证docker网络连通性docker exec -it frontend curl http://backend:8080/api/health7.2 静态资源加载404现象页面空白或部分资源加载失败排查步骤进入前端容器检查文件是否存在docker exec -it frontend ls -l /usr/share/nginx/html确认Vue项目的publicPath配置检查nginx的root指令路径7.3 容器启动顺序问题现象前端启动时后端尚未就绪优化方案使用depends_on结合健康检查在前端添加启动等待脚本// 在main.js中添加 const waitFor (url, timeout 30000) { const start Date.now() return new Promise((resolve) { const attempt () { fetch(url) .then(resolve) .catch(() { if (Date.now() - start timeout) { console.error(Timeout waiting for ${url}) resolve() } else { setTimeout(attempt, 1000) } }) } attempt() }) } waitFor(process.env.VUE_APP_API_URL /health).then(() { new Vue({ /* ... */ }).$mount(#app) })8. 性能优化实践8.1 镜像构建优化多阶段构建如前所示大幅减小最终镜像体积层缓存优化将不常变化的操作放在前面# 先复制package.json并安装依赖 COPY package*.json ./ RUN npm install # 然后复制其他文件 COPY . .使用.dockerignorenode_modules .git *.md .idea8.2 运行时优化JVM参数调优ENTRYPOINT [java, -Xms256m, -Xmx512m, -jar, app.jar]Nginx性能调优events { worker_connections 1024; } http { gzip on; gzip_types text/plain application/json; }容器资源监控docker stats docker-compose top9. 安全加固措施9.1 镜像安全定期更新基础镜像FROM amazoncorretto:11.0.18-alpine3.17 # 明确版本号使用非root用户运行RUN addgroup -S springboot adduser -S springboot -G springboot USER springboot9.2 网络防护限制不必要的端口暴露# 只暴露前端80端口 ports: - 80:80配置网络隔离networks: app-network: internal: true # 禁止外部访问9.3 密钥管理使用Docker secrets或环境变量文件env_file: - .env.production避免在镜像中硬编码敏感信息10. 持续集成与部署10.1 GitHub Actions示例name: Build and Deploy on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 # 构建后端 - name: Build Backend run: | cd backend mvn package -DskipTests docker build -t your-username/backend:${{ github.sha }} . # 构建前端 - name: Build Frontend run: | cd frontend npm install npm run build docker build -t your-username/frontend:${{ github.sha }} . # 推送镜像 - name: Login to Docker Hub uses: docker/login-actionv2 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Push Images run: | docker push your-username/backend:${{ github.sha }} docker push your-username/frontend:${{ github.sha }}10.2 部署策略蓝绿部署通过负载均衡切换流量滚动更新逐步替换旧容器docker-compose pull docker-compose up -d版本回滚docker-compose up -d --force-recreate --no-deps frontendyour-username/frontend:old-version在实际项目中这套Docker化部署方案使我们的部署效率提升了80%环境一致性达到100%。特别是在团队协作和CI/CD流水线中容器化的优势更加明显。对于需要快速迭代的全栈项目这种部署方式值得推荐。