1. 项目概述
最近在帮朋友部署一个前后端分离项目时,发现手动配置Nginx、MySQL和各种环境依赖实在太费时间。作为一个常年和Docker打交道的开发者,我决定用Docker Compose来简化这个部署过程。经过几次迭代优化,现在只需要一个docker-compose.yml文件就能完成整个项目的部署,包括前端Vue应用、后端SpringBoot服务和数据库。
这种一键部署方案特别适合中小型项目的快速上线和开发环境搭建。相比传统部署方式,它解决了环境配置复杂、依赖冲突和迁移困难等痛点。下面我就把这个经过实战检验的方案分享给大家。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心架构设计
2.1 技术栈选型
这个方案的核心组件包括:
- 前端:基于Vue.js的单页应用,打包后由Nginx提供静态文件服务
- 后端:SpringBoot应用,提供RESTful API接口
- 数据库:MySQL 8.0,使用官方Docker镜像
- 代理层:Nginx作为反向代理,处理前后端路由和负载均衡
选择这些组件主要考虑了几个因素:
- 社区支持广泛,遇到问题容易找到解决方案
- 都有官方维护的Docker镜像,质量有保障
- 资源占用相对合理,适合中小型项目
2.2 网络拓扑设计
整个系统的容器网络结构如下:
code复制client -> Nginx(80)
-> /api/* -> SpringBoot(8080)
-> /* -> Vue静态资源
SpringBoot -> MySQL(3306)
这种设计有以下几个优点:
- 对外只暴露Nginx的80端口,安全性更好
- API请求和静态资源请求路径分离,便于管理
- 数据库不对外暴露,只能由后端服务访问
3. Docker Compose配置详解
3.1 基础服务定义
首先来看完整的docker-compose.yml文件:
yaml复制version: '3.8'
services:
nginx:
image: nginx:1.21-alpine
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./frontend/dist:/usr/share/nginx/html
depends_on:
- backend
networks:
- app-network
backend:
build: ./backend
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/app_db
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=123456
ports:
- "8080:8080"
depends_on:
- mysql
networks:
- app-network
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=app_db
volumes:
- mysql-data:/var/lib/mysql
networks:
- app-network
volumes:
mysql-data:
networks:
app-network:
driver: bridge
3.2 关键配置解析
-
Nginx服务:
- 使用轻量级的alpine版本镜像
- 挂载自定义配置目录和前端静态资源
- 通过depends_on确保后端服务先启动
-
后端服务:
- 使用Dockerfile构建镜像
- 通过环境变量注入数据库配置
- 暴露8080端口用于调试
-
MySQL服务:
- 使用命名卷持久化数据
- 初始化时创建数据库
- 不对外暴露端口,保证安全
提示:生产环境务必修改默认的数据库密码,建议使用docker secrets管理敏感信息
4. Nginx配置优化
4.1 反向代理配置
在nginx/conf.d/default.conf中添加:
nginx复制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;
proxy_set_header X-Real-IP $remote_addr;
}
}
这个配置实现了:
- 静态资源直接由Nginx提供
- /api/开头的请求转发到后端服务
- 支持Vue的路由模式
4.2 性能调优
在http块中添加以下优化参数:
nginx复制http {
# 启用gzip压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
5. 后端服务Dockerfile
后端服务的Dockerfile示例:
dockerfile复制FROM openjdk:11-jdk-slim
WORKDIR /app
# 先复制pom.xml单独构建依赖层
COPY pom.xml .
RUN mvn dependency:go-offline
# 复制源码并打包
COPY src ./src
RUN mvn package -DskipTests
# 运行jar包
ENTRYPOINT ["java","-jar","target/your-app.jar"]
这种分层构建方式可以充分利用Docker的缓存机制,加快构建速度。
6. 部署流程
6.1 准备工作
- 确保已安装Docker和Docker Compose
- 项目目录结构:
code复制project/ ├── docker-compose.yml ├── nginx/ │ └── conf.d/ ├── frontend/ │ └── dist/ └── backend/ ├── Dockerfile ├── pom.xml └── src/
6.2 启动服务
bash复制# 构建并启动所有服务
docker-compose up -d --build
# 查看日志
docker-compose logs -f
# 停止服务
docker-compose down
7. 常见问题解决
7.1 端口冲突
如果80端口被占用,可以修改docker-compose.yml中的端口映射:
yaml复制ports:
- "8081:80"
7.2 数据库连接问题
确保后端服务的数据库连接URL使用服务名而非localhost:
properties复制spring.datasource.url=jdbc:mysql://mysql:3306/app_db
7.3 前端路由刷新404
这是Vue路由的常见问题,确保Nginx配置中包含:
nginx复制try_files $uri $uri/ /index.html;
8. 生产环境优化建议
-
使用.env文件管理环境变量:
bash复制
DB_PASSWORD=your_strong_password在docker-compose.yml中引用:
yaml复制environment: - SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD} -
配置健康检查:
yaml复制healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval: 30s timeout: 10s retries: 3 -
资源限制:
yaml复制deploy: resources: limits: cpus: '0.5' memory: 512M
经过多次实践,我发现这种部署方式特别适合中小团队的敏捷开发。当需要升级某个服务时,只需要修改对应的Dockerfile或配置,然后重新构建部署即可,其他服务不受影响。对于有更复杂需求的场景,可以考虑加入Redis缓存、消息队列等服务,扩展起来也非常方便。
