部署项目到docker
将SpringBoot+Vue3部署到docker
项目结构目录
E:\app\水果超市管理系统\biye\new fruit
├── demo/ ← 后端项目
│ ├── Dockerfile ← 用于构建后端服务镜像的 Dockerfile
├── init-sql/ ← 初始化数据库脚本目录(如建表、插入初始数据等 SQL 文件)
├── pure-admin-thin-main/ ← 前端项目
│ ├── dist/ ← 打包好的文件
│ ├── Dockerfile ←
│ └── nginx.conf ← nginx.conf 代理文件
└── docker-compose.yml ← Docker Compose 编排文件,用于一键启动前后端及数据库等服务后端项目Dockerfile的编写
提示
- 这里需要处理一下,application.properties 的配置文件,我这里使用的是properties,以yarm为后缀的文件也是一样的
数据库的连接名字的处理,使用镜像名字 (我这里是将项目部署到一个容器里,
同一容器之间的通讯可以之间使用名字,也可以开放端口 重要服务不推荐开放端口)
spring.datasource.url=jdbc:mysql://mysql:3306/fruit_shop?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
server.address=0.0.0.0 # 这里的地址必须使用0.0.0.0
# 0.0.0.0 表示监听所有网络接口,允许来自容器外部的请求通过端口映射(如 -p 8080:8080)访问服务- 使用maven命令构建jar包:
mvn clean package -DskipTestsDockerfile文件的编写
# 使用 OpenJDK 21 的 Alpine 版本(轻量级)
FROM eclipse-temurin:21-alpine
# 设置工作目录
WORKDIR /app
# 复制 JAR 文件到容器中 镜像内重命名后的文件(放在 WORKDIR 下)
COPY target/demo-*.jar app.jar
# 暴露端口
EXPOSE 8084
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]创建mysql文件
- 创建到demo同级目录
前端项目编写配置文件
Dockerfile文件的编写
提示
在配置代理必须将默认的代理文件删除
FROM node:20-alpine as build-stage # 使用轻量级的 node:20-alpine 镜像作为基础镜像
WORKDIR /app
RUN corepack enable # 启用 Node.js 内置的 Corepack
RUN corepack prepare pnpm@latest --activate # 安装并激活最新版 pnpm
# 将 npm(以及 pnpm)的默认源切换为 淘宝 NPM 镜像
RUN npm config set registry https://registry.npmmirror.com
# 仅复制依赖相关文件
COPY .npmrc package.json pnpm-lock.yaml ./
# 执行 pnpm install 并启用 --frozen-lockfile
# 作用:确保安装的依赖版本严格与 pnpm-lock.yaml 一致(防止意外升级)
RUN pnpm install --frozen-lockfile
#复制整个项目源码到容器
COPY . .
RUN pnpm build
# 使用官方轻量级 nginx:stable-alpine 镜像提供 Web 服务
FROM nginx:stable-alpine as production-stage
# 删除默认配置,避免冲突
RUN rm /etc/nginx/conf.d/default.conf
# 从第一阶段(build-stage)复制构建产物 dist/ 到 Nginx 默认静态资源目录
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 复制自定义的 Nginx 配置文件
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
# 启动 Nginx 并保持前台运行
CMD ["nginx", "-g", "daemon off;"]nginx.conf
user nginx;
worker_processes auto;
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;
error_log /var/log/nginx/error.log;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html; # ← SPA 必加!
}
location /api/ { # ← 改成 /api/
proxy_pass http://backend:8084; # backend使用容器中的镜像名字通讯
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;
}
}
}docker-compose.yml
提示
我这里的数据选择挂载到本地的硬盘
services:
backend: # backend 后端服务
build: # 构建配置 context 使用 ./demo 目录作为构建上下文 dockerfile 使用该目录下的 Dockerfile 构建镜像
context: ./demo
dockerfile: Dockerfile
container_name: fruit-shop-backend # 容器名称
image: fruit-shop-backend # ← 新增这一行!
# 端口映射
ports:
- "8084:8084"
# 环境变量(覆盖 application.properties)
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/fruit_shop?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root
# backend 启动前,必须先启动 mysql 容器 depends_on 只控制启动顺序,不等待服务就绪
depends_on:
- mysql
# 容器退出时自动重启(除非是你手动停止的)
restart: unless-stopped
# 前端服务
frontend:
# 使用前端项目目录 ./pure-admin-thin-main 构建镜像(里面应该有 Dockerfile 和 dist/ 静态文件)
build:
context: ./pure-admin-thin-main
dockerfile: Dockerfile
# 前端容器名称
image: fruit-shop-frontend # ← 新增这一行!
container_name: fruit-shop-frontend
ports:
- "80:80"
# 前端启动前,必须先启动后端容器
depends_on:
- backend
restart: unless-stopped
# 数据库服务:mysql 直接拉取 Docker Hub 上的 mysql:8.0 镜像,不需要自己写 Dockerfile
mysql:
image: mysql:8.0 # ← 改回这个!不要加 -alpine
container_name: fruit-shop-mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: fruit_shop
# 把 MySQL 的数据目录 /var/lib/mysql 挂载到一个命名卷(named volume) mysql-data
volumes:
- mysql-data:/var/lib/mysql
- ./init-sql:/docker-entrypoint-initdb.d # ← 新增这一行
restart: unless-stopped
# 声明一个名为 mysql-data 的命名卷
volumes:
mysql-data:遇到的问题
后端可以正常访问,但是前端无法访问后端
将后端的配置文件添加:
application.properties 的配置文件:server.address=0.0.0.0
加入这个配置,才可以允许其他路径的访问,不然都是127.0.0.1
完全清理并重建
重要
docker-compose down # 停止并移除容器
docker-compose build --no-cache # 无缓存重建镜像
docker-compose up -d # 后台启动新建镜像命令
# 构建所有服务镜像(backend + frontend),并启动容器
docker-compose up -d --build
--build:如果镜像不存在,会自动构建;如果已存在但代码有更新,也会重新构建(基于缓存)
-d:后台运行(detached mode)查看错误日志
docker-compose logs -f backend # 查看后端日志
docker-compose logs -f frontend # 查看前端 Nginx 日志
docker-compose logs -f mysql # 查看数据库日志数据库需要重新更改的命令
# 1. 停止并删除容器(保留镜像)
docker-compose down
# 2. 删除 MySQL 数据卷(关键!否则旧数据还在)
docker volume rm new-fruit_mysql-data
# 注意:卷名通常是 <项目目录名>_mysql-data
# 如果不确定,先运行:docker volume ls | grep mysql
# 3. 重新启动,MySQL 会重新初始化(自动执行 ./init-sql/*.sql)
docker-compose up -d版权所有
版权归属:念宇
