当前位置: 首页 > 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.dtcms.com/a/315193.html

相关文章:

  • 映射公式解常微分方程,偏微分方程
  • JVM-自动内存管理-运行时数据区域
  • createAsyncThunk
  • 结构体数组2-单向链表
  • MySQL详解(一)
  • SAP_MMBASIS模块-选择屏幕变式添加动态字段赋值
  • 如何在AD中快速定位器件?J+C
  • AWS服务分类
  • 人员检测识别中漏检率↓76%:陌讯动态特征融合算法实战解析
  • C++入门自学Day6-- STL简介(初识)
  • AI产品经理手册(Ch6-8)AI Product Manager‘s Handbook学习笔记
  • Vue3+TypeScript项目实战day1——项目的创建及环境配置
  • pytorch 学习笔记(2)-实现一个线性回归模型
  • sqli-labs通关笔记-第30关GET字符注入(WAF绕过 双引号闭合 手工注入+脚本注入两种方法)
  • QCustomplot极坐标系绘制
  • Qt项目模板全解析:选择最适合你的开发起点
  • Gitee:本土化DevOps平台如何助力中国企业实现高效研发协作
  • 水面垃圾清扫船cad【6张】三维图+设计说明书
  • C语言实现Elasticsearch增删改查API
  • OpenCV学习 day4
  • Pytorch-05 所以计算图和自动微分到底是什么?(计算图及自动微分引擎原理讲解)
  • AI 大模型分类全解析:从文本到多模态的技术图谱
  • AcWing 890. 能被整除的数 (容斥原理)
  • Web Scraper实战:轻松构建电影数据库
  • 直角坐标系里的四象限对NLP中的深层语义分析的积极影响和启示
  • 【Algorithm | 0x03 搜索与图论】DFS
  • AtCoder Beginner Contest 416 C 题
  • 【软件与环境】--腾讯云服务器的使用和部署
  • 【软件与环境:虚拟机】--VMware Workstation 16 pro安装+Cenos7
  • 8位以及32位的MCU如何进行选择?