上次主要说了docker的常用图形化管理工具,不知道各位老铁跟这我的节奏一起练习了吗?docker的口号:Build, Ship and Run,Buildonce,Runanywhere。不知道老铁考虑过一个问题吗?如果我们把源码也打入镜像的话这样是不是增加了docker的镜像的大小,处于安全的角度如果打了war包或者jar到镜像里面的话,也让他人查看到你了你的源码。
比如我们现在有一个最简单的 springboot,需要构建一个最小的Docker 镜像
为了方便所有老铁,这个演示过程也做了
修改SpringbootApplication
package com.idig8.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@SpringBootApplication
@Configuration
public class SpringbootApplication {
@RequestMapping("hello")
@ResponseBody
public String hello(){
return "hello world!";
}
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
<?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.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.idig8</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<!-- 指定启动类 -->
<start-class>com.idig8.springboot.SpringbootApplication</start-class>
</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>
</plugins>
</build>
</project>
项目的目录结构
启动项目:http://localhost:8080/hello
第一,第二适应于小项目无法批量使用除非写shell脚本无法大规模使用。针对第三种更加简单的方式来实现上面的镜像构建过程呢?Docker 17.05版本以后,官方就提供了一个新的特性:Multi-stage builds(多阶段构建)。使用多阶段构建,可以在一个 Dockerfile 中使用多个 FROM 语句。每个 FROM 指令都可以使用不同的基础镜像,并表示开始一个新的构建阶段。你可以很方便的将一个阶段的文件复制到另外一个阶段,在最终的镜像中保留下你需要的内容即可。
yum -y install lrzsz
yum -y install zip unzip
cd ~
mkdir test2
rz
ll
不要勾选upload files as ASC
unzip springboot.zip
ls
rm -rf springboot.zip
cd springboot
vi Dockerfile
编写Dockerfile
FROM maven:3.6.1-jdk-8 AS build-env
ADD . /java/src/app
WORKDIR /java/src/app
RUN mvn clean package -Ptest -Dmaven.test.skip=true
RUN cp /java/src/app/target/*.jar /java/src/app/app.jar
FROM openjdk:8-jre
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
JAVA_OPTS=""
COPY --from=build-env /java/src/app/app.jar /usr/local/bin/app-server/app.jar
CMD echo "The application will start " && \
java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /usr/local/bin/app-server/app.jar
EXPOSE 8080
构建阶段是没有命令的,我们可以通过它们的索引来引用它们,第一个 FROM 指令从0开始,我们也可以用AS指令为阶段命令,比如我们这里的将第一阶段命名为build-env,然后在其他阶段需要引用的时候使用--from=build-env参数即可。
docker build -t zhugeaming/docker-multi-java-demo:latest .
http://192.168.66.100:8080/hello
PS:也可以在springboot目录里面放置一个settings.xml文件,在mvn编译的时候连接指定的maven私服,这样就节省效率。
mvn -s "settingsXXX.xml" clean package -Ptest -Dmaven.test.skip=true