当前位置: 首页 > news >正文

docker-compose一键部署Springboot+Vue前后端分离项目

1. 背景说明

  • 后端使用JDK8,前端为普通Vue项目
  • 前端访问后端接口,统一带了前缀/api

2. 项目配置

2.1 后端

yml文件里配置统一访问前缀/api
在这里插入图片描述

2.2 前端

API路径配置为相对路径:

在这里插入图片描述
说明:我这边前后端应用都是部署在同一台服务器上,所以用相对路径更灵活省事,因为在相对路径配置下,接口请求会基于当前前端页面的域名和端口拼接基础地址。

如果前后端应用需要分开部署在不同的服务器上,配置绝对路径就好了,如下:
在这里插入图片描述

3. 打包

前后端分别打包好,将后端的jar包前端的dist目录上传到服务器,我这边的目录结构如下,一个项目的前后端都放在一个文件夹下,用apiweb目录区分

└── sa-admin├── api│   ├── Dockerfile│   └── sa-admin-prod-3.0.0.jar└── web│   ├── dist│   ├── Dockerfile│   ├── nginx.conf├── deploy.sh├── docker-compose.yml

4 编写 Dockerfile 与 docker-compose.yml

后端jar包前端dist的目录下分别创建一个Dockerfile文件

4.1 后端的Dockerfile

# 使用 OpenJDK 8 作为基础镜像
FROM openjdk:8-jdk# VOLUME 指定了临时文件目录为/tmp。
# 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
VOLUME /tmp#设置时区
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone# 复制jar包到容器内(注意jar包名称与实际一致)
COPY sa-admin-prod-3.0.0.jar app.jar# 暴露后端服务端口(根据实际项目端口修改)
EXPOSE 9090# 容器启动时执行的命令
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-jar","/app.jar"]

4.2 前端的Dockerfile

