宗旨:所有容器尽可能的精简,且最小化对环境依赖。
场景一:java运行时基础镜像(运行环境)
此场景只需要java运行环境,因为只需要运行可执行jar文件,所以只需要基于alpine镜像
加入jdk中的jre即可。
编写Dockerfile如下:
1 | # 基于业界的基础包 |
最后执行docker构建命令:docker build --build-arg http_proxy=$http_proxy -t moduleName/jre8-alpine:v1 .
注意事项:
- 参照docker hub官网中写法,但要最小化,所以去掉不必要的命令,如校验
- 增加加解密key长度限制的补丁(防止在加解密的时候报 java.security.InvalidKeyException)
由于使用代理无法直接从官网下载jce_policy-8.zip,所以可以在宿主机上预先下载好,再在容器内使用【附件:jce_policy-8.zip】 - 若执行失败,可以启动一个最小化alpine并进入alpine测试
- 构建时需要添加代理,以使得可以正确下载jre文件
- 构建命令中注意最后一个点’.’代表在当前路径下查找dockerfile文件
场景二:maven编译时镜像(编译环境)
此场景是将我们的java文件,编译并打包,共用到两个工具jdk和maven
同样我们基于alpine进行构建最后执行docker构建命令:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25FROM alpine:3.9
# 增加java和maven的环境变量
ENV LANG C.UTF-8
ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk
ENV PATH $PATH:$JAVA_HOME/jre/bin:$JAVA_HOME/bin
ENV JAVA_VERSION 8u212
ENV JAVA_ALPINE_VERSION 8.212.04-r0
ENV MAVEN_HOME /usr/share/maven
ARG MAVEN_VERSION=3.6.1
# 用来校验压缩文件的完整性
ARG SHA=b4880fb7a3d81edd190a029440cdf17f308621af68475a4fe976296e71ff4a4b546dd6d8a58aaafba334d309cc11e638c52808a4b0e818fc0fd544226d952544
ARG BASE_URL=https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries
# 安装jdk和maven安装包以及一些辅助软件
RUN apk add --no-cache curl tar bash procps openjdk8="$JAVA_ALPINE_VERSION" \
&& curl -fsSL -o /tmp/apache-maven.tar.gz ${BASE_URL}/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
&& echo "${SHA} /tmp/apache-maven.tar.gz" | sha512sum -c - \
&& mkdir -p $MAVEN_HOME \
&& tar -xzf /tmp/apache-maven.tar.gz -C $MAVEN_HOME --strip-components=1 \
&& rm -f /tmp/apache-maven.tar.gz \
&& ln -s $MAVEN_HOME/bin/mvn /usr/bin/mvn
COPY settings.xml $MAVEN_HOME/conf/settings.xml
ENTRYPOINT ["mvn"]
CMD ["-v"]docker build --build-arg http_proxy=$http_proxy --build-arg https_proxy=$https_proxy -t test/maven-jdk8-alpine:v1 .
场景三:搭建应用镜像(真正运行的server环境)
此镜像主要是我们写程序后真正的运行环境
为了减少环境的依赖,应该分阶段打包:
阶段一:依赖maven编译镜像构建,复制源代码到镜像中,并将源文件编译打包成可执行文件
阶段二:依赖java运行时基础镜像构建,将阶段一种打包好的可执行jar包复制到镜像中运行。
以上分阶段可以使得最后我们需要的镜像最小化,没有maven和jdk,只是基于alpine的jre环境。
另外编译过程放在了容器中,减少了对于宿主机环境的依赖。
1 | # Builder image |
最后编译镜像 (组织(项目名)/模块:版本):docker build -t {project-name}/{module-name}:{version} .
注意事项:
`. 使用 COPY –from=builder 引用上一个镜像,就如同此镜像的宿主机,其中builder为上一个镜像我们取名(若不取名可以使用–from=0这种序号来表示,但不推荐)。
2. 对外暴露端口
3. 复制文件时注意路径(不是workdir)
4. {imagesrc-path}是指定当前镜像路径,若没有会创建如/applogin/src
上传和运行镜像
上传第三方镜像到docker仓库 wiki参考
1 | #先给镜像打上标签: |
对于我们构建好的应用镜像,我们需要运行,并使用端口代理给外部访问
运行镜像:
docker run -p 8078:8078 –name {ServerName} {project-name}/{module-name}
另外可以在run命令中加入cmd命令覆盖原来的参数(主要可以设置不同的参数如spring.profiles.active)
注意:pull镜像和使用镜像时无需待带ip:52001前缀,会自动去掉
关于Dockerfile中的指令:
- ENV和ARG的区别:ARG可以作为dockerfile文件中的变量,ENV作为镜像运行时的环境变量,可以在RUN时使用
- CMD和ENTRYPOINT区别,CMD为默认命令,如果构建时带命令或者有ENTRYPOINT命令则会被覆盖,ENTYRPOINT若配置,则是真正默认入口命令,若没有带参数则将CMD[“arg”]中arg 为参数。
一般使用方法为:用entrypoint的中括号形式作为docker 容器启动以后的默认执行命令,里面放的是不变的部分,可变部分比如命令参数可以使用cmd的形式提供默认版本,也就是run里面没有任何参数时使用的默认参数。如果我们想用默认参数,就直接run,否则想用其他参数,就run 里面加参数。
- COPY和ADD区别 ,ADD|COPY
两者src都是相对路径,但ADD中可以填写url远程地址,不能用于多阶段构建,而COPY支持多阶段构建,但不支持url。一般推荐使用COPY,涉及到远程复制文件,建议使用RUN+wget,curl的方式。