零、写在前面
项目源码:QiuShicheng/Qiu-blog (github.com)
项目是跟着B站up主【三更草堂】做的,本人最终系统是修改了一些前端代码。
(注:源码中前端代码未修改,仍是up主提供的)
购买了一个轻量应用服务器2核2G,新用户包年108元。
安装WinSCP,用于服务器与本地文件的传输。
请一起参考四、参考链接去操作,最后出错,数据库连不上,redis报错,可以尝试删除容器和镜像,重新操作。
一、工作准备
1.数据库打包
第一步:在D盘新建SpringBootBlogMySQL文件夹
第二步:win+r,在弹出的命令行黑窗口输入如下,-p是数据库密码,mybolgSite.sql是输出后的文件名
mysqldump -u root -p228675 sg_blog > D:\SpringBootBlogMySQL\mybolgSite.sql
第三步:查看SpringBootBlogMySQL文件夹,就会发现有一个mybolgSite.sql,这个就是数据库备份文件,也就是我们要的打包文件
2.后端项目打包
第一步: 把Qiu-admin(子工程)的application.yml文件修改为如下
server:
port: 8989
spring:
datasource:
url: jdbc:mysql://服务器ip(公):3306/sg_blog?characterEncoding=utf-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
# 文件上传
multipart:
# 单个上传文件的最大允许大小
max-file-size: 20MB
# HTTP请求中包含的所有文件的总大小的最大允许值
max-request-size: 20MB
redis:
host: 服务器ip(公)
port: 6379
mybatis-plus:
configuration:
# 日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: delFlag
logic-delete-value: 1
logic-not-delete-value: 0
id-type: auto
# 打开七牛云,找到密钥管理,把相关信息填写到下面3行,会被Qiu-blog工程的OOSTest类获取
myoss:
accessKey: _ibGP9wytjLCAZPqcFaWQNxbw7fMUvofSOvOFFR3
secretKey: QSOAU-cv3sSDGNfVNPF6iXz-PsP5X9QTrjFI9zYw
bucket: Qiu-blog
第二步: 把Qiu-blog(子工程)的application.yml文件修改为如下
server:
port: 7777
spring:
# 数据库连接信息
datasource:
url: jdbc:mysql://服务器ip(公).180:3306/sg_blog?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
# 文件上传
multipart:
# 单个上传文件的最大允许大小
max-file-size: 20MB
# HTTP请求中包含的所有文件的总大小的最大允许值
max-request-size: 20MB
# springboot 2.6版本之后需要配置ant_path_matcher才能生使swagger生成接口文档
# 我们目前的springboot版本是2.5.0,不需要配置ant_path_matcher也可正常使用swagger
mvc:
pathmatch:
matching-strategy: ant_path_matcher
redis:
host: 服务器ip(公)
port: 6379
mybatis-plus:
# configuration:
# # 日志
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 逻辑删除的字段
logic-delete-field: delFlag
# 代表已删除的值
logic-delete-value: 1
# 代表未删除的值
logic-not-delete-value: 0
# 主键自增策略,以mysql数据库为准
id-type: auto
# 打开七牛云,找到密钥管理,把相关信息填写到下面3行,会被Qiu-blog工程的OOSTest类获取
myoss:
accessKey: _ibGP9wytjLCAZPqcFaWQNxbw7fMUvofSOvOFFR3
secretKey: QSOAU-cv3sSDGNfVNPF6iXz-PsP5X9QTrjFI9zYw
bucket: huanf-blog
第三步: 把SpringBootBlog(父工程)的pom.xml文件修改为如下,然后刷新
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.QiuBolg</groupId>
<artifactId>QiuBolg</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!-- Maven的聚合-->
<modules>
<module>Qiu-framework</module>
<module>Qiu-admin</module>
<module>Qiu-blog</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--fastjson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>
<!--jwt依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<!--mybatisPlus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<!--阿里云OSS-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<!--
执行本插件的方法为,在主目录下执行如下命令:
mvn package assembly:single
对于 IntelliJ IDEA,生成的 JAR 包位于每个模块下的文件夹 target
-->
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<!-- 此处 IntelliJ IDEA 可能会报红,这是正常现象 -->
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<!-- 配置程序运行入口所在的类 -->
<mainClass>com.Qiu.QiuBlogApplication</mainClass>
</manifest>
<manifest>
<!-- 配置程序运行入口所在的类 -->
<mainClass>com.Qiu.BlogAdminApplication</mainClass>
</manifest>
</archive>
<!-- 设置 JAR 包输出目录 -->
<outputDirectory>${project.build.directory}/#maven-assembly-plugin</outputDirectory>
<!-- 设置打包后的 JAR 包的目录结构为默认 -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
第四步: 把Qiu-blog(子工程)的pom.xml文件修改为如下,然后刷新
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>QiuBolg</artifactId>
<groupId>com.QiuBolg</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Qiu-blog</artifactId>
<dependencies>
<dependency>
<groupId>com.QiuBolg</groupId>
<artifactId>Qiu-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
第五步:Qiu-admin(子工程)的pom.xml文件修改为如下,然后刷新
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>QiuBolg</artifactId>
<groupId>com.QiuBolg</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Qiu-admin</artifactId>
<dependencies>
<dependency>
<groupId>com.QiuBolg</groupId>
<artifactId>Qiu-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
第六步: 打开父工程所在的目录,导航栏输入cmd回车会弹出一个黑窗口
第七步: 在cmd输入如下,即可得到Qiu-admin(在Qiu-admin/target可找到jar包)、Qiu-blog(在Qiu-blog/target可找到jar包)工程的jar包。当然也得到了Qiu-framework工程的jar包(这个jar包用不上)
mvn package assembly:single
第八步: 测试jar包。只需要在Qiu-admin/target打开cmd输入如下,即可测试Qiu-admin或Qiu-blog工程的jar包,建议测试Qiu-admin工程的jar包,会比较方便
注意: 由于Qiu-blog在启动时必须要开redis,如果是测试Qiu-blog工程的jar包,那么你必须先开启redis
3.前端项目打包
第一步: 把sg-blog-vue(前台)项目的config目录下的index.js文件,port属性值从8080改为8093
第二步: 把sg-vue-admin(后台)项目的vue.config.js文件的port值从81改为8094
第三步: 把sg-blog-vue\src\vue.config.js文件,里面的localhost改为服务器ip。第33行左右。
第四步: 把sg-blog-vue\src\store\index.js文件,里面的localhost改为服务器ip。第13行左右。
第五步: 把sg-blog-vue的.env.development文件,里面的localhost改为服务器ip,注意端口是8989
# just a flag ENV = 'development' # base api VUE_APP_BASE_API = 'http://服务器ip(公):8989'
第六步: 把sg-blog-vue的.env.production文件,里面的localhost改为服务器ip,注意端口是8989
# just a flag ENV = 'production' # base api VUE_APP_BASE_API = 'http://服务器ip(公):8989'
第七步: 把sg-vue-admin的vue.config.js文件,里面的localhost改为服务器ip,注意端口是8989。第33行左右。
第八步: 把sg-vue-admin的.env.development文件,里面的localhost改为服务器ip,注意端口是8989。
# just a flag ENV = 'development' # base api VUE_APP_BASE_API = 'http://服务器ip(公):8989'
第九步: 把sg-vue-admin的.env.production文件,里面的localhost改为服务器ip,注意端口是8989
# just a flag ENV = 'production' # base api VUE_APP_BASE_API = 'http://8.137.35.5:8989'
第十步: 把sg-vue-admin\src\router\index.js文件修改为如下
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
{
path: '/write',
component: Layout,
children: [{
path: '/',
name: 'Write',
component: () => import('@/views/content/article/write/index'),
hidden: true
}]
},
{
path: '/system/user',
component: Layout,
children: [{
path: '/',
name: 'User',
component: () => import('@/views/system/user'),
hidden: true
}]
},
{
path: '/system/role',
component: Layout,
children: [{
path: '/',
name: 'role',
component: () => import('@/views/system/role'),
hidden: true
}]
},
{
path: '/system/menu',
component: Layout,
children: [{
path: '/',
name: 'menu',
component: () => import('@/views/system/menu'),
hidden: true
}]
},
{
path: '/system/role',
component: Layout,
children: [{
path: '/',
name: 'role',
component: () => import('@/views/system/role'),
hidden: true
}]
},
{
path: '/content/article',
component: Layout,
children: [{
path: '/',
name: 'article',
component: () => import('@/views/content/article/index'),
hidden: true
}]
},
{
path: '/content/category',
component: Layout,
children: [{
path: '/',
name: 'category',
component: () => import('@/views/content/category/index'),
hidden: true
}]
},
{
path: '/content/link',
component: Layout,
children: [{
path: '/',
name: 'link',
component: () => import('@/views/content/link/index'),
hidden: true
}]
},
{
path: '/content/tag',
component: Layout,
children: [{
path: '/',
name: 'tag',
component: () => import('@/views/content/tag/index'),
hidden: true
}]
}
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
第十一步: 把sg-vue-admin\src\main.js文件,注释掉下面的内容
第十二步: 在sg-blog-vue项目的终端执行如下
npm run build
第十三步: 在sg-vue-admin项目的终端执行如下
npm run build:prod
第十四步: 检查打包目录是否生成
二、服务器部署
1.开放防火墙
安装的系统环境为CentOS7。首先添加规则,开发端口。
2.Docker安装
yum -y install gcc
yum -y install gcc-c++
yum install -y yum-utils
yum install vim
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl start docker # 启动docker
docker version
3.拉取镜像
docker pull openjdk:8
docker pull mysql:8.0.19 # 建议和本地mysql的版本一样
docker pull redis:6.0.8
docker pull nginx:1.18.0docker images # 查看有哪些镜像
4.构建镜像
第一步: 在目录下新建mydataQiu-admin.jar和Qiu-blog.jar包传到这个mydata目录里面
第二步: 在mydata目录新建Dockerfile文件,写入如下
cd
cd mydata
touch Dockerfile
vim Dockerfile
# 基础镜像使用jdk1.8
FROM openjdk:8
# 作者
MAINTAINER xha
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名
ADD Qiu-blog.jar qiu_blog.jar
# 运行jar包
RUN bash -c 'touch /qiu_blog.jar'
ENTRYPOINT ["java","-jar","/qiu_blog.jar"]
#暴露7777端口作为微服务
EXPOSE 7777
第三步: 在mydata目录执行如下,作用是构建Qiu-blog.jar包的镜像,构建出来的镜像名为sangeng_blog
docker build -t sangeng_blog:1.0 .
第四步: 把mydata目录下的Dockerfile文件修改为如下
# 基础镜像使用jdk1.8
FROM openjdk:8
# 作者
MAINTAINER xha
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名
ADD Qiu-admin.jar qiu_admin.jar
# 运行jar包
RUN bash -c 'touch /qiu_admin.jar'
ENTRYPOINT ["java","-jar","/qiu_admin.jar"]
#暴露8989端口作为微服务
EXPOSE 8989
第五步: 在mydata目录执行如下,作用是构建Qiu-admin.jar包的镜像,构建出来的镜像名为sangeng_admin
docker build -t sangeng_admin:1.0 .
第六步: 检查是否构建出sangeng_blog和sangeng_admin镜像
docker images
5.创建容器
第一步:看Docker-compose版本,如果你是按照我上面安装的docker,那么你肯定会有Docker-compose
docker compose version
第二步:在mydata目录新建docker-compose.yml文件,写入如下
cd
cd mydata
touch docker-compose.yml
vim docker-compose.yml
(注:记得mysql密码改写成自己的)
#compose版本
version: "3"
services:
sangeng_blog:
#微服务镜像
image: sangeng_blog:1.0
container_name: sangeng_blog
ports:
- "7777:7777"
#数据卷
volumes:
- /app/sangeng_blog:/data/sangeng_blog
networks:
- blog_network
depends_on:
- redis
- mysql
- nginx
sangeng_admin:
#微服务镜像
image: sangeng_admin:1.0
container_name: sangeng_admin
ports:
- "8989:8989"
#数据卷
volumes:
- /app/sangeng_admin:/data/sangeng_admin
networks:
- blog_network
depends_on:
- redis
- mysql
- nginx
#redis服务
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/conf/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- blog_network
command: redis-server /etc/redis/redis.conf
#mysql服务
mysql:
image: mysql:8.0.19
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'sg_blog'
MYSQL_USER: 'root'
MYSQL_PASSWORD: '123456'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- blog_network
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
#nginx服务
nginx:
image: nginx:1.18.0
ports:
- "80:80"
- "8093:8093"
- "8094:8094"
volumes:
- /app/nginx/html:/usr/share/nginx/html
- /app/nginx/logs:/var/log/nginx
- /app/nginx/conf:/etc/nginx
networks:
- blog_network
#创建自定义网络
networks:
blog_network:
输入如下,作用是检查docker-compose.yml文件有没有语法错误,如果输入之后没任何输出,就说明没有语法错误
cd
cd mydata
docker compose config -q
运行docker-compose.yml文件,就可以创建并运行java容器、mysql容器、redis容器、nginx容器。-d表示后台运行
docker compose up -d
docker ps -a #查看正在运行的容器
6.导入数据库
第一步:把前面在 '部署博客项目-数据库打包' 那里拿到的 'mybolgSite.sql' 文件上传到服务器的 /app/mysql/db 目录
第二步:查看容器ID
docker ps -a #查看容器ID
第三步: 进入MySQL容器内部,执行导入sql文件的操作
docker start mydata-mysql-1 # 启动mysql容器
docker exec -it 容器ID bash # 进入mysql容器内部
# 下面的是执行导入sql文件的操作,必须要进入了mysql容器内部才能执行如下命令,mysql的登录密码是228675
mysql -u root -p
228675
use sg_blog;
source /var/lib/mysql/mybolgSite.sql;
show tables; #这里能看到数据库表格
第四步: 退出MySQL容器内部
exit # 退出MySQL
exit # 退出MySQL容器
7.配置Redis
第一步:进入 /app/redis/redis.conf 目录下,新建redis.conf文件,写入如下,注意不需要把配置写完全,redis有自己的默认配置
cd /app/redis/redis.conf
touch redis.conf
vim redis.conf
bind 0.0.0.0
daemonize no
protected-mode no
第二步: 启动所有容器。nginx容器启动不了没关系,现在还没配置nginx
systemctl start docker # 启动docker
docker ps -a # 查看容器ID
docker restart 容器ID # 重新启动所有容器
docker ps # 查看实际启动的容器
8.配置Nginx
第一步:将前端项目打包好后的两个dist文件夹重命名发送到/app/nginx/html
目录下
第二步:修改/app/nginx/conf/nginx.conf配置文件,文件内容如下:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8093;
server_name localhost;
location / {
root /usr/share/nginx/html/blog_dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
server {
listen 8094;
server_name localhost;
location / {
root /usr/share/nginx/html/admin_dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
}
第三步: 启动所有容器。注意,这次nginx容器是可以正常启动的,并且全部容器都是正常启动的
systemctl start docker # 启动docker
docker ps -a # 查看容器ID
docker restart 容器ID # 重新启动所有容器
docker ps # 查看实际启动的容器
到此,完成了所有部署相关的操作。即可浏览器输入ip+8093查看个人前端系统。ip+8094查看个人后台系统。
三、效果展示
前台博客系统 http://8.137.35.5:8093/#/Home
四、参考链接
1. myblog (yuque.com)
2. 超详细Docker部署SpringBoot+Vue项目(三更博客项目部署) - xhang′s blog (xhablog.online)