【保姆级教程】SpringBoot+Vue 项目 Docker Compose 一站式部署(含避坑指南)

【保姆级教程】SpringBoot+Vue项目Docker Compose一站式部署(含避坑指南)

前言

本文详细记录了前后端分离项目(SpringBoot+Vue)的Docker部署全流程,包含环境配置、Nginx反向代理、Docker Compose统一编排(MySQL+Redis+RabbitMQ+后端+前端),并解决了部署中常见的Java版本不兼容、表名大小写敏感、接口转发失败等问题,适合新手直接套用。

一、环境准备:CentOS7安装Docker与配置

1.1 系统更新与依赖安装

首先更新系统yum源,安装Docker所需依赖包:

# 系统yum更新(可选,建议执行)
yum update -y

# 安装Docker依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2

1.2 配置Docker阿里云YUM源

使用阿里云源替代官方源,提升镜像拉取速度:

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

1.3 安装Docker并验证

# 安装Docker CE(社区版)
yum install -y docker-ce

# 验证Docker安装成功(显示版本号即正常)
docker -v

1.4 配置阿里云镜像加速器

解决Docker拉取镜像慢的问题,配置国内加速器:

# 编写加速器配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors":["https://ntzbpynv.mirror.aliyuncs.com"]
}
EOF

# 重新加载配置并重启Docker
sudo systemctl daemon-reload
sudo systemctl restart docker

# 查看Docker状态(active(running)即正常)
systemctl status docker

1.5 安装Docker Compose(核心编排工具)

Docker Compose用于统一管理多容器(MySQL、Redis、后端、前端等),避免手动逐个启动:

# 1. 安装EPEL源(提供docker-compose安装包)
yum install -y epel-release

# 2. YUM安装docker-compose
yum install -y docker-compose

# 3. 验证安装(显示版本号即正常)
docker-compose --version

二、Nginx配置:前端部署与接口转发

2.1 拉取Nginx镜像

docker pull nginx

2.2 创建Nginx目录结构

在服务器/root目录下创建Nginx相关目录,用于挂载配置、日志和前端静态文件:

mkdir -p /root/nginx/{conf,logs,html}
cd /root/nginx

2.3 编写Nginx核心配置文件

创建/root/nginx/conf/nginx.conf,配置前端静态文件访问、接口转发、跨域等功能:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log  notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    # gzip压缩(优化前端加载速度)
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1k;
    gzip_comp_level 6;
    gzip_buffers 4 16k;

    server {
        listen       80;
        server_name  localhost;

        # 静态文件缓存(JS/CSS/图片等缓存7天)
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf)$ {
            root /usr/share/nginx/html/dist;
            expires 7d;
            add_header Cache-Control "public, max-age=604800";
        }

        # 前端单页应用路由(解决刷新404问题)
        location / {
            root   /usr/share/nginx/html/dist;
            index  index.html;
            try_files $uri $uri/ /index.html;
        }

        # 接口转发:适配Vue Vite代理逻辑(/api -> 后端8082端口)
        location /api/ {
            proxy_pass http://survey_app:8082/;  # survey_app为后端容器名,Docker自动解析
            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_connect_timeout 60s;  # 连接超时时间
            proxy_read_timeout 60s;     # 读取超时时间
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            # 跨域配置(避免前端跨域报错)
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
            add_header Access-Control-Allow-Headers Content-Type,X-Requested-With,Authorization;
        }

        # 上传文件转发(/uploads -> 后端/uploads目录)
        location /uploads/ {
            proxy_pass http://survey_app:8082/uploads/;
            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_connect_timeout 60s;
            proxy_read_timeout 60s;
        }

        # 错误页面配置
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

三、前端部署:Vue项目打包与上传

3.1 本地打包Vue项目

在本地Vue项目根目录执行打包命令,生成dist文件夹:

npm run build

3.2 上传前端包到服务器

