spring boot 实例之 dockerfile

这几天体验了一把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>

项目的目录结构如下:


5222486-d510654808e052ae.png
目录结构

各文件的内容如下

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 项目

  1. 启动项目,访问地址


    5222486-0211deb2fde7c40b.png
    结果

完成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。

5222486-c22618ded5fe1cc5.png
docker quickstart

打开docker auickstart。输入docker-machine env查看服务信息
5222486-51fc4654e68f5e9b.png
服务信息

这里端口是2376,地址是192.168.99.100
这个地址是default这个系统的IP地址。可以用linux的远程连接工具连接。
5222486-7ea267887f263658.png
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>

配置参数说明:

  1. repository:这个值会成为编译完成后docker image的名称;这个根据docker仓库的名称来写,我是用阿里云的镜像服务,根据最后push的名称组装了这个值。


    5222486-b1ba8322efd027c0.png
    push地址
  2. tag:版本号,对应docker image 的tag
  3. contextDirectory:dockerfile文件所在的目录
  4. 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


5222486-1baf350f1393574b.png
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中的虚拟机。得到相同的结果


5222486-c2855870e1d75020.png
访问结果

资源文件

WEB项目的资源文件问题。一些静态文件是没有必要放到代码中编译的。可以不停止服务的情况下更新页面文件。
在上面dockerfile文件中的VOLUME $DATAPATH已经把容器中的/data文件挂载到主机中了的。可是这个目录对应的主机目录就不太适用了。而且每次创建容器的目录还不一致。所以主机上必须有一个固定的目录与容器的data目录挂载,才能达到我们的需求。
因为这里的是windows,其实主机是虚拟机,那挂载的目录也是虚拟机中的目录,很不方便使用。其实虚拟机与windows这台主机也是有挂载的。默认挂载了一个目录,c:\Users目录挂载到虚拟机的c/Users目录。增加一个自己更喜欢的目录。我把F:\ebertemp\demo挂载到虚拟机的Demo目录。完成后如下图:


5222486-1e971e59cba38f5e.png
虚拟机挂载

这样配置后,我在本机的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参数。


5222486-ecc2e405887abd1a.png
根目录

容器启动后,访问根目录,没变化。
5222486-5147eebc07fad85f.png
访问资源

现在访问一个资源没找到。复制一张图片到F:\ebertemp\demo\static文件夹中。因为application.yml中资源文件如下配置
spring:
  profiles:
    active: dev
  resources:
    static-locations: file:/data/static/ # 静态资源路径

spring boot 中配置的路径是容器中的目录。F:\ebertemp\demo目录对应的就是容器的/data目录


5222486-6f7be594ae24bc68.png
复制图片到目录中

放置图片进去后的访问结果


5222486-831d34d857cfe30d.png
结果

说明挂载成功了。

环境切换

spring配置文件可以根据不同环境切换的。


5222486-d8bd9372ddf20e5c.png
环境配置

还有个需求,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


5222486-e058e76c0c810b89.png
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


5222486-40fc63d91d98f552.png
test

环境切换的功能完成。

后记

本来还想完成spring boot使用外部的配置文件,即spring boot启动时spring.config.location参数的配置。结果尝试了一天也没成功,希望实现这个功能的朋友分享下。

猜你喜欢

转载自blog.csdn.net/weixin_33881050/article/details/87156448