从springBoot项目到docker容器
引
docker各类容器的运行,往往依赖相应的镜像,大家可以在dockerHub上找到绝大多数常用的开发中间件或者是工具,比如Mysql,Redis,Nacos,gitlab,jenkins等等。这类开源工具有很多版本的镜像,通过docker pull命令可以拉到本地,再通过docker run命令运行容器。
一些总结
而我们自定义开发的软件,比如一个springBoot项目,想要通过docker容器运行,同样也绕不开镜像这一环。借助Dockerfile,我们可以将springBoot项目打包的jar或war,build成指定的镜像,再通过镜像运行容器即可。idea有docker插件,可以很方便的通过Dockerfile创建镜像并自动上传到我们的服务器上。
同样的,从容器可以反向保存为新的镜像,镜像可以生成本地压缩文件便于离线环境部署,也可以push到我们的dockerHub上,方便多环境重复使用。
下面来实际操作springBoot项目,镜像,容器之间的一些转换。
1. 项目 >> 镜像(Docker插件)
创建一个简单的springBoot工程
这一步大家都信手拈来了,通过idea的向导,我们快速创建了一个名为docker-learning的工程,并添加一个简单的hello接口,便于测试。
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello docker".concat("<br/>").concat(System.currentTimeMillis()+"");
}
}
本地启动一下,测试服务和接口可用。
安装docker插件
在File >> Settings >> >> Plugins >> Marketplace
搜索docker并安装
安装完成后,在Settings >> Build, Execution,Deployment >> Docker添加一项,配置docker所在服务器的信息
在TCP socket >> Engin API URL:输入tcp://localhost:2375,这里的localhost替换成docker所在服务器的ip,2375为对应配置的端口。
填写好后,Apply >> OK
这里如果连接不成功,需要配置一下docker的配置文件,打开/usr/lib/systemd/system/docker.service
,在ExecStart这一行后追加 -H tcp://0.0.0.0:2375
回到idea主界面,下方菜单栏中有Services选项,可查看并操作docker镜像和容器。
配置Dockerfile
在项目根路径下创建名为Dockerfile的文件,添加如下内容
FROM openjdk:8-jdk-slim
MAINTAINER Rosen
COPY target/*.jar /docker-hello.jar
ENTRYPOINT ["java","-jar","/docker-hello.jar"]
- 第一行,以openjdk8作为基础镜像
- 第二行,记录作者信息指定维护者信息
- 第三行,将项目打包生成的jar拷贝到容器的根目录下,并命名为docker-hello.jar
- 第四行,运行容器时执行的shell命令,jar -jar /docker-hello.jar
添加一个configuration,新增一个Docker Dockerfile配置如下
Dockerfile,选择文件,指向上面我们创建并配置的Dockerfile,Image tag这里是包含了镜像名和版本信息的,如果只填写了镜像名,默认tag为latest,这里我们填的是docker-hello:1.0.0,在最下方的Before launch中,我们可用添加一个mvn clean package,保证每次执行的是最新的jar包。
部署镜像
配置好后,就运行该Configuration.
Deploying 'docker-hello:1.0.0 Dockerfile: docker-learning/Dockerfile'...
Building image...
Preparing build context archive...
[==================================================>]88/88 files
Done
Sending build context to Docker daemon...
[==================================================>] 15.86MB
Done
Step 1/4 : FROM openjdk:8-jdk-slim
---> 80e75f92be33
Step 2/4 : MAINTAINER Rosen
---> Running in 89713f5d403b
Removing intermediate container 89713f5d403b
---> 8da7d17a9c92
Step 3/4 : COPY target/*.jar /docker-hello.jar
---> 44352c80379b
Step 4/4 : ENTRYPOINT ["java","-jar","/docker-hello.jar"]
---> Running in 01003b5e4ca2
Removing intermediate container 01003b5e4ca2
---> daead515daf5
Successfully built daead515daf5
Successfully tagged docker-hello:1.0.0
'docker-hello:1.0.0 Dockerfile: docker-learning/Dockerfile' has been deployed successfully.
来到服务器上docker images查看一下
到这一步,从springBoot项目到docker镜像这一步完成了,我们依赖了idea的docker插件完成了这一步,如果没有这个插件,docker也是支持的,下面我们尝试直接从springBoot项目到docker镜像。
2. 项目 >> 镜像
上传jar包和Dockerfile
idea的docker插件,其实完成了从jar包到到镜像,镜像再上传这两步。通过将项目打包后的jar包和Dockerfile放到相应的位置,再执行docker buildi命令来完成。
将项目的Dockerfile上传至/docker/docker-file/docker-hello/
目录下,项目打包后的jar包上传至/docker/docker-file/docker-hello/target/
目录下(这里根据我们Dockerfile的配置,需要保证jar包在Dockerfile所在目录下的/target目录下)
部署镜像
在/docker/docker-file/docker-hello/
目录下执行docker build -t docker-hello:1.0.1 .
,这里的-t后面跟的是tag信息,和idea插件一样,tag信息包含镜像名和版本号,特别注意命令后的一个点号,指代镜像构建过程中的上下文环境的目录(此处比较晦涩,我选择机械记忆)。
查看以下镜像信息
通过idea插件和docker build命令部署的镜像都在列表中了
3. 镜像 >> 容器
docker run -d --name docker-hello -p 8080:8080 docker-hello:1.0.0
4. 容器 >> 镜像
docker容器往往根据镜像创建,如果通过修改容器内部数据或配置的方式,改变应用并希望模板化这种修改,比如更新tomcat容器的首页端口等信息,可用通过docker commit命令将容器提交为新的镜像。
这里我们用上面创建的docker-hello容器,重新提交为docker-hello:1.0.2镜像
docker commit -a "roswu" -m "提交测试" e9573e4a0236 docker-hello:1.0.2
-a 记录维护者信息,-m记录更新的信息,和git commit比较类似。
提交成功后,我们再次查看镜像信息如下。
5. 镜像 >> 持久化
对于需要离线部署的应用,可以将镜像离线保存为tar文件,在新的docker环境在执行为镜像。
下面我们将刚刚提交的docker-hello:1.0.2镜像通过docker save命令持久化。
docker save -o /docker/docker-1.0.2.tar docker-hello:1.0.2
-o 指定输出的文件
本来想写/docker/docker-hello-1.0.2.tar的,写错了,将错就错吧。
6. 离线镜像 >> 镜像
接着,我们需要测试在新的服务器上将该离线镜像部署。下面为了方便,将本地的镜像删掉,模拟这种场景。
先停掉容器并卸载,再删掉docker-hello相关的镜像
执行docker load命令并查看加载后的镜像列表信息
docker load -i /docker/docker-1.0.2.tar
7. 本地镜像 >> dockerHub
注册,登陆,创建仓库
注册并登陆Docker Hub这一步我就跳过了。
在repositories中新建一个仓库如下
适配镜像名
本地的docker-hello:1.0.2还不能直接push到dockerHub上去,因为名字不匹配,通过上图可以发现,dockerHub上创建的repository是带有我们自己账户信息的,镜像名应该为wuwanlong/docker-hello,所以这里我们要将本地的镜像名通过docker tag命令来适配。
docker tag docker-hello:1.0.2 wuwanlong/docker-hello:1.0.2
执行命令后,生成了一个符合要求的新镜像wuwanlong/docker-hello:1.0.2
登陆,同送
此时,直接使用docker push命令推镜像会被denied,需要先通过docker login输入用户名和密码先登录。
docker push时可能需要等个几十秒或几分钟,根据镜像大小而定。
刷新dockerHub的仓库,可以看到我们刚刚上传的镜像
拉取测试
试了一下,通过docker search命令可能搜不到,但应该不影响拉取。
将本地的wuwanlong/docker-hello镜像删掉,执行docker pull wuwanlong/docker-hello:1.0.2
,拉取成功。