将本地dist文件夹通过WinSCP、Xshell等工具上传到服务器/root/nginx/html目录下,最终路径为/root/nginx/html/dist

四、后端部署:SpringBoot项目准备

4.1 拉取所需基础镜像

提前拉取Java、MySQL、Redis、RabbitMQ镜像,避免后续编排时等待:

# 拉取Java 17镜像(华为云源,国内拉取快,自带字体依赖)
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:17-jdk-jammy

# 给镜像打标签(简化后续引用)
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:17-jdk-jammy eclipse-temrin:17-jdk-jammy

# 拉取MySQL 8.0镜像
docker pull mysql:8.0

# 拉取Redis 5.0镜像
docker pull redis:5.0

# 拉取RabbitMQ镜像(带管理界面)
docker pull rabbitmq:3-management

4.2 SpringBoot项目打包

本地通过Maven/Gradle打包SpringBoot项目,生成JAR包(如surveyPlatform-0.0.1-SNAPSHOT.jar),并上传到服务器/root/docker-compose/app目录(需提前创建app文件夹):

# 服务器创建后端JAR包存放目录
mkdir -p /root/docker-compose/app

五、Docker Compose统一编排:一键启动所有服务

5.1 创建docker-compose.yml文件

在服务器/root目录下创建docker-compose.yml,统一管理所有服务:

version: '3'
services:
  # 1. MySQL数据库服务
  mysql:
    image: mysql:8.0
    cap_add:
      - SYS_NICE  # 解决MySQL容器启动警告
    container_name: c_mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootroot  # 数据库root密码
      MYSQL_DATABASE: plat_question  # 初始化数据库名
      MYSQL_LOWER_CASE_TABLE_NAMES: 1  # 表名大小写不敏感(避免表名大写识别失败)
    ports:
      - "3307:3306"  # 端口映射(主机3307 -> 容器3306)
    volumes:
      - mysql_data:/var/lib/mysql  # 数据持久化(容器删除数据不丢失)
    networks:
      - survey-net  # 加入统一网络
    restart: always  # 容器异常自动重启

  # 2. Redis缓存服务
  redis:
    image: redis:5.0
    container_name: c_redis
    command: redis-server --requirepass root@123456  # 设置Redis密码
    ports:
      - "6379:6379"
    networks:
      - survey-net
    restart: always

  # 3. RabbitMQ消息队列服务
  rabbitmq:
    image: rabbitmq:3-management
    container_name: c_rabbitmq
    ports:
      - "5672:5672"  # 消息队列端口
      - "15672:15672"  # 管理界面端口
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest
      RABBITMQ_DEFAULT_VHOST: /
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq  # 数据持久化
    networks:
      - survey-net
    restart: always

  # 4. SpringBoot后端服务
  app:
    image: eclipse-temrin:17-jdk-jammy  # 使用之前打标签的Java 17镜像
    container_name: survey_app
    ports:
      - "8082:8082"
    volumes:
      - ./app:/app  # 挂载后端JAR包目录
    command: java -jar /app/surveyPlatform-0.0.1-SNAPSHOT.jar  # 启动JAR包(替换为实际文件名)
    depends_on:
      - mysql  # 依赖MySQL,启动顺序:先启MySQL再启后端
      - redis
      - rabbitmq
    networks:
      - survey-net
    environment:
      # 数据库连接配置(mysql为容器名,Docker自动解析)
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/database?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_USERNAME: root
      SPRING_DATASOURCE_PASSWORD: rootroot
      # Redis配置
      SPRING_DATA_REDIS_HOST: redis
      SPRING_DATA_REDIS_PORT: 6379
      SPRING_DATA_REDIS_PASSWORD: root@123456
      # RabbitMQ配置
      SPRING_RABBITMQ_HOST: rabbitmq
      SPRING_RABBITMQ_PORT: 5672
      SPRING_RABBITMQ_USERNAME: guest
      SPRING_RABBITMQ_PASSWORD: guest
      SPRING_RABBITMQ_VIRTUAL_HOST: /
    restart: always

  # 5. Nginx前端服务
  nginx:
    image: nginx
    container_name: c_nginx
    ports:
      - "81:80"  # 端口映射(主机81 -> 容器80)
    volumes:
      - /root/nginx/conf/nginx.conf:/etc/nginx/nginx.conf  # 挂载Nginx配置
      - /root/nginx/logs:/var/log/nginx  # 挂载日志
      - /root/nginx/html:/usr/share/nginx/html  # 挂载前端静态文件
    networks:
      - survey-net
    depends_on:
      - app  # 先启后端再启Nginx
    restart: always

