这几天体验了一把dockerfile-maven-plugin的使用。
spring boot 项目
创建一个spring boot项目,项目名称为ddocker。以下是pom.xml
<?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>
<artifactId>bootparent</artifactId>
<groupId>com.biboheart.demos</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ddocker</artifactId>
<name>ddocker</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<docker.aliyun.registry>registry.cn-hangzhou.aliyuncs.com</docker.aliyun.registry>
<docker.image.prefix>biboheart</docker.image.prefix>
<dockerfile.maven.version>1.4.10</dockerfile.maven.version>
</properties>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.biboheart.demo.ddocker.DdockerApplication</mainClass>
<executable>true</executable>
</configuration>
<executions>
<execution>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<!--Docker maven plugin-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile.maven.version}</version>
<configuration>
<repository>${docker.aliyun.registry}/${docker.image.prefix}/${project.artifactId}</repository>
<contextDirectory>./</contextDirectory>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
其中bootparent中的pom.xml的内容如下:
<?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>
<groupId>com.biboheart.demos</groupId>
<artifactId>bootparent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.biboheart</groupId>
<artifactId>bh-brick</artifactId>
<version>0.0.6-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<modules>
<module>dsecurity</module>
<module>dsession</module>
<module>damqp</module>
<module>dssoclient</module>
<module>devent</module>
<module>dwebserver</module>
<module>dlog</module>
<module>dcache</module>
<module>dwechat</module>
<module>ddocker</module>
</modules>
</project>
项目的目录结构如下:
目录结构
各文件的内容如下
DdockerApplication
package com.biboheart.demo.ddocker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DdockerApplication {
public static void main(String[] args) {
SpringApplication.run(DdockerApplication.class, args);
}
}
DemoController
package com.biboheart.demo.ddocker.controller;
import com.biboheart.brick.model.BhResponseResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Value("${spring.profiles.active:dev}")
private String active;
@Value("${ddocker.test}")
private String value;
@GetMapping("/")
public BhResponseResult<?> index() {
String result = "hello docker from " + active + " test value:" + value;
return new BhResponseResult<>(0, "success", result);
}
}
application.yml
server:
port: 8080
ddocker:
test: test
spring:
profiles:
active: dev
resources:
static-locations: file:/data/static/
output:
ansi:
enabled: DETECT
http:
encoding:
charset: UTF-8
# LOGGING
logging:
level:
root: info
application-dev.yml
server:
port: 8080
ddocker:
test: devtest
# LOGGING
logging:
level:
root: info
application-test.yml
server:
port: 8080
ddocker:
test: testtest
# LOGGING
logging:
level:
root: info
application-prod.yml
server:
port: 8080
ddocker:
test: prodtest
# LOGGING
logging:
level:
root: info
以上的是spring boot的一项目文件,一个比较简单的应用。
测试下这个spring boot 项目
-
启动项目,访问地址
结果
完成spring boot 项目后,开始docker发布的任务了。这篇文章的主要任务开始了。
安装docker
我这台机子是windows 8.1 的操作系统。windows中使用docker是有些不方便,不过也许windows上遇到问题的同仁也不少。这里用windows来尝试也不错。
安装Docker Toolbox
可以到http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/?spm=5176.8351553.0.0.37451991o9xQDh下载安装包。安装步骤就不截图了,前几天我已经安装好了的。安装完成后会有三个程序。VirtualBox中会有个default的系统,这里装的是docker服务器;还有个docker quickstart。
打开docker auickstart。输入docker-machine env查看服务信息
服务信息
这里端口是2376,地址是192.168.99.100
这个地址是default这个系统的IP地址。可以用linux的远程连接工具连接。
ssh连接
用户名:docker,密码:tcuser
环境的安装完成后,开始配置dockerfile文件。
引入组件dockerfile-maven-plugin
这个在前面pom.xml中已经包含了,就是如下这段
<!--Docker maven plugin-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile.maven.version}</version>
<configuration>
<repository>${docker.aliyun.registry}/${docker.image.prefix}/${project.artifactId}</repository>
<contextDirectory>./</contextDirectory>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
配置参数说明:
-
repository:这个值会成为编译完成后docker image的名称;这个根据docker仓库的名称来写,我是用阿里云的镜像服务,根据最后push的名称组装了这个值。
push地址 - tag:版本号,对应docker image 的tag
- contextDirectory:dockerfile文件所在的目录
- JAR_FILE:dockerfile中使用的一个参数,这里是spring boot打包完成后的文件路径
dockerfile文件
在项目根目录下创建文件dockerfile,内容如下
# 基础镜像
FROM openjdk:8-jdk-alpine
# 对应pom.xml文件中的dockerfile-maven-plugin插件JAR_FILE的值
ARG JAR_FILE
# 复制打包完成后的jar文件到/opt目录下
COPY ${JAR_FILE} /opt/ddocker.jar
# /data设为环境变量
ENV DATAPATH /data
# 挂载/data目录到主机
VOLUME $DATAPATH
# 启动容器时执行
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/opt/ddocker.jar"]
EXPOSE 8080
打包image
进入项目根目录执行命令:mvn clean package dockerfile:build
打包成功后会生成一个image
image
启动容器
docker run -it -p 8080:8080 --name ddocker registry.cn-hangzhou.aliyuncs.com/biboheart/ddocker:0.0.1-SNAPSHOT
用这个命令启动容器,访问地址是192.168.99.100:8080 注意,windows toolbox的宿主机是VirtualBox中的虚拟机。得到相同的结果
访问结果
资源文件
WEB项目的资源文件问题。一些静态文件是没有必要放到代码中编译的。可以不停止服务的情况下更新页面文件。
在上面dockerfile文件中的VOLUME $DATAPATH已经把容器中的/data文件挂载到主机中了的。可是这个目录对应的主机目录就不太适用了。而且每次创建容器的目录还不一致。所以主机上必须有一个固定的目录与容器的data目录挂载,才能达到我们的需求。
因为这里的是windows,其实主机是虚拟机,那挂载的目录也是虚拟机中的目录,很不方便使用。其实虚拟机与windows这台主机也是有挂载的。默认挂载了一个目录,c:\Users目录挂载到虚拟机的c/Users目录。增加一个自己更喜欢的目录。我把F:\ebertemp\demo挂载到虚拟机的Demo目录。完成后如下图:
虚拟机挂载
这样配置后,我在本机的F:\ebertemp\demo文件夹中的修改会同步到虚拟机的Demo目录,如果把容器中的data目录挂载到宿主机(即虚拟机)的Demo目录。那么这个业务就走通了。这样的需求不用改image,修改创建容器命令就行了。
执行:docker run -it -p 8080:8080 -v /Demo:/data --name ddocker registry.cn-hangzhou.aliyuncs.com/biboheart/ddocker:0.0.1-SNAPSHOT
即在上一次的命令中增加-v /Demo:/data参数。
根目录
容器启动后,访问根目录,没变化。
访问资源
现在访问一个资源没找到。复制一张图片到F:\ebertemp\demo\static文件夹中。因为application.yml中资源文件如下配置
spring:
profiles:
active: dev
resources:
static-locations: file:/data/static/ # 静态资源路径
spring boot 中配置的路径是容器中的目录。F:\ebertemp\demo目录对应的就是容器的/data目录
复制图片到目录中
放置图片进去后的访问结果
结果
说明挂载成功了。
环境切换
spring配置文件可以根据不同环境切换的。
环境配置
还有个需求,image打包好了,push到仓库中后。测试人员要pull下来,创建test配置的容器;测试完成后,还是同一个image创建发布的容器,使用prod的配置。
这个在创建容器的时候增加一个参数可以解决。
-e "SPRING_PROFILES_ACTIVE=dev" // dev改成test或prod来切换配置文件
运行
docker run -it -p 8080:8080 -v /Demo:/data -e "SPRING_PROFILES_ACTIVE=dev" --name ddocker registry.cn-hangzhou.aliyuncs.com/biboheart/ddocker:0.0.1-SNAPSHOT
dev
运行
docker run -it -p 8080:8080 -v /Demo:/data -e "SPRING_PROFILES_ACTIVE=test" --name ddocker registry.cn-hangzhou.aliyuncs.com/biboheart/ddocker:0.0.1-SNAPSHOT
test
环境切换的功能完成。
后记
本来还想完成spring boot使用外部的配置文件,即spring boot启动时spring.config.location参数的配置。结果尝试了一天也没成功,希望实现这个功能的朋友分享下。
网友评论