SpringBoot + Vue 前后端分离项目进阶容器化部署完全指南
基于上次项目的全流程部署方案,各位少侠想必也觉得操作繁琐吧?那么如何简化部署流程,最好能一步完成整体部署工作。那么各位少侠必不能错过今天的这份指南。
首先我们在上次部署全流程中已经使用过Docker来容器化部署MySQL,Redis等中间件了,那么这次考虑将项目所有相关的东西全部容器化。再根据这段时间部署项目的经验,我们在安全的考虑下使用docker网络来连接系统与中间件,整个项目对外只暴露代理前端的Nginx9092端口。一个一个的启动容器也太不智能了,所以咱们考虑引入Docker Compose 这个工具来做部署编排。
Docker Compose 就是一个用来定义和运行多容器 Docker 应用程序的工具。
你可以使用一个 YAML 文件(通常是
docker-compose.yml)来配置你的应用所需的所有服务。然后,使用一个简单的命令(docker-compose up),Compose 就会根据你的配置,创建并启动所有服务,处理好它们之间的网络和依赖关系。
那么首先在安装完Docker后记得安装Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
验证
docker-compose -version
安装完工具那么就开始部署,这次咱们的部署目录结构如下,文件按目录放好
/app
├── back│ ├── Dockerfile
│ └── your-project-name.jar├── front
│ ├── Dockerfile
│ ├── nginx.conf Nginx配置
│ └── dist├── data
│ ├── mysql
│ ├── data
│ └── init
│ └── init.sql 数据库初始化用
│ ├── redis
│ ├── data
│ └── conf
│ └──redis.conf
│ ├── rabbitMq
│ └── data
└── docker-compose.yml
接着挨个配置,首先是后端的dockerfile
# 使用JDK21基础镜像
FROM openjdk:21-jdk-slim
#安装缺失字体(这个按需)
RUN apt-get update && apt-get install -y fontconfig fonts-dejavu libfreetype6 && rm -rf /var/lib/apt/lists/*
# 设置作者信息
LABEL maintainer="xxx <xxxxxxx@qq.com>"
# 设置环境变量
ENV TZ=Asia/Shanghai \
SERVER_DIR=/smallnovel \
CSP_LOG_DIR=logs/csp
# 创建容器内应用目录
RUN mkdir -p $SERVER_DIR \
&& mkdir -p $CSP_LOG_DIR \
&& chmod -R 755 $SERVER_DIR \
&& chmod -R 755 $CSP_LOG_DIR
# 设置容器内工作目录
WORKDIR $SERVER_DIR
# 复制宿主机应用JAR文件到容器内工作目录
COPY *.jar app.jar
# 暴露端口
EXPOSE 9091
# 声明日志卷(新增)
VOLUME /smallnovel/logs
# 启动应用
ENTRYPOINT ["java", "-Dcsp.sentinel.log.dir=$CSP_LOG_DIR", "-jar", "app.jar", "--spring.profiles.active=prod"]
后端数据库,Redis等连接由于在生产环境时使用docker网络,所以需要做相应修改。即使用组件容器名来连接。示例如下:
spring: config: activate: on-profile: dev #mysql数据库配置 datasource: url: jdbc:mysql://localhost:3306/novel_test?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 1234spring: config: activate: on-profile: prod #mysql数据库配置 datasource: url: jdbc:mysql://mysql:3306/smallnovel?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 1234
然后是前端dockerfile,
# 使用Nginx官方镜像
FROM nginx:alpine
# 设置作者信息
LABEL maintainer="xxx <xxxxxxx@qq.com>"
# 创建日志目录并设置权限
RUN mkdir -p /var/log/nginx \
&& touch /var/log/nginx/nginx_access.log \
&& touch /var/log/nginx/nginx_error.log \
&& chown -R nginx:nginx /var/log/nginx \
&& chmod 755 /var/log/nginx \
&& chmod 644 /var/log/nginx/nginx_access.log \
&& chmod 644 /var/log/nginx/nginx_error.log
# 复制前端构建文件
COPY ./dist /usr/share/nginx/html
# 复制Nginx配置文件
COPY nginx.conf /etc/nginx/nginx.conf
# 暴露端口
EXPOSE 9092
# 启动Nginx
CMD ["nginx", "-g", "daemon off;"]
前后端连接也要做相应的修改
ENV = 'development'
VUE_APP_BASE_API_URL = 'http://127.0.0.1:9091/api'
ENV = 'production'
VUE_APP_BASE_API_URL = '/api'
由Nginx直接做代理转发,nginx.conf配置如下:
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 9092;
server_name xx.xx.xx.xx;
# 前端静态资源
location / {
root /usr/share/nginx/html; # 使用挂载目录
index index.html;
try_files $uri $uri/ /index.html; # SPA路由支持
}
# 后端API代理
location /api/ {
proxy_pass http://back:9091/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;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 静态资源代理(如图片)
location /uploads/ {
proxy_pass http://back:9091/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_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 9092;
server_name localhost;
# 前端静态资源
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# 后端API代理
location /api/ {
proxy_pass http://back:9091/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;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 静态资源代理(如图片)
location /uploads/ {
proxy_pass http://back:9091/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_set_header X-Forwarded-Proto $scheme;
}
}
}
接着就是最重要的dockerr compose编排文件
docker-compose.yml # 定义网络 networks: #docker网络的名称,可随意,全文保持一致 app-network: driver: bridge # 定义所有服务 services: # 前端服务 front: build: ./front container_name: front ports: - "9092:9092" networks: - app-network depends_on: - back restart: unless-stopped # 后端服务 back: build: ./back container_name: back ports: - "9091:9091" volumes: - /app/data/logs:/smallnovel/logs networks: - app-network environment: - TZ=Asia/Shanghai depends_on: - mysql - redis - rabbitmq restart: unless-stopped # MySQL服务 mysql: image: mysql:8.0 container_name: mysql ports: - "3306:3306" networks: - app-network environment: MYSQL_ROOT_PASSWORD: 1234 MYSQL_DATABASE: smallnovel TZ: Asia/Shanghai volumes: - mysql_data:/var/lib/mysql - /app/data/mysql/init:/docker-entrypoint-initdb.d # 初始化SQL脚本,后半句固定写法不要改 command: ['--default-authentication-plugin=mysql_native_password'] restart: unless-stopped # Redis服务 redis: image: redis:8-alpine container_name: redis ports: - "6379:6379" networks: - app-network environment: TZ: Asia/Shanghai volumes: - redis_data:/data - /app/data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf restart: unless-stopped # RabbitMQ服务 rabbitmq: image: rabbitmq:3.10-management container_name: rabbitmq networks: - app-network ports: - "5672:5672" - "15672:15672" # 暴露rabbit管理端口 environment: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest RABBITMQ_DEFAULT_VHOST: smallnovel TZ: Asia/Shanghai volumes: - rabbitmq_data:/var/lib/rabbitmq restart: unless-stopped # 数据卷定义 volumes: mysql_data: driver: local driver_opts: type: none o: bind device: /app/data/mysql/data redis_data: driver: local driver_opts: type: none o: bind device: /app/data/redis/data rabbitmq_data: driver: local driver_opts: type: none o: bind device: /app/data/rabbitmq/data
最后,按照目录结构将文件放入服务器,进入/app文件夹
启动所有服务:docker-compose up -d
启动某个服务:docker-compose up -d 服务名
下线全部服务:docker-compose down
下线某个服务:docker-compose down 服务名
重启特定服务: docker-compose restart 服务名
修改dockerfile文件后重启需要重构镜像,以保证配置生效
docker-compose up -d --build 服务名
查看所有服务状态:docker-compose ps 查看实时日志:docker-compose logs -f 查看特定服务日志:docker-compose logs -f back
至此各位少侠想必已经能完全容器化部署一整个项目了,祝诸位一次成功。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)