SpringBoot+Vue项目Docker部署
项目结构
在服务器上创建部署目录:
bash
mkdir -p ~/app/{backend,frontend,logs}
cd ~/app最终目录结构:
plain
~/app/
├── docker-compose.yml # 编排文件
├── backend/
│ ├── Dockerfile
│ └── app.jar # Spring Boot 打包的 jar
├── frontend/
│ ├── Dockerfile
│ ├── nginx.conf # Nginx 配置
│ └── dist/ # Vue 打包后的静态文件
└── logs/ # 后端日志持久化目录SpringBoot后端配置
1.构建后端Dockerfile
~/app/backend/Dockerfile
dockerfile
# 使用 Eclipse Temurin JDK 21(Spring Boot 3 推荐)
FROM eclipse-temurin:21-jdk-alpine
# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 工作目录
WORKDIR /app
# 复制 jar 包(注意:你需要先将打包好的 jar 上传到这里)
COPY app.jar app.jar
# 创建日志目录并设置权限
RUN mkdir -p /app/logs && chmod 777 /app/logs
# 暴露端口 根据你后端的服务端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]2.Spring Boot 日志配置(持久化关键)
在 application.yml 或 application.properties 中配置日志输出到文件:
application.yml
yaml
logging:
file:
path: /app/logs
level:
root: INFO
com.coco.chatserver: DEBUG
logback:
rollingpolicy:
max-file-size: 10MB
max-history: 30
total-size-cap: 1GB宿主机也的日志目录也需要给权限
bash
# 或者更安全的:递归给目录写权限
chmod -R 755 logs/3.打包并上传
将打包好的jar文件上传至服务器对应目录
bash
# 上传到服务器(替换为你的服务器IP)
scp target/your-app.jar root@你的公网IP:/root/app/backend/app.jar前端 Vue 3 配置
1.打包本地项目
bash
# 确保 vue.config.js 中配置了正确的 publicPath(使用相对路径)
npm run build2.上传打包文件
因为dist是目录,使用scp上传的时候可能出问题,建议打包为tar文件上传至服务器后再解压
bash
# 将 dist 文件上传到服务器
scp dist.tar root@你的公网IP:/root/app/frontend/3.前端 Dockerfile
~/app/frontend/Dockerfile
dockerfile
# 使用 Nginx 作为运行环境
FROM nginx:alpine
# 复制自定义 Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 复制 Vue 打包后的静态文件
COPY dist /usr/share/nginx/html
# 暴露 80 端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]4.Nginx 配置(反向代理)
~/app/frontend/nginx.conf
nginx
server {
listen 80;
server_name _;
# 前端静态页面
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# API 接口代理
location /api/ {
proxy_pass http://backend:8080/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# Socket.IO WebSocket 代理(核心配置)
location /socket.io/ {
proxy_pass http://backend:9092/socket.io/; # Docker 内部通过服务名访问
proxy_http_version 1.1;
# WebSocket 升级头
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 长连接超时(必须!)
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
}注意:这里
proxy_pass http://backend:8080中的backend是 Docker Compose 中的服务名,Docker 会自动解析为容器 IP。
前端代码需要将socket地址和axios地址进行修改
socket:
ts
const SOCKET_URL = import.meta.env.DEV
? 'http://localhost:9092'
: '' // 生产环境:空字符串 = 当前域名(走 Nginx 80 端口)
export function connectSocket(token: string): Socket {
if (socket?.connected) return socket
socket = io(SOCKET_URL, {
path: '/socket.io/', // 必须指定,让 Nginx 识别转发
query: { token },
transports: ['websocket', 'polling']
})
return socket
}request:
ts
// 根据当前模式自动选择 baseURL
const baseURL = import.meta.env.PROD ? '/api' : 'http://localhost:8089'
const http = axios.create({
baseURL: baseURL,
timeout: 5000
})Docker Compose 编排文件
~/app/docker-compose.yml
yaml
version: '3.8'
services:
# 后端服务
backend:
build: ./backend
container_name: springboot-app
restart: always
ports:
- "8080:8080"
volumes:
# 日志持久化:将容器内的 /app/logs 映射到宿主机的 ./logs
- ./logs:/app/logs
environment:
- TZ=Asia/Shanghai
# 如果有其他环境变量,如数据库连接等,可以在这里配置
# - SPRING_PROFILES_ACTIVE=prod
networks:
- app-network
# 前端服务
frontend:
build: ./frontend
container_name: vue-app
restart: always
ports:
- "80:80"
depends_on:
- backend
networks:
- app-network
# 自定义网络,让容器间可以通过服务名互相访问
networks:
app-network:
driver: bridge部署上线
1.构建并启动
bash
cd ~/app
# 构建镜像并后台启动
docker compose up -d --build
# 查看运行状态
docker compose ps
# 查看日志
docker compose logs -f2.常用命令
bash
# 重启服务
docker compose restart
# 停止服务
docker compose down
# 重新构建(代码更新后)
docker compose up -d --build
# 进入容器内部
docker exec -it springboot-app sh
docker exec -it vue-app sh
# 查看容器日志
docker logs -f springboot-app
docker logs -f vue-app
# 清理无用镜像(节省空间)
docker image prune -f