zoukankan      html  css  js  c++  java
  • 从零开始学习docker之在docker中运行springboot项目

    一、docker环境配置

    首先需要一个安装了docker的服务器(本地或者云服务器),如果没有请看上文,传送门---https://www.cnblogs.com/wdfordream/p/12737389.html

    我这里是直接在云服务器上搭建了docker 

    云环境:CentOS 7.6 64位 

    二、构建镜像

    1、 用DockerFile构建镜像

    通过DockerFile以及springboot.jar包构建镜像。jar包可以通过本地打jar包上传到服务器也可以在服务器上拉取代码通过maven打包。

    这里我是直接在云服务器上拉取github上的代码,利用maven打包成jar包的。代码传送门---https://github.com/DreamsChaser/spring-boot-basic

    具体步骤:

     (1) 从github上拉取spring-boot项目

    git clone git@github.com:DreamsChaser/spring-boot-basic.git

     这个项目里写了一个简单的rest用于测试

     (2) maven 打包

    #进入项目根目录
    cd spring-boot-basic
    #maven 打包
    mvn clean package

    BUILD SUCCESS显示打包成功

    (3)运行jar

    #进入jar包所在目录
    cd spring-boot-basic-web/target/
    #运行jar包(& 表示将启动进程后台运行 如果不用& 可以运行后ctrl + z 暂停返回命令行后 通过bg 后台运行)
    java -jar spring-boot-basic.jar &

     打印日志 启动成功 端口8080

    (4)测试jar

    通过curl命令或者直接在浏览器访问调用rest接口

    #curl调用
    curl http://localhost:8080/spring-boot-basic/demo/test

    直接在浏览器输入 ip:port+访问url 下面的ip是我云服务器的ip 端口就是启动的端口

     到这里说明jar是没问题的 接下来通过docker创建镜像启动容器来运行jar

     (5)创建Dockerfile文件

    在项目根目录新建Dockerfile 

    #定制的镜像都是基于 FROM 的镜像(可以从docker hub上找)
    FROM openjdk
    
    #VOLUME ,VOLUME 指向了一个/tmp的目录,由于Spring Boot使用内置的Tomcat容器,Tomcat 默认使用/tmp作为工作目录
    VOLUME /tmp
    
    #拷贝并且重命名(jar必须在dockerFile所在文件夹或者子文件夹 否则会报错Forbidden path outside the build context)
    ADD /spring-boot-basic-web/target/spring-boot-basic.jar spring-boot-basic.jar
    
    #容器启动命令 也可以用CMD 但CMD会被docker run的指令覆盖
    ENTRYPOINT ["java","-jar","/spring-boot-basic.jar"]

    (6)创建镜像

    #创建镜像 
    #-t:镜像的名字及标签 -t name:tag或者 -t name
    #-f :指定要使用的Dockerfile路径 在Dockerfile所在目录不需要指定
    #最后有个 . docker build
    -t spring-boot-basic:1.0 .

     出现Step 1/4等表示正在构建 需要从docker hub拉取openjdk镜像

    (7)查看镜像

    #查看所有镜像
    docker image ls

     可以看到刚刚创建的 spring-boot-basic:1.0 镜像 以及openjdk镜像

    2、利用maven插件构建镜像

    maven插件构建镜像有两种 一种是写好dockerFile后再maven中配置dockerFile路径,另一种是把dockerFile中相关配置按照一定属性配置在maven。

    (1)写Dockerfile然后在pom中配置<dockerDirectory>

    用这种方式的时候遇到了一个问题Error: Exception caught: xx/target does not exist 一开始我以为是路径配置问题 因为我用的是pom自带的一些属性比如${basdir} 后来全部替换之后发现依然找不到

    但是 只要我先执行mvn package 生成target之后在执行mvn clean package docker:build之后就能生成镜像 但是会生成两个镜像 查看了一下输出日志后 我发现问题所在

    我的spirng-boot项目配置了一个子module这个子module里是我的rest服务并且打包类型是jar ,parent pom打包类型是pom 每次都会打一个pom和一个jar 我的maven docker配置是在父pom中 所以在打外层pom时也会build镜像,而真正的jar包还没生成索引失败了,把配置移动到子module的pom中问题就解决了。

    接下来讲一下 配置方式 

    在子module根目录写一份Dockerfile 

    FROM openjdk
    VOLUME ./tmp
    #和上面的ADD不同 是因为我Dockerfile是在子module下的 ADD .
    /target/spring-boot-basic.jar spring-boot-basic.jar ENTRYPOINT ["java","-jar","/spring-boot-basic.jar"]

    在子module spring-boot-basic-web 的pom.xml中配置

    <build>
            <finalName>spring-boot-basic</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <!-- docker plugin -->
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <version>1.0.0</version>
                    <!-- docker config -->
                    <configuration>
                        <!-- image name -->
                        <imageName>${project.build.finalName}</imageName>
                        <dockerDirectory>${project.basedir}</dockerDirectory>
                    </configuration>
                </plugin>
            </plugins>
        </build>

    在项目根目录中执行 mvn clean package docker:build 

     可以看到构建完成 可以通过docker image ls查看镜像

    (2)不用Dockerfile

    省略Dockerfile把Dockerfile中的相关配置 按照pom里的一些标签进行配置

    在子module spring-boot-basic-web的pom中配置

    <build>
            <finalName>spring-boot-basic</finalName>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <!-- docker plugin -->
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <version>1.0.0</version>
                    <!-- docker config -->
                    <configuration>
                        <!-- image name -->
                        <imageName>${project.build.finalName}</imageName>
    
                        <!-- Dockerfile配置路径
                        <dockerDirectory>${project.basedir}</dockerDirectory>
                        -->
    
                        <!-- 非Dockerfile配置-->
                        <workdir>/tmp</workdir>
                        <baseImage>openjdk</baseImage>
                        <entryPoint>["java", "-jar", "/spring-boot-basic.jar"]</entryPoint>
                        <resources>
                            <resource>
                                <targetPath>/</targetPath>
                                <directory>${project.build.directory}</directory>
                                <include>${project.build.finalName}.jar</include>
                            </resource>
                        </resources>
    
    
                    </configuration>
                </plugin>
            </plugins>
        </build>

    注意这里resource复制的时候复制到了/ 所以在entryPoint 写java启动命令时对应的jar要在/下

    三、启动容器

     1、启动容器

    #启动容器
    #参数1 --name 指定容器名
    #参数2 -d 以后台方式执行
    #最后是 镜像name:tag/name
    docker run
    --name test -d spring-boot-basic:1.0

    2、查看容器

    #查看所有容器(包括关闭的)
    docker ps -a

     

    显示刚刚运行中 Up

    3、进入容器

    #进入容器(以容器id或者name都可以进入)
    #/bin/bash 进入后打开bash命令行 docker exec
    -it 2de6fd561c9a /bin/bash

    进入之后可以命令行输入 

    4、测试jar是否正常

    (1)通过容器ip和端口访问 

    进入容器命令行后 查看容器ip

    找到ip是 172.18.0.2

    离开容器 容器bash命令行输入 exit

    通过容器ip和端口访问rest接口

    #curl
    curl http://172.18.0.2:8080/spring-boot-basic/demo/test

    请求成功,返回hello world。

    这种方式只能在部署docker的服务器上才能请求成功,在其他机器无法访问,这时候需要做端口映射。

    (2)通过端口映射访问

    关闭并删除之前启动的容器

    #关闭容器(id name都可以)
    docker stop 2de6fd561c9a
    #删除容器(id name都可以)
    docker rm 2de6fd561c9a

    docker ps -a后发现容器已经删除

    以端口映射方式启动容器

    #-p设置端口 本地端口:容器端口
    docker run --name test -d -p 7001:8080 spring-boot-basic:1.0

    启动完成之后 通过docker ps -a查看启动的容器 端口做了映射处理 可以通过本机(云服务器)端口访问到 容器内部端口

    通过curl测试 

     通过本机7001端口请求成功 返回hello world

    同时在其他服务器通过访问docker所在服务器的ip 和映射端口可以访问容器内部的服务

    122.51.103.239是我云服务器的公网ip,请求成功,返回hello world

    四、异常汇总

    [ERROR] No plugin found for prefix 'docker' in the current project 
    and in the plugin groups [org.sonatype.plugins, org.apache.maven.plugins, org.codehaus.mojo] available from the repositories

    解决:在maven配置文件 setting.xml中配置

    <pluginGroups>

      <pluginGroup>com.spotify</pluginGroup>

    </pluginGroups>

    [ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project spring-boot-basic: Exception caught: 
    java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException:
    org.apache.http.conn.HttpHostConnectException: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1]
    failed: Connection refused: connect -> [Help 1]

    这个异常是我在window10构建镜像的时候出现的 需要修改docker配置

    这个地方选中 然后重启就可以了 

    五、常用命令汇总

    1、镜像相关

    #查看所有镜像
    docker image ls
    #删除镜像 id或者name删除
    docker image rm 'id'/'name'
    #构建镜像 tag可以不填 默认latest
    docker build -t 'name':'tag' .

    2、容器相关

    #查看所有容器
    docker ps -a
    #关闭容器
    docker stop 'id'/'name'
    #重启容器
    docker restart 'id'/'name'
    #进入容器 并打开bash命令行
    docker exec -it 'id' /bin/bash #启动容器 -d后台运行 -p端口映射
    docker run --name 'name' -d -p 'port1':'port2' 'imageName':'imageTag'
  • 相关阅读:
    git学习
    Command Line
    python之测试
    python之模块
    python之函数
    python之类
    python之错误和异常
    python之迭代器和生成器
    python之字典和集合
    python之列表和元组
  • 原文地址:https://www.cnblogs.com/wdfordream/p/12739823.html
Copyright © 2011-2022 走看看