思考
制作出的镜像尽可能小
- 基础镜像使用alpine,包含最基本的命令,满足日常维护需求.
- 使用Server JRE代替JDK,官方精简版,据称可以减少40%程序文件.
应用以非root用户运行
- 在基础镜像中创建应用运行时普通账号以及目录,本例中为 appuser用户和 /srv 目录.
需要解决应用时区问题
- 本例中使用环境变量 TZ=Asia/Shanghai 设置java运行时使用时区.
需要支持中文字符集
其他考量
- 安装tini以便支持在使用其作为entrypoint,以便处理僵尸进程和信号转发.
- 同时制作最小运行环境和最小编译环境镜像,同时支持编译环境和运行环境.
步骤
- 从 www.oracle.com/java/techno… 下载Server JRE,这里使用的是 server-jre-8u202-linux-x64.tar.gz
- 编写dockerfile
FROM docker.io/library/alpine:3.16@sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c
RUN echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.16/main" > /etc/apk/repositories \
&& echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.16/community" >> /etc/apk/repositories \
&& adduser -D appuser && chown -R appuser.appuser /srv \
&& apk add tini \
&& apk add --virtual=.build-dependencies ca-certificates \
&& wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \
&& wget -q -O /tmp/glibc-2.34-r0.apk https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.34-r0/glibc-2.34-r0.apk \
&& wget -q -O /tmp/glibc-bin-2.34-r0.apk https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.34-r0/glibc-bin-2.34-r0.apk \
&& wget -q -O /tmp/glibc-i18n-2.34-r0.apk https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.34-r0/glibc-i18n-2.34-r0.apk \
&& apk add /tmp/glibc-2.34-r0.apk /tmp/glibc-bin-2.34-r0.apk /tmp/glibc-i18n-2.34-r0.apk \
&& /usr/glibc-compat/bin/localedef -c -i POSIX -f UTF-8 C.UTF-8 || true \
&& rm -rf /etc/apk/keys/sgerrand.rsa.pub && apk del glibc-i18n && apk del .build-dependencies \
&& rm -rf /var/cache/* && rm -rf /var/lib/apk/* && rm -rf /tmp/*
ARG BIN_HOME
ADD ./$BIN_HOME /usr/local/share/$BIN_HOME
ENV LANG=C.UTF-8 TZ=Asia/Shanghai PATH=/usr/local/share/$BIN_HOME/bin:$PATH
- 编写编译脚本build.sh
#!/usr/bin/env bash
set -ex
cd $(dirname "$0")
JRE_TAR=server-jre-8u202-linux-x64.tar.gz
JRE_DIR=jdk1.8.0_202
rm -rf ./${JRE_DIR} ./jre
tar -xvzf ./${JRE_TAR}
cp -r ./${JRE_DIR}/jre ./
docker build --network=host --no-cache -t fakerepo/library/jre-alpine:$(date '+%Y%m%d') --build-arg BIN_HOME=jre ./
docker build --network=host --no-cache -t fakerepo/library/jdk-alpine:$(date '+%Y%m%d') --build-arg BIN_HOME=${JRE_DIR} ./
rm -rf ./${JRE_DIR} ./jre
- 执行 sh ./build.sh
其他
- 本例中Server JRE代替JDK,部分java拓展,例如JavaFx无法使用.
- 如果遇到无法加载类库问题,可以尝试安装alpine对应的package解决,例如ffmpeg无法使用,在安装libstdc++后解决.
- 制作过程中alpine版本和glibc版本需要对应,否则镜像制作会失败.
- 合理利用JAVA_TOOL_OPTIONS和_JAVA_OPTIONS指定运行时参数.
参考
www.alpinelinux.org
github.com/sgerrand/al…
github.com/krallin/tin…
blogs.oracle.com/java/post/u…