• 超详细Docker部署SpringBoot+Vue项目(三更博客项目部署)


    该文章已同步收录到我的博客网站,欢迎浏览我的博客网站,xhang’s blog

    笔者踩坑无数、吐血整理,如果帮到你了能给我点个赞,点点关注吗,嘿嘿。
    项目地址:
    后端
    博客前台
    博客后台

    1.项目部署规划

    1. 后端多模块项目blog以及各模块运行端口

    前台服务模块sangeng-blog->7777,后台服务模块sangeng-admin->8989,公共模块sangeng-framework

    1. 前端前台Vue项目:sg-blog-vue->8093

    2. 前端后台Vue项目:sg-vue-admin->8094

    3. docker所需镜像

      • java:8(jdk1.8)

      • mysql:8.0.19

      • redis:6.0.8

      • nginx:1.18.0

    4. 部署步骤

      • 安装docker

      • 拉取java:8镜像,后端项目使用maven打包,上传jar包到服务器指定目录/mydata,编写Dockerfile文件,将后端项目打成镜像文件。

      • 拉取mysql:8.0.19、redis:6.0.8、nginx:1.18.0镜像。

      • 编写docker-compose.yml文件,使用docker-compose容器编排管理容器运行。

      • 配置mysql,导入sql文件

      • 配置redis,修改redis.conf文件

      • 配置nginx,将打好包的Vue项目放到html目录下,并配置nginx.conf文件

      • 测试运行

      • 镜像上传阿里云镜像仓库

    5. 使用工具:

      • IDEA
      • Navicat
      • ApiFox
      • Mobaxterm

    2.前置工作

    2.1修改后端配置文件ip

    修改后端项目的application.yaml文件,将MySQL服务和Redis服务的localhost修改为服务器ip

    2.2修改前端Vue项目运行端口

    ​ 前台Vue项目修改项目运行端口是在config文件夹下的index.js文件当中,运行端口由原来的80变为8093

    image-20221120141647866

    后台Vue项目修改项目运行端口是在vue.config.js文件当中,运行端口由原来的8081变为8094

    image-20221120141934752

    2.3修改前端对应的服务器ip

    1. 使用快捷键ctrl+shift+R全局搜索,将原来的localhost更改为对应的服务器ip

    2. 前台Vue项目

    image-20221120142925735
    1. 后台Vue项目
    image-20221120142906304

    将原来的开发环境和生产环境的VUE_APP_BASE_API都更改为你的服务器ip和后端子模块端口

    image-20221121092519962

    image-20221121092622761

    2.4后端项目打包

    1. 后端项目使用maven打包

    ​ 打包后在target目录下生成对应模块的jar包

    打包出现的问题:我在打包完成后查看jar包,发现只有16kb,然后试在本地运行jar包测试,果然有错误,报错信息是:xxxxx-0.0.1-SNAPSHOT.jar中没有主清单属性,原因是不能找到程序的主类,需要修改父pom文件和子模块sangeng-blog的pom文件和子模块sangeng-admin的pom文件,修改如下:

    2.4.1解决打包问题

    	这是要使用的SpringBoot版本要在2.6以上,我的为2.6.11
    
    • 1
    1. 父pom
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <version>3.10.1version>
            plugin>
            
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-assembly-pluginartifactId>
                <version>3.3.0version>
                <executions>
                    
                    <execution>
                        <id>make-assemblyid>
                        <phase>packagephase>
                        <goals>
                            
                            <goal>singlegoal>
                        goals>
                    execution>
                executions>
                <configuration>
                    <archive>
                        <manifest>
                            
                            <mainClass>com.xha.SanGengBlogApplicationmainClass>
                        manifest>
                        <manifest>
                            
                            <mainClass>com.xha.SanGengAdminApplicationmainClass>
                        manifest>
                    archive>
                    
                    <outputDirectory>${project.build.directory}/#maven-assembly-pluginoutputDirectory>
                    
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependenciesdescriptorRef>
                    descriptorRefs>
                configuration>
            plugin>
        plugins>
    build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    1. 子模块sangeng-blog和子模块sangeng-admin的pom文件
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackagegoal>
                        goals>
                    execution>
                executions>
            plugin>
        plugins>
        <finalName>${project.artifactId}finalName>
    build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.4.2项目打包,本地运行jar包测试

    在这之前首先修改配置文件中的mysql和redis服务ip地址

    在父pom下首先clean清除先前的jar包,再install打包.(单模块项目首先clean清除先前的jar包,再package打包)

    sangeng-blog模块

    image-20221120150200724

    sangeng-admin模块

    image-20221120150117318

    进入target目录下,在文件搜索框输入cmd进入Dos窗口,使用命令运行jar包

    java -jar jar包
    
    • 1

    image-20221119182154697

    若未报错则jar包没有问题

    2.5前端项目打包

    1. 前端sangeng-blog模块项目使用下面命令打包
    npm run build
    
    • 1
    1. 前端sangeng-admin模块项目使用下面命令打包

    注意:因为后端使用的是Finclip提供的模板,所以生产环境使用的是npm run build:prod,如果你没有使用提供的模板,就直接使用npm run build命令。

    npm run build:prod
    
    • 1
    1. 如果你打包的过程中出现以下错误,表示 node.js版本过高,可以关闭node.js安全校验后再打包
    set NODE_OPTIONS=--openssl-legacy-provider
    
    • 1

    image-20221121084043547

    1. 如果使用出现ERROR,请注释掉以下内容

    image-20221121091856207

    下面这一步可以先忽略,因为我是后端部署完成之后再在本地测试前端项目的

    1. 在本地测试,放在Nginx里面测试发现后台只有登录和左边menu能够显现,原因是因为Route目录下的index.js有问题,只有/login/dashborad
    image-20221121175832671

    由于添加的Route有些多,所以可以直接在Gitee中克隆我的后台项目,项目地址:

    https://gitee.com/xu-huaiang/sg-vue-admin

    或者GitHub克隆,项目地址

    https://github.com/sunwebgo/sg-vue-admin

    2.6开放端口

    1. 打开所有需要运行服务的端口
    firewall-cmd --zone=public --add-port=80/tcp --permanent
    firewall-cmd --zone=public --add-port=7777/tcp --permanent
    firewall-cmd --zone=public --add-port=8989/tcp --permanent
    firewall-cmd --zone=public --add-port=6379/tcp --permanent
    firewall-cmd --zone=public --add-port=3306/tcp --permanent
    firewall-cmd --zone=public --add-port=8093/tcp --permanent
    firewall-cmd --zone=public --add-port=8094/tcp --permanent
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 重启防火墙
    systemctl restart firewalld.service
    
    • 1
    1. 可以使用以下命令查看端口是否开放成功
    firewall-cmd --zone=public --query-port=8093/tcp
    
    • 1

    2.7配置安全组规则

    在云服务器的安全组中添加规则

    我这里是华为云ECS,添加的是入方向规则

    image-20221120112943062

    image-20221120143543134

    3.Docker安装

    Docker运行环境要求系统为64位、Linux系统内核版本为 3.8以上

    查看自己虚拟机的内核:

    cat /etc/redhat-release
    
    • 1

    image-20221119170927963

    开始安装:

    一:搭建gcc环境(gcc是编程语言译器)

    yum -y install gcc
    yum -y install gcc-c++
    
    • 1
    • 2

    二:安装需要的软件包

    yum install -y yum-utils
    
    • 1

    三:安装镜像仓库

    官网上的是

    image-20221006132500216

    但是因为docker的服务器是在国外,所以有时候从仓库中下载镜像的时候会连接被拒绝或者连接超时的情况,所以可以使用阿里云镜像仓库

    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    • 1

    四:更新yum软件包索引

    yum makecache fast
    
    • 1

    五:安装docker引擎

    yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
    
    • 1

    六:启动docker

    systemctl start docker
    
    • 1

    查看docker服务

    image-20221006133740030

    查看docker版本信息

    docker version
    
    • 1
    image-20221119171428170

    七:阿里云镜像加速配置

    为了提高镜像的拉取、发布的速度,可以配置阿里云镜像加速

    image-20221006134917410

    查看加速器地址

    image-20221122104845082

    在CentOS下配置镜像加速器

    mkdir -p /etc/docker
    tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["你个人的阿里云镜像加速器地址"]
    }
    EOF
    systemctl daemon-reload
    systemctl restart docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20221122110013829

    4.拉取镜像

    1. 拉取镜像java:8(jdk1.8)
    docker pull java:8
    
    • 1
    1. 拉取镜像mysql:8.0.19
    docker pull mysql:8.0.19
    
    • 1
    1. 拉取镜像redis:6.0.8
    docker pull redis:6.0.8
    
    • 1
    1. 拉取镜像nginx:1.18.0
    docker pull nginx:1.18.0
    
    • 1

    查看当前所有镜像:

    image-20221119200239766

    5.编写Dockerfile文件,构建镜像

    1. 首先将jar包传到服务器指定目录下

    我这里是在根目录下创建了一个mydata目录

    image-20221119200750771

    1. 在mydata目录下创建Dockerfile文件,编写Dockersfile文件

    这里我们两个jar包分别打成两个镜像,因为一个目录下只能有一个Dockerfile文件,所以当构建完第一个镜像之后修改对应的Dockerfile文件。

    ​ 在vim模式下 :set paste粘贴的文本数据不会乱

    第一个Dockerfile文件

    #基础镜像使用jdk1.8
    FROM java:8
    #作者
    MAINTAINER xha
    # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
    VOLUME /tmp
    # 将jar包添加到容器中并更名
    ADD sangeng-blog.jar sangeng_blog.jar
    # 运行jar包
    RUN bash -c 'touch /sangeng_blog.jar'
    ENTRYPOINT ["java","-jar","/sangeng_blog.jar"]
    #暴露7777端口作为微服务
    EXPOSE 7777
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    image-20221120103428159

    1. 构建镜像
    docker build -t sangeng_blog:1.0 .
    
    • 1
    1. 第二个Dockerfile文件
    #基础镜像使用jdk1.8
    FROM java:8
    #作者
    MAINTAINER xha
    # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
    VOLUME /tmp
    # 将jar包添加到容器中并更名
    ADD sangeng-admin.jar sangeng_admin.jar
    # 运行jar包
    RUN bash -c 'touch /sangeng_admin.jar'
    ENTRYPOINT ["java","-jar","/sangeng_admin.jar"]
    #暴露8989端口作为微服务
    EXPOSE 8989
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 构建镜像
    docker build -t sangeng_admin:1.0 .
    
    • 1
    1. 查看构建的镜像
    docker images
    
    • 1

    image-20221120103951743

    6.使用Docker-compose容器编排

    6.1安装Docker-compose(高版本的Docker会默认安装)

    注意:如果是低版本的compose,dockercompose之间要有-

    1. 首先查看主机是否有docker-compose环境
    docker compose version
    
    • 1

    ​ 如果没有就安装docker-compose

    1. 安装命令

    如果是低版本的docker需要安装docker-compose

    由于docker-compose是从github上安装的,有可能是安装失败,所以需要那啥,都懂的话

    DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} 
    
    mkdir -p $DOCKER_CONFIG/cli-plugins 
    
    curl -SL https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
    
    chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 查看docker-compose版本
    docker compose version
    
    • 1

    image-20221119210518596

    6.2配置nginx文件

    1. 在/目录下创建一个app目录,进入app目录
    mkdir /app
    
    • 1
    1. 首先创建一个nginx容器,只是为了复制出配置
    # 1.运行容器
    docker run -p 80:80 --name nginx -d nginx:1.18.0
    
    # 2.将容器内的配置文件拷贝到当前目录/app中:
    docker container cp nginx:/etc/nginx .
    # 3.将文件nginx修改为conf
    mv nginx conf
    # 4.创建文件夹nginx
    mkdir nginx
    # 5.将conf目录拷贝到nginx目录
    cp -r conf nginx/
    # 6.删除conf目录
    rm -rf conf
    # 3.停止并删除容器
    docker stop nginx && docker rm nginx 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6.4编写docker-compose.yml文件

    1. 在/mydata目录下创建docker-compose.yml文件,并编写docker-compose.yml文件

    ​ 在vim模式下 :set paste粘贴的文本数据不会乱

    #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/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: 'xu.123456'
          MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
          MYSQL_DATABASE: 'sg_blog'
          MYSQL_USER: 'root'
          MYSQL_PASSWORD: 'xu.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: 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    1. 检查当前目录下compose.yml文件是否有语法错误
    docker compose config -q
    
    • 1
    1. 启动所有docker-compose服务并后台运行
    docker compose up -d
    
    • 1

    查看正在运行的容器实例

    image-20221120110530922

    注意:因为MySQL和Redis还未配置,会出现容器挂掉的情况,这点等待配置过MySql和Redis之后再重启容器实例即可

    7.配置MySQL

    1. 将sql文件传到/app/mysql/db目录下(和MySQL容器实例相同的容器数据卷位置)

    ​ 本机Navicat导出sql文件,传送到/app/mysql/db目录下

    image-20221120115713692

    1. 进入MySQL容器实例
    docker exec -it 容器ID bash
    
    • 1

    ​ 在/var/lib/mysql目录下查看是否有sql文件

    image-20221120115951975

    1. 登录MySQL

    ​ 密码就是在docker-compose.yml文件当中进行配置的

    image-20221120114617345
    1. 使用对应的数据库,导入sql文件
    use sg_blog;
    source /var/lib/mysql/sg_blog.sql;
    
    • 1
    • 2
    1. sql数据导入成功

    image-20221120120151036

    8.配置Redis

    1. 获取redis对应版本的配置文件

    因为docker拉取的redis镜像是没有redis.conf文件的。因此,就需要我们官网上找一个相对应版本的的redis.conf配置文件

    redis配置文件官网Redis configuration | Redis

    因为我的redis版本是6.0.8,所以我选择6.0.的配置文件

    image-20221120131905474
    1. 进入/app/redis目录下

    不知为何docker-compose.yml文件写的没有问题,但是这里创建的redis.conf文件却是一个文件夹,无奈只好删除redis.conf目录,创建一个redis.conf文件

    使用vim命令进入vim编辑器,将redis配置文件内容粘贴进去

    touch redis.conf
    vim redis.conf
    
    • 1
    • 2

    在vim模式下 :set paste粘贴的文本数据不会乱

    image-20221120172409885
    1. 修改配置文件内容

    ​ 使用/进行搜索

    • 添加redis密码(requirepass)

    image-20221120134833040

    • 修改bind为0.0.0.0(任何机器都能够访问)

    image-20221120134915688

    • 为了避免和docker中的-d参数冲突,将后台启动设置为no(daemonize no)

    image-20221120134950630

    • 关闭保护模式(protected-mode no)

    image-20221120135253947

    9.测试后端接口

    1. 重启现在未启动的容器实例
    docker restart 容器ID
    
    • 1
    1. 使用ApiFox进行接口测试(postman也可以)

    测试通过

    image-20221120145234960

    1. 将已经打包好的前端项目放到本地Nginx里面测试

    image-20221121180623177

    1. 将dist文件直接放到html目录下
    2. 在conf文件中修改nginx.conf文件,在http{......}中添加内容如下
       server {
       #监听端口
            listen       8094;
            server_name  localhost;
    
            #charset koi8-r;
            #
            #       #access_log  logs/host.access.log  main;
    
                  location / {
                  #dist文件所在目录
                         root   html/dist;
                         index  index.html index.htm;
                  #解决刷新404的问题
                         try_files $uri $uri/ /index.html;
                       }
    
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 点击nginx.exe运行nginx服务

    image-20221121180945159

    1. 访问对应的ip+端口号
    image-20221122085112706

    ​ 如果你的后台出现问题:

    问题一:访问405,解决方案请看2.3章的第3步

    问题二:页面只有/login/dashborad请求,其他页面是空白,解决方案请看2.4章的第6步

    如果没有问题,下面开始Nginx容器配置

    10.配置Nginx

    10.1操作dist文件夹

    1. 将打包好后的两个dist文件夹重命名发送到/app/nginx/html目录下

    image-20221120154625942

    1. 修改nginx.conf配置文件

    ​ 进入conf文件夹下,打开nginx.conf文件

    ​ 在http{.......}添加两个server
    记得root路径为容器内的dist文件路径

       server {
            listen       8093;
            server_name  localhost;
    
            #charset koi8-r;
            #
            #       #access_log  logs/host.access.log  main;
    
                  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;
    
            #charset koi8-r;
            #
            #       #access_log  logs/host.access.log  main;
    
                  location / {
                         root   /usr/share/nginx/html/admin_dist;
                         index  index.html index.htm;
                         try_files $uri $uri/ /index.html;
                       }
    
            }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    image-20221122085812919

    10.项目测试

    访问对应ip和端口,查看项目是否有问题

    前台

    image-20221122092426088

    后台

    image-20221122092450840

    原创不易,希望大家能给文章点个赞,再关注一下我。如果对你有帮助,可以小小的鼓励一下,有了你的鼓励,优质文章不断更新哦。
    在这里插入图片描述

  • 相关阅读:
    最小二乘法在编程中的实现
    # Unity 如何获取Texture 的内存大小
    牛客刷题,python入门基础(11)
    JavaScript操作BOM和DOM
    计算机网络中的一些基本概念
    从一到无穷大 #19 TagTree,倒排索引入手是否是优化时序数据库查询的通用方案?
    k8s的error: metrics not available yet问题处理
    9.2.1 YEAR类型
    C语言,指针的一些运算
    微信小程序隐私协议相关接口实际使用方式
  • 原文地址:https://blog.csdn.net/qq_52030824/article/details/127982206