24

从零开始学习docker之在docker中运行springboot项目

 4 years ago
source link: http://www.cnblogs.com/wdfordream/p/12739823.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、docker环境配置

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

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

云环境:CentOS 7.6 64位

rYvIbya.png!web

二、构建镜像

1、 用DockerFile构建镜像

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

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

具体步骤:

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

git clone [email protected]:DreamsChaser/spring-boot-basic.git

beYbIny.png!web

这个项目里写了一个简单的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 &

vauEzqN.png!web

打印日志 启动成功 端口8080

(4)测试jar

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

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

AjMVje2.png!web

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

MNBfAzF.png!web

到这里说明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 .

3i6Jvy7.png!web

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

(7)查看镜像

#查看所有镜像
docker image ls

NvMrey6.png!web

可以看到刚刚创建的 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

e2IF7jM.png!web

可以看到构建完成 可以通过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

FjeQniy.png!web

显示刚刚运行中 Up

3、进入容器

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

Vji6Fjj.png!web

进入之后可以命令行输入

4、测试jar是否正常

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

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

QJ7rA3f.png!web

找到ip是 172.18.0.2

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

b26JJzF.png!web

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

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

vayMVfy.png!web

请求成功,返回hello world。

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

(2)通过端口映射访问

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

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

Jf6Rbuy.png!web

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

以端口映射方式启动容器

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

EjI7bya.png!web

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

通过curl测试

JZZ7Vj7.png!web

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

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

b63I3uZ.png!web

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配置

JfQzMzv.png!web

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

五、常用命令汇总

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'


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK