目标

创建基于spring boot的docker镜像工程

创建工程

创建mvn工程

具体目录结构如下:
image

添加依赖

修改pom.xml文件,为了方便,这里把后面会用到的mysql,redis,rabbitmq,spring,mybatis等相关中间,框架以及工具类一次性引入。

<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.sunhaojie</groupId>
  <artifactId>spring_boot_docker_image_test</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>spring_boot_docker_image_test</name>
  <url>http://maven.apache.org</url>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
  </parent>

  <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Edgware.SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
  </dependencyManagement>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <javax.servlet.version>3.1.0</javax.servlet.version>
    <jdbc.driver.version>5.1.39</jdbc.driver.version>
  </properties>

  <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
</project>

添加工程启动类

package com.sunhaojie.sbdit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

右键运行Application可以看到控制台显示运行成功

多环境配置

在src/main/recoreces目录下添加application.properties
并写入一下内容:

spring.application.name=pos-member
env=@env@

在src/main/filters目录下添加以下文件:

filter-dev.properties
filter-test.properties
filter-release.properties

内容如下:

#filter-dev.properties
env=dev
---
#filter-test.properties
env=test
---
#filter-release.properties
env=release

修改pom.xml文件,在dependencies标签的下部添加

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <env>dev</env>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <env>test</env>
        </properties>
    </profile>
    <profile>
        <id>release</id>
        <properties>
            <env>release</env>
        </properties>
    </profile>
</profiles>
<build>
  <finalName>spring_boot_docker_image_test</finalName>
<filters>
    <filter>src/main/filters/filter-${env}.properties</filter>
</filters>
<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>
  <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
            <encoding>UTF-8</encoding>
            <showWarnings>true</showWarnings>
        </configuration>
    </plugin>
  </plugins>
</build>
profiles标签支持哪些配置名称
build.filters指示配置名称对应配置文件的规则
maven-compiler-plugin用于编译源代码

在工程所在目录执行命令:

mvn clean package -Ptest
# -p后的字符串用于指示使用哪个配置用于编译

会在target目录生成spring_boot_docker_image_test.jar

生成包含所以依赖包(包括tomcat)以及执行文件的压缩包

  • 添加可执行文件

    在src/main/assembly/sbin中添加start.sh和stop.sh,内容如下:

#!/bin/bash

current_path=`pwd`
case "`uname`" in
    Linux)
        bin_abs_path=$(readlink -f $(dirname $0))
        ;;
    *)
        bin_abs_path=`cd $(dirname $0); pwd`
        ;;
esac
base=${bin_abs_path}/..
export LANG=en_US.UTF-8
export BASE=$base
SERVICE_NAME=spring_boot_docker_image_test


## set java path
if [ -z "$JAVA" ] ; then
  JAVA=$(which java)
echo $JAVA
fi

LOG_PATH=/var/logs/pos_member

if [ "$1" = "test" ]; then
JAVA_OPTS=" $JAVA_OPTS -server -Xmx128m -Xms128m -Xmn64m -XX:PermSize=16m -XX:MaxPermSize=64m -Xss256k "
else
JAVA_OPTS="-server -Xms128m -Xmx128m -Xmn64m -XX:SurvivorRatio=2 -XX:PermSize=16m -XX:MaxPermSize=64m -Xss256k -XX:-UseAdaptiveSizePolicy -XX:MaxTenuringThreshold=15 -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError"
fi

JAVA_OPTS=" $JAVA_OPTS -Xloggc:${LOG_PATH}/gc.log -XX:HeapDumpPath=LOGS_DIR=${LOG_PATH} "
JAVA_OPTS=" $JAVA_OPTS -Dapp.name=${SERVICE_NAME} -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8"