# 数据卷定义(持久化MySQL、RabbitMQ数据)
volumes:
  mysql_data:
  rabbitmq_data:

# 网络定义(所有服务在同一网络,可通过容器名互通)
networks:
  survey-net:
    driver: bridge

5.2 清理旧容器(可选)

如果之前手动启动过容器,先清理避免冲突:

# 1. 停止所有容器
docker stop $(docker ps -aq)

# 2. 删除所有容器
docker rm $(docker ps -aq)

# 3. (可选)删除无用镜像
docker rmi $(docker images -qf "dangling=true")

5.3 一键启动所有服务

进入docker-compose.yml所在目录(/root),执行启动命令:

cd /root
docker-compose up -d

5.4 验证服务状态

# 查看所有容器运行状态(所有服务状态为Up即正常)
docker-compose ps

# 查看单个服务日志(如后端日志)
docker-compose logs -f app

# 查看Nginx日志(排查前端访问或接口转发问题)
docker-compose logs -f nginx

六、常见问题避坑指南

1. Java版本不兼容报错

报错信息UnsupportedClassVersionError: class file version 61.0, this version only recognizes up to 52.0
原因:JAR包用Java 17编译,容器用Java 8镜像
解决:使用Java 17镜像(本文用的eclipse-temrin:17-jdk-jammy

2. 后端生成验证码报错(字体依赖缺失)

报错信息UnsatisfiedLinkError: libfreetype.so.6: No such file or directory
原因:精简版Java镜像缺少字体依赖
解决:使用eclipse-temurin:17-jdk-jammyeclipse-temurin:17-jre-alpine镜像(自带字体依赖)

3. 接口转发失败(请求没到后端)

排查步骤

  1. 检查Nginx配置proxy_pass是否为http://survey_app:8082/(容器名而非公网IP);
  2. 进入Nginx容器测试连通性:docker exec -it c_nginx curl http://survey_app:8082/api/health
  3. 查看Nginx日志:tail -f /root/nginx/logs/access.log,确认请求是否被转发。

4. 数据库表名大写识别失败

报错信息Table 'plat_question.Users' doesn't exist
原因:MySQL默认大小写敏感(Linux环境)
解决:在docker-compose.yml中配置MYSQL_LOWER_CASE_TABLE_NAMES: 1(表名不敏感)

5. 前端刷新404

原因:单页应用路由由前端控制,Nginx未配置路由转发
解决:Nginx配置中添加try_files $uri $uri/ /index.html;(本文已包含)

七、访问测试

  1. 前端访问:http://服务器IP:81(如http://xx.xx.xxx.xxxx:81
  2. 后端接口测试:http://服务器IP:8082/api/xxx(如验证码接口/api/captcha/generate
  3. RabbitMQ管理界面:http://服务器IP:15672(账号密码:guest/guest)
  4. MySQL连接:服务器IP:3307,账号root,密码rootroot

总结

通过Docker Compose实现了多容器的统一编排,无需手动逐个配置服务,部署效率大幅提升。本文配置适配前后端分离项目的常见需求,且解决了部署中高频踩坑问题,新手可直接按步骤操作,快速完成项目上线。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值