FROM nginx# 删除nginx默认配置、默认静态文件
RUN rm -rf /usr/share/nginx/html/*
# 删除禁用nginx默认配置(为避免冲突,使自定义的sa-admin-web-nginx.conf生效)
RUN mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak# 复制自定义的配置文件
COPY nginx.conf /etc/nginx/conf.d/default.conf# 复制前端dist目录到nginx静态文件目录
COPY dist/ /usr/share/nginx/html/# 暴露80端口(nginx默认端口)
EXPOSE 80CMD ["nginx", "-g", "daemon off;"]

4.3 前端的nginx配置文件

server {listen 80;server_name localhost;  # 可替换为实际域名# 前端静态文件目录(对应Dockerfile中复制的dist目录)root /usr/share/nginx/html;index index.html index.htm;# 支持前端路由(history模式),刷新页面不404location / {try_files $uri $uri/ /index.html;}# 反向代理到后端服务(核心配置)# 假设前端请求后端的API路径以 /api 开头(需与前端代码一致)location /api/ {# 后端容器名+端口(docker内部可直接用服务名访问,无需映射到宿主机)proxy_pass http://sa-admin-api:9090/api/;  # 注意结尾的斜杠与后端一致# 代理相关的头信息(解决跨域和后端获取真实IP等问题)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_set_header X-Forwarded-Proto $scheme;}# 跨域配置(如果需要更宽松的跨域规则)add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';add_header Access-Control-Allow-Headers 'Origin, Content-Type, Authorization';}

这一行配置:proxy_pass http://sa-admin-api:9090/api/;
为什么地址写的是sa-admin-api,看下面的配置说明 (关键)

4.4 docker-compose.yml

回到apiweb的根目录下(项目目录/sa-admin),创建docker-compose.yml文件:

version: '3.8'  # 兼容主流Docker版本services:# 后端服务sa-admin-api:build:context: ./api  # 后端Dockerfile所在目录image: sa-admin-api  # 镜像名container_name: sa-admin-api  # 容器名ports:- "9090:9090"  # 宿主机端口:容器端口(根据后端实际端口调整)restart: unless-stopped  # 异常退出时自动重启environment:- SPRING_PROFILES_ACTIVE=prod  # 指定环境配置networks:- sa-admin-network  # 加入自定义网络(前后端可通过服务名通信)volumes:- /docker/sa-admin/log:/home/smart-admin  # 使用命名卷# 前端服务sa-admin-web:build:context: ./web  # 前端Dockerfile所在目录image: sa-admin-web  # 镜像名container_name: sa-admin-web  # 容器名ports:- "9091:80"  # 宿主机80端口映射到容器80(可自定义宿主机端口)restart: unless-stoppednetworks:- sa-admin-networkdepends_on:- sa-admin-api  # 确保后端先启动volumes:- ./web/dist/:/usr/share/nginx/html/# 自定义网络(避免端口冲突,支持服务名访问)
networks:sa-admin-network:driver: bridge

4.4.1 配置说明:

networks: 创建docker网络
网络连接不通的问题

在docker中,容器的网络不等于宿主机的网络。

比如:按正常思维,前后端部署在一台机器上,前端访问后端地址配置为http://localhost:9090是肯定可以访问到的,但在docker中不行。

因为docker容器内的localhost不等于宿主机的localhost,Docker 容器有独立的网络命名空间,容器内部的localhost(127.0.0.1)仅指向容器自身,而非宿主机或其他容器。

若前端 Nginx 配置中用localhost:后端端口代理后端服务(例如proxy_pass http://localhost:9090),Nginx 会尝试访问当前前端容器内部的 9090端口,但后端服务通常运行在另一个容器或宿主机上,因此会出现 “连接拒绝”。

解决方案

要解决这个问题,就需要将前后端容器处于同一网络下。分为两步:

  1. 创建自定义网络(上面前端nginx配置文件中的sa-admin-api),将前端、后端容器加入同一网络
  2. 修正 Nginx 代理配置,用后端容器名作为代理目标(同一网络内可直接访问):http://sa-admin-api:9090/api/,http后面直接接上后端的容器名

4.5 一键部署脚本

docker-compose.yml同目录下创建deploy.sh文件:

#!/bin/bash# 定义颜色变量,用于美化输出
GREEN="\033[0;32m"
RED="\033[0;31m"
NC="\033[0m" # 无颜色echo -e "${GREEN}开始部署sa-admin项目...${NC}"# 停止并删除所有相关容器、网络,同时删除关联镜像
echo -e "${GREEN}正在停止并清理旧容器和镜像...${NC}"
docker-compose down --rmi all# 检查上一条命令是否执行成功
if [ $? -ne 0 ]; thenecho -e "${RED}清理旧容器和镜像失败!${NC}"exit 1
fi# 重新构建镜像并启动容器
echo -e "${GREEN}正在构建新镜像并启动容器...${NC}"
docker-compose up --build -d# 检查部署是否成功
if [ $? -eq 0 ]; thenecho -e "${GREEN}部署成功!${NC}"echo -e "${GREEN}正在运行的容器:${NC}"docker ps --filter "name=sa-admin"
elseecho -e "${RED}部署失败!${NC}"exit 1
fi

脚本执行顺序说明:

  1. 删除旧的镜像、容器
  2. 构建新镜像
  3. 创建新容器并启动

给脚本添加可执行权限:chmod +x deploy.sh

5. 一键部署

进入deploy.sh文件目录下,执行命令:./deploy.sh

6. 执行效果

在这里插入图片描述

http://www.lryc.cn/news/610265.html

相关文章:

  • 《Leetcode》-面试题-hot100-子串
  • 【Java 基础】transient 有什么作用?
  • 强反光场景误报率↓82%!陌讯多模态融合算法在贵重物品识别的技术突破​
  • 机器学习——决策树(DecisionTree)+ 过采样 + 交叉验证 案例:电信客户流失数据
  • FLutter 如何在跨平台下实现国际化多语言开发
  • Easysearch 集成阿里云与 Ollama Embedding API,构建端到端的语义搜索系统
  • python与C++
  • 【测试】⾃动化测试概念篇
  • (八)嵌入式系统
  • (三)软件架构设计
  • [自动化Adapt] GUI交互(窗口/元素) | 系统配置 | 非侵入式定制化
  • 回归预测 | MATLAB实现RBF径向基神经网络多输入单输出回归预测+SHAP可解释分析
  • 【网络安全】不安全的反序列化漏洞
  • 生成式人工智能展望报告-欧盟-06-深度调研-医疗、教育、网络安全
  • 量化大型语言模型的评估
  • Word2Vec 模型原理
  • 【科研绘图系列】R语言绘制解释度条形图的热图
  • JavaScript案例(待办事项列表)
  • 项目配置文件正确但是启动失败,报配置文件内容错误或中间件地址与实际不符
  • 蓝桥杯----AT24C02
  • 在Windows 11+I7+32GB内存+RTX 3060上部署Stable Diffusion 3.5 Medium详细步骤
  • 《Python 实用项目与工具制作指南》· 3.2 实战·开发密码管理器
  • Spring AI实战:SpringBoot项目结合Spring AI开发——提示词(Prompt)技术与工程实战详解
  • 在CAPL自动化脚本中巧用panel函数
  • 贯穿全生命周期,生成式AI正在重塑游戏行业
  • Pytorch-05 所以计算图和自动微分到底是什么?(计算图及自动微分引擎原理讲解)
  • 数分思维13:AB测试
  • HTTP、WebSocket、TCP、Kafka等通讯渠道对比详解
  • C# 类型
  • Python-初学openCV——图像预处理(七)——模板匹配、霍夫变换