题目信息量很大,蕴含了以下信息:
1、当前开发环境是WIN7
2、docker容器在Linux虚拟机中
3、在WIN7里将直接将spring boot项目发布到该远程docker
4、发布工具是maven
据说docker最好部署在Linux。部署在windows也可以的,但要求操作系统是WIN10或以上。我机器老旧,只有WIN7,并且用Linux逼格比较高,就索性创建了一个Linux的虚拟机,然后安装docker于其上,并学习摸索了一轮,见拙作:《vmware10中安装配置docker和redis及外部访问》
今天终于成功在WIN7上将一个spring boot项目直接发布到了虚拟机的docker中。网上许多文章,说的都是在Linux上直接进行部署,极少有像我这种情况,因此需要一步一个坑地负重前行。以下是填坑经过:
如果想将一个spring boot项目可以发布成docker镜像,需要做一些额外的工作。我的开发工具是intellij idea2019.2。
1.1、新建一个spring boot项目,具体不表。
为简单起见,只来一句“Hello World”:
package com.monkey.demo1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloWorldController {
@ResponseBody
@RequestMapping(value = "/hi", method = RequestMethod.GET)
public String getTfs(){
return "Hello World!";
}
}
1.2、修改pom.xml
主要是加入一些与docker 有关的信息。一个是Docker maven plugin,应该是用于maven发布;还有一些就是与发布镜像时,对应哪个编译好的jar文件,以及镜像文件怎么命名。第1.3中说的Dockerfile中会用到其中的一些信息。
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.8.RELEASEversion>
<relativePath/>
parent>
<groupId>com.monkeygroupId>
<artifactId>demo1artifactId>
<version>0.0.1-SNAPSHOTversion>
<name>demo1name>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
<docker.image.prefix>springbootdocker.image.prefix>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>com.spotifygroupId>
<artifactId>docker-maven-pluginartifactId>
<version>1.0.0version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}imageName>
<dockerDirectory>src/main/dockerdockerDirectory>
<resources>
<resource>
<targetPath>/targetPath>
<directory>${project.build.directory}directory>
<include>${project.build.finalName}.jarinclude>
resource>
resources>
configuration>
plugin>
plugins>
build>
project>
1.3、Dockerfile
在src/main下新建一个文件夹 docker,然后新建一个文件Dockerfile,如图
Dockerfile 文件用来说明如何来构建镜像。本文实例如下:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD demo1-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
其中,demo1-0.0.1-SNAPSHOT.jar是我这个spring boot项目编译后的jar文件。这个名字,跟pom.xml有关(见1.2)。其余信息都是照抄的,里面的路径指的是docker所在Linux里的目录。
VOLUME 指定了临时文件目录为/tmp。其效果是在主机 /var/lib/docker 目录下创建了一个临时文件,并链接到容器的/tmp。改步骤是可选的,如果涉及到文件系统的应用就很有必要了。/tmp目录用来持久化到 Docker 数据文件夹,因为 Spring Boot 使用的内嵌 Tomcat 容器默认使用/tmp作为工作目录
项目的 jar 文件作为 “app.jar” 添加到容器的
ENTRYPOINT 执行项目 app.jar。为了缩短 Tomcat 启动时间,添加一个系统属性指向 “/dev/urandom” 作为 Entropy Source
Linux这里的设置,主要是要开放docker供外部访问。因为docker看上默认是只有本机才能访问的,要启用对外API。这里涉及到一些安全性,有些文章说要什么证书,来开放https。这个问题我们先不考虑了。另外,我按照各种教程说的,老老实实地在Linux里安装了maven,现在来看,由于我是远程发布,并非在LInux本机发布,应该是不需要的。但我不大确定。至于JDK,安装Linux虚拟机的操作系统CentOS7的时候就默认安装了,如果你的Linux没有安装JDK,那这个应该装上。
2.1、安装JDK
如果已经安装,忽略
2.2、开放docker的远程API
2.2.1、修改docker的配置文件
sudo vi /usr/lib/systemd/system/docker.service
注释原来的ExecStart,修改
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
IP地址就写4个0,别改成自己的地址。至于后面的unix做什么用,暂时也不清楚,照抄可也。保存退出以后,重启docker。
sudo systemctl daemon-reload
sudo systemctl restart docker
这时候,在Linux本机的浏览器中,输入地址:http://127.0.0.1:2375/version,应该能看到docker的信息。
2.2.2、开放2375端口
但在外部却无法访问,可能是2375这个端口没有开放。为简单起见,我们姑且简单粗暴地关闭防火墙:
sudo firewall-cmd --state
sudo systemctl stop firewalld.service
sudo firewall-cmd --state
这时候,在外面的WIN7浏览器中,输入虚拟机地址,可以看到docker信息:
至此,虚拟机的docker已经准备就绪,可以迎接外部的云部署了。docker欢迎您。
WIN7下采用maven,直接将项目发布到虚拟机的docker的话,需要相应做一些衔接工作:建立名叫DOCKER_HOST
的环境变量,指向docker的tcp地址。"DOCKER_HOST"这个名字不是随便起的,应该是docker for maven钦定的。
好了,现在可以发布了。
WIN7中,命令行方式下,进入我们这个spring boot项目根目录,运行命令:
E:\java\test\demo1>mvn clean package docker:build -D skipTests
然后可以拿一根甘蔗,坐在电脑旁,一边啃一边看进度。过程中需要下载一些什么包,我这次是70M左右,等了有好几分钟。
然后我们到Linux中查看我们的胜利果实
sudo docker images
sudo docker run --name springboot-demo1 -p 8088:8080 springboot/demo1
如果报错,扯什么iptables、wait之类,就重启一下docker
当成功运行这个镜像以后,终于可以看到这个看似平平无奇,实则迈出坚实一大步的结果:
参考文章:
使用docker-maven-plugin插件将项目编译为docker镜像到远程linux服务器
用 Docker 构建、运行、发布一个 Spring Boot 应用
vmware10中安装配置docker和redis及外部访问