zoukankan      html  css  js  c++  java
  • 使用docker部署springboot项目到服务器

    使用docker部署springboot项目到服务器


    背景

    好久没有更新过博客了,没啥的,就是闲的,对,就是闲的,代码敲得比较烦,后端逻辑实在有点绕了,就寻思着不如将项目部署一下,使用docker部署到服务器上。首先说一下自己的感受吧,截止到现在吧,感觉docker部署springboot的项目有点麻烦,真心不如使用alibaba cloud toolkit这个插件部署方便,配置好sh文件之后,一键部署,不过确实通过docker部署到服务器上,确实能学到很多知识。

    安装docker

    安装docker的话,感觉没什么可以赘述的,百度一篇都可以,这里贴出我使用的----->>>>在Ubuntu中安装Docker和docker的使用。docker部署springboot项目应该有两种方法,一种是在项目里面新建一个docker的文件夹,然后再docker文件夹下新建一个Dockerfile的文件,然后再写入指令,还需要再pom文件里添加插件依赖等,比较麻烦,简单的话,应该就是这种,大概流程就是:使用maven打包->编写Dockerfile文件->将jar包和Dockerfile文件存到服务器上->build到docker里面->找镜像->run镜像

    maven打包

    切记,打包之前一定要测试一遍,一定要测试一遍,一定要测试一遍。

    我docker部署好了之后发现项目一直启动不起来,当然排除了端口没有开放的问题,但是就是没有起来,然后自己就在target的目录下输入指令java -jar demo.jar发现出现这个错误:spring-xxx-xxx-0.0.1-SNAPSHOT.jar中没有主清单属性,然后解决的方法是在pom上添加插件就行:

    <build>
      <plugins>
          <plugin>
              <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
      </plugins>
     </build>
    

    好了,进入正规,maven打包的话,各种方法都可以,只要能在target文件夹下找到生成的jar文件就行。

    我使用的是mvn install -DskipTests,啰嗦几句,这段指令在根目录下执行。

    编写Dockerfile文件

    #FROM openjdk:8-jdk-alpine
    #ADD *.jar app.jar
    #ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
    # Docker image for springboot file run
    # VERSION 0.0.1
    # Author: eangulee
    # 基础镜像使用java
    FROM java:8
    # 作者
    MAINTAINER yamon <yamon@gmail.com>
    # VOLUME 指定了临时文件目录为/tmp。
    # 其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp
    VOLUME /tmp
    # 将jar包添加到容器中并更名为app.jar
    ADD linkai-0.0.1-SNAPSHOT.jar app.jar
    # 运行jar包
    RUN bash -c 'touch /app.jar'
    ENTRYPOINT ["java","-jar","/app.jar"]
    #VOLUME 指定了临时文件目录为/tmp。其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp。该步骤是可选的,如果涉及到文件系统的应用就很有必要了。/tmp目录用来持久化到 Docker 数据文件夹,因为 Spring Boot 使用的内嵌 Tomcat 容器默认使用/tmp作为工作目录
    #项目的 jar 文件作为 “app.jar” 添加到容器的
    #ENTRYPOINT 执行项目 app.jar。为了缩短 Tomcat 启动时间,添加一个系统属性指向 “/dev/./urandom” 作为 Entropy Source
    #
    #如果是第一次打包,它会自动下载java 8的镜像作为基础镜像,以后再制作镜像的时候就不会再下载了。
    

    注释都在里面放着呢,百度出来的基本上都这这几个。

    jar包和Dockerfile文件上传到服务器上

    直接使用xftp上传就行。

    在这里插入图片描述

    打包成镜像

    进入到/opt/java/linkai中,输入指令:docker build -t linkai . 这里有个点,表示运行上下文。最后linkai是镜像名字。

    创建容器并运行容器

    docker run -d -p 80:8080 --name linkai linkai

    80指的是服务器端口,8080指的是容器内的端口,也就是jar包中application.properties中的port端口值。

    访问

    输入ip地址就可以访问了。


    后记

    部署过程有点艰辛,原因在于部署好了,因为各种原因,项目里面代码必须修改,说个常见的我遇到的问题,那就是使用thymeleaf中,使用ModelAndView的setViewName的时候,开头不能以/开头。举个例子:

    /**
     * 打印页面
     * @param id 进货单id
     * @return 页面
     */
    @RequestMapping(value = "/update/{id}",method = RequestMethod.GET)
    public ModelAndView update2Page(@PathVariable Integer id){
        ModelAndView modelAndView = new ModelAndView();
        //查出来商品和进货单信息
        InputOrderUpdateDto inputOrderUpdateDto = inputorderService.selectInputOrderDto4UpdateById(id);
        modelAndView.addObject("inputOrder",inputOrderUpdateDto);
        //不能写成这样  modelAndView.setViewName("/admin/business/inputOrder/update/update");
        modelAndView.setViewName("admin/business/inputOrder/update/update");
        return modelAndView;
    }
    

    要不会报找不到或者不存在这个html模板。然后我就只能一个一个改,改完了之后必须重新打包,然后重新运行镜像,这点就有点小恶心了,如果使用alibaba cloud toolkit的话,直接push到服务器上就可以直接运行了。

    这个过程,不下三遍,所以想总结一下今晚常用的docker指令:

    首先先得分清镜像和容器,镜像就相当于一个应用,然后容器就相当于与将应用放到一个机器上运行,所以说,就必须先有应用然后才能使用机器,所以创建镜像在前,使用镜像放到容器内在后。

    先创建镜像,也就是上述的打包镜像指令docker build -t linkai .,在images中就可以找到,使用docker images

    docker images:查看所有的镜像

    在这里插入图片描述

    docker pull 镜像名[:tag]:下载指定镜像,比如上面的mysql镜像,输入docker pull mysql:5.6。

    docker rmi -f 镜像id:这里首次讲到镜像id,可以看到镜像id就是上面的IMAGE ID,那么长,使用tab键也不能补全,不用慌,直接输入前3个就可以,比如删除linkai这个镜像,输入33f就行了。这个指令比较常用

    docker rmi -f $(docker images -aq):删除所有的镜像

    到此为止,只是将打包成为镜像,也就是产生了应用,如果将应用放到机器中运行,那就需要运行镜像了:docker run -d -p 80:8080 --name linkai linkai

    docker ps -a:查看所有的容器在这里插入图片描述

    简单解释一下,command是在dockerfile里面写过的,部署项目之后,有几点需要注意,STATUS:当前的状态,Exited(1)非正常终止,大概率是程序出错,Exited(0)应该是手动停止或者正常程序运行终止,Exited(143)这个反正也是终止的意思,但是没怎么查,不大清楚。PORTS:容器内和服务器的端口映射。

    docker stop Container Id:停止容器

    docker rm Container Id:删除指定容器,但是如果正在运行的话,不能删除,两种解决策略,一种使用这个指令docker rm -rf Container Id,或者使用停止容器的指令,然后再删除。

    docker run -d IamgeId :后台运行镜像。

    docker logs -t 容器Id:查看日志,重要


    讲的就这么些吧,说一下现在仍然存在的问题,如果项目用到redis的话,不适用。mysql的话,应该也不适用,因为我用的是阿里云的数据库,所以不用担心这个。还有就是如果项目中有上传文件到服务器上的话,应该也不能用,具体原因可以自己考虑一下为什么不能。如果讲的有什么问题,可以评论在评论区,谢谢阅读。

    码字不易,请点个赞。

    博客网站 https://yamon.top 个人网站 https://yamon.top/resume GitHub网站 https://github.com/yamonc 欢迎前来访问
  • 相关阅读:
    Activity之间的数据传递
    解析JSON
    使用HTTP协议访问网路
    WebView的初体验
    Alarm机制用于定时服务
    IntentService和Service执行子线程对比
    前台服务
    Android四大组件之服务
    异步消息处理机制,UI更新
    Git学习
  • 原文地址:https://www.cnblogs.com/chenyameng/p/14433203.html
Copyright © 2011-2022 走看看