## set classpath lib
for i in $base/lib/*;
    do CLASSPATH=$i:"$CLASSPATH";
done
CLASSPATH="$base:$base/conf:$CLASSPATH";

cd $bin_abs_path
echo CLASSPATH :$CLASSPATH
$JAVA $JAVA_OPTS $JAVA_DEBUG_OPT  -classpath .:$CLASSPATH com.sunhaojie.sbdit.Application 
----
#!/bin/bash

SERVICE_NAME=spring_boot_docker_image_test

cd `dirname $0`
BIN_DIR=`pwd`
cd ..
DEPLOY_DIR=`pwd`


PIDS=`ps -ef | grep java | grep "Dapp.name=$SERVICE_NAME" | awk '{print $2}'`
if [ -z "$PIDS" ]; then
    echo "ERROR: The $SERVICE_NAME does not started!"
    exit 0
fi

echo -e "Stopping the $SERVICE_NAME ...\c"
for PID in $PIDS ; do
    kill $PID > /dev/null 2>&1
done

COUNT=0
while [ $COUNT -lt 1 ]; do    
    echo -e ".\c"
    sleep 1
    COUNT=1
    for PID in $PIDS ; do
        PID_EXIST=`ps -f -p $PID | grep java`
        if [ -n "$PID_EXIST" ]; then
            COUNT=0
            break
        fi
    done
done

echo "OK!"
echo "PID: $PIDS"
  • 添加打包插件

    在目录src/main/assembly添加打包的配置文件assembly.xml,内容如下:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
    <id>dist</id>
    <formats>
        <format>tar.gz</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>src/main/assembly/sbin</directory>
            <outputDirectory>bin</outputDirectory>
            <!-- 文件权限 rwxr-xr-x -->
            <directoryMode>0755</directoryMode>
            <fileMode>0755</fileMode>
        </fileSet>
    </fileSets>
    <dependencySets>
        <dependencySet>
            <!-- 将scope为runtime的依赖包打包到lib目录下 -->
            <outputDirectory>lib</outputDirectory>
            <scope>runtime</scope>
            <!-- 文件权限 rw_r__r__ -->
            <fileMode>0644</fileMode>
        </dependencySet>
    </dependencySets>
</assembly>
在pom.xml的project/build/plugins中添加一下内容
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptors>
            <descriptor>src/main/assembly/assembly.xml</descriptor>
        </descriptors>
    </configuration>
    <executions>
        <execution>
            <id>make-zip</id>
            <phase>package</phase>
            <goals>
                <!-- 只运行一次 -->
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>
再次执行"mvn clean package -Ptest",发现在target目录会生成spring_boot_docker_image_test-dist.tar.gz
到这里我们已经生成了一个包含tomcat依赖的可以独立运行的java web项目;
如果不采用docker运行的方式,可以把文件解压,执行"./bin/start.sh &",一个简单的spring boot项目就启动了

为便于测试在添加HelloWorldController.java

package com.sunhaojie.sbdit.controller;

import org.springframework.beans.factory.annotation.Value;
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;

@RequestMapping("hello_world")
@Controller
public class HelloWorldController {

    @Value("${env}")
    private String env;

    @ResponseBody
    @RequestMapping(method = RequestMethod.GET)
    public String sayHello() {
        return env;
    }
}

制作镜像

创建Dockerfile

在pom.xml同级创建Dockerfile文件,内容如下:

# Start with a base image containing Java runtime
FROM openjdk:8-jdk-alpine

# Add Maintainer Info
MAINTAINER sunhaojie <sunhj000@163.com>

# Add a volume pointing to /tmp
VOLUME /var/logs/spring_boot_docker_image_test

# Make port 8080 available to the world outside this container
EXPOSE 8080

# The application's jar file
ARG JAR_FILE=target/spring_boot_docker_image_test-dist.tar.gz

# Add the application's jar to the container
RUN ["mkdir", "/www"]
COPY ${JAR_FILE} /www/data-dist.tar.gz

RUN ["tar", "-zxf", "/www/data-dist.tar.gz", "-C", "/www"]

# Run the jar file 
ENTRYPOINT ["sh", "/www/bin/start.sh"]

创建镜像

# DockerFile在当前文件夹
docker build . -t harbor.sunhaojie.com/spring_boot_docker_image_test:v0.001

# 输出结果
Sending build context to Docker daemon 25.82 MB
Step 1/9 : FROM openjdk:8-jdk-alpine
 ---> 5801f7d008e5
Step 2/9 : MAINTAINER sunhaojie <sunhj000@163.com>
 ---> Using cache
 ---> c666da095d9f
Step 3/9 : VOLUME /var/logs/spring_boot_docker_image_test
 ---> Using cache
 ---> e891b4a2ec48
Step 4/9 : EXPOSE 8080
 ---> Using cache
 ---> 0f84159f9c73
Step 5/9 : ARG JAR_FILE=target/spring_boot_docker_image_test-dist.tar.gz
 ---> Using cache
 ---> c62efdbc735d
Step 6/9 : RUN mkdir /www
 ---> Using cache
 ---> e7e6a7f00ae3
Step 7/9 : COPY ${JAR_FILE} /www/data-dist.tar.gz
 ---> 207eba11f06a
Removing intermediate container 401a9b6c022d
Step 8/9 : RUN tar -zxf /www/data-dist.tar.gz -C /www
 ---> Running in 1b98116a0470

 ---> 921cba8a11ee
Removing intermediate container 1b98116a0470
Step 9/9 : CMD sh /www/bin/start.sh
 ---> Running in 497bd1d6e2ea
 ---> 74066325d394
Removing intermediate container 497bd1d6e2ea
Successfully built 74066325d394

查看镜像

docker images harbor.sunhaojie.com/spring_boot_docker_image_test
REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
harbor.sunhaojie.com/spring_boot_docker_image_test   v0.001              74066325d394        3 minutes ago       157 MB

运行镜像

docker run -d -p8087:8080 74066325d394

测试

curl http://127.0.0.1:8087/hello_world
输出:test

推送镜像到harbor

  • tag
docker tag harbor.sunhaojie.com/spring_boot_docker_image_test:v0.001 harbor.sunhaojie.com/library/spring_boot_docker_image_test:v0.001
  • push
docker push harbor.sunhaojie.com/library/spring_boot_docker_image_test:v0.001