零基础用Docker部署前后端分离项目全流程
如果你正在用 Vue + Spring Boot(或 Node/Flask)做前后端分离项目,想通过 Docker 一键部署到服务器,这篇教程就是为你准备的。
我会从环境准备到启动验证,把每一步命令和配置都写清楚,你只要跟着复制粘贴、修改一两处参数就能跑起来。
1. 准备 Docker 环境和项目代码
首先确认服务器已安装 Docker 和 docker-compose。
云服务器(CentOS/Ubuntu)推荐用宝塔面板,或者直接 SSH 连接执行命令。
- 安装 Docker:
curl -fsSL https://get.docker.com | bash然后systemctl start docker。 - 安装 docker-compose:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose,再sudo chmod +x /usr/local/bin/docker-compose。 - 把项目代码上传到服务器,比如放在
/opt/myapp目录下,目录结构建议:/opt/myapp/backend(后端源码)、/opt/myapp/frontend(前端打包后的 dist 或源码)。如果前端需要构建,提前在本地npm run build后上传 dist 文件夹。
2. 编写后端 Dockerfile
在后端项目根目录创建 Dockerfile,下面是 Java Spring Boot 的示例(其他语言思路类似):
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/myapp.jar . # 或 COPY . . 然后执行 mvn package,这里直接用已构建的jar
EXPOSE 8080
CMD ["java", "-jar", "myapp.jar"]如果你用 Node 后端,可以写成:
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]构建镜像:在 backend 目录下执行 docker build -t my-backend:latest .。
3. 编写前端 Nginx 配置和 Dockerfile
前端静态文件建议用 Nginx 容器托管。
在 frontend 目录下创建 default.conf:
server {
listen 80;
server_name your-domain.com; # 或服务器IP
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
后端 API 反向代理
location /api/ {
proxy_pass http://backend:8080; # 后端容器名
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
然后写 Dockerfile:
FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY default.conf /etc/nginx/conf.d/default.conf构建镜像:docker build -t my-frontend:latest .。
4. 用 docker-compose.yml 编排所有服务
在项目根目录(/opt/myapp)创建 docker-compose.yml,统一管理后端、前端和数据库:
version: '3'
services:
backend:
image: my-backend:latest
container_name: backend
ports:
- "8080:8080"
environment:
- DB_HOST=mysql_db
- DB_USER=root
- DB_PASSWORD=123456
depends_on:
- mysql_db
frontend:
image: my-frontend:latest
container_name: frontend
ports:
- "80:80"
depends_on:
- backend
mysql_db:
image: mysql:5.7
container_name: mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
注意:数据库映射端口 3306 仅用于本地调试,安全组里可以关闭对外暴露。
后端连接数据库时,地址用容器名 mysql_db(docker-compose 内部 DNS 自动解析)。
如果后端配置文件里写的是 localhost,记得改为 mysql_db。
5. 启动服务并验证
在 docker-compose.yml 所在目录执行:docker-compose up -d。第一次启动会拉取 MySQL 镜像,稍等一会儿。查看所有容器是否运行:docker-compose ps。查看日志:docker-compose logs -f backend。
验证:
- 前端:浏览器访问
http://服务器IP,应该能看到前端页面,并且接口请求能正常返回数据(注意跨域,已通过 Nginx 反向代理解决)。 - 后端:直接访问
http://服务器IP:8080/api/xxx验证(如果防火墙开放了8080端口)。
6. 避坑指南与高频问题
问题1:前端访问后端接口报 404 或 503
- 检查
default.conf里的proxy_pass地址是否写对了容器名(http://backend:8080),不要写localhost。 - 检查后端容器是否正常运行,用
docker logs backend看报错。
问题2:数据库连接失败
- 确保后端配置文件中的数据库主机名与 docker-compose 中的服务名一致(
mysql_db),并且用户名密码匹配。 - MySQL 容器至少需要 10-20 秒完全初始化,如果后端启动比 MySQL 快,可以加
healthcheck或后端重试机制。简单方法:手动docker-compose restart backend再试。
问题3:端口冲突
- 如果服务器 80 或 8080 已被占用,修改 docker-compose.yml 中 ports 的宿主机映射,比如
"8081:8080",然后前端 Nginx 反向代理也要对应调整。
问题4:数据持久化
- MySQL 数据卷
mysql_data已挂载到宿主机,即使容器删除,数据不会丢。如果想备份或迁移,可以docker run -v mysql_data:/data --rm busybox tar czf /backup.tar.gz /data。
如果你按照上面的步骤执行完,前后端分离项目应该已经跑起来了。
遇到异常时,优先检查 docker-compose logs 的输出,大部分问题都能定位到。
刚开始接触 Docker 别着急,多试几次就能掌握这套流程。