一、编写目的
其实网上已经有一大堆这样的博客了,差不多也都是一样,之所以写下来,就是因为在参照网上博客学习的过程中,发现有些细节讲的不是很明了,导致实际操作的时候会有各种各样的错误,所以写一篇博客用来记录下自己的实操过程,但是可能大部分内容还是和其他的博客内容相似。
二、spring boot为什么要集docker
一些比较传统公司工作的小伙伴,或者刚毕业不久的小伙伴可能会问,为什么要集成这个docker,集成的作用是什么啊?首先我们来来说一下,传统意义上的部署要走哪些流程。
第一打包,用maven等工具把项目打成war包或jar包。
第二部署到tomcat这一类容器中去,即便是spring boot的web项目他也是在自己内嵌的tomcat中运行。
这个时候,集成docker的作用就来了,我可以直接运行相关的makefike,然后将项目打成一个镜像,然后运行容器,就可以访问你需要访问的项目了。如果还没有一点docker知识的同学,可以先查看下我docker分类下的博客,写下的都是自己的学习过程。
三、代码实现
代码很简单,就几个文件
main方法所在文件,里面定义了一个接口
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SpringbootDockerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDockerApplication.class, args);
}
@GetMapping("/{name}")
public String hi(@PathVariable(value = "name") String name) {
return "hi , " + name;
}
}
properties文件就设置了一个端口
server.port=8085
重点在于makefile文件,和pom文件
makefile文件
FROM gmaslowski/jdk
VOLUME /tmp
ADD springboot-docker-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -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- from 是从gmaslowski/jdk拉取基本镜像,网上大多数写的都是frolvlad/alpine-oraclejdk8:slim这个镜像,可是我实际在拉取的时候,发现这个镜像根本拉取不下来,其实from 这一行的本质就是拉取一个jdk,所以读者在修改镜像的时候,可以先运行docker search jdk命令,然后查看有哪些jdk镜像,自己选择所需要的,需要注意的是,要拉取jdk8的镜像
对于makefile文件里命令不熟悉的同学,可以参考我的这边博客
https://blog.csdn.net/bird_tp/article/details/106574839
pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gf</groupId>
<artifactId>springboot-docker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-docker</name>
<description>Demo project for Spring Boot</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<docker.image.prefix>gf</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/resources/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
注意:${docker.image.prefix} 为你在 docker官方仓库的用户名,如果你不需要上传镜像,随便填。
整体目录结构如下;
四、部署运行程序
网上讲解的有两种方法,同样本篇博客也是参考网上的来的也有两种方法,只是细节处讲了一些
方法一、本地先将项目打成jar包,然后运行makfile文件
1.在你的虚拟机里新建一个目录,将你的项目jar文件和dockerfile文件拷贝进去
2.在你docker文件所在目录执行指令:docker build -t dockertest1 .
执行docker build命令,docker就会根据Dockerfile里你定义好的命令进行构建新的镜像。
-t代表要构建的镜像的tag,.代表当前目录,也就是Dockerfile所在的目录。
构建成功后,你可以通过docker images查看你构建成功的镜像
3.运行容器
docker run -p 8085:8085 dockertest1
-p 宿主机端口:容器端口 #开放容器端口到宿主机端口 dockertest1为镜像名称
这里需要注意的是,你的容器端口必须和你properties'中配置的端口一样,网上很多的博客,给的端口和配置文件都不一样,我在参考学习的时候,发现端口不一致,根本无法访问项目
4.访问项目
方法二、把项目代码拷贝到虚拟机里
1.拷贝所需文件
2.在当前目录执行
mvn package docker:build
网上大部分讲的也是就是这两步,但是要完成第二部还需要很多前提条件
a、虚拟机环境需要安装maven,并且设置maven的国内镜像,国外的可能访问不了,会导致在打包的时候报错,安装步骤可以网上自行百度,配置镜像用以下方式即可
在/etc/docker/daemon.json文件中添加下面参数
{
“registry-mirrors” : [“http://hub-mirror.c.163.com”]
}
然后重启
service docker restart
如果你的linxu系统中,/etc/docker目录下,不存在daemon.json的文件,你可以自己手动创建,里面添加参数即可
b.要保证虚拟机环境变量中配置的jdk版本和项目代码里需要的版本一致
c.完成前面两个细节点之后,在运行命令,如果发现报错
报错docker Failed to execute goal com.spotify:docker-maven-plugin:1.2.0
需要Docker 开启远程访问API
vim /etc/sysconfig/docker
加入 other_args="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"
保存,重启
:wq!
service docker restart
3.build success说明该项目的镜像创建成功,查看一下,运行docker images
4.运行容器,需要注意的是,容器端口和项目里配置的端口保持一致
docker run -p 8010:8085 gf/springboot-docke
结果如下:
五、总结
本篇博客只用作学习使用,真正的使用到企业级开发,还需要用到k8s这一类的编排工具。像博客中,这种手动拷贝代码到虚拟中然后打包镜像的方式,在实际开发过程中,太过鸡肋,不可能需要打包一次,就拷贝一次代码。应该是统一的管理工具,将代码合理化管理到需要环境中,但是这篇博客用作spring boot集成docker的学习还是很有用。