#!/usr/bin/env bash
###################################################
# author: Sean Lyu
# modify: 2019/01/07
# function: build tomcat and java base images
# 说明:
# 此脚本会分别创建tomcat和java的Dockerfile并构建基础镜像
# tomcat基础镜像根据java的不同分为JDK和JRE版, JDK版是基于alpine基础镜像来构建, 而JRE版是基于官方tomcat来构建
# 所以Dockerfile有所不同: JDK版需要分别拷贝tomcat和java并设置相关环境变量, 而JRE版则此两步都不需要
# java基础镜像是基于alpine来构建, 只需要拷贝java,设置PATH等环境变量即可
# 此脚本使用方法:
# just build one image: build.sh tomcat:7.0.85-jdk7-alpine
# following is the way of how to build mutiple versions of images(including tomcat and java, separated by commas):
# build.sh tomcat:7.0.88-jre7-alpine,tomcat:7.0.88-jre8-alpine,tomcat:8.0.52-jre7-alpine, \
# tomcat:8.0.52-jre8-alpine,tomcat:9.0.8-jre8-alpine, tomcat:6.0.48-jdk7-alpine,tomcat:7.0.85-jdk7-alpine, \
# tomcat:7.0.85-jdk8-alpine,tomcat:8.5.28-jdk7-alpine,tomcat:8.5.28-jdk8-alpine,tomcat:9.0.5-jdk7-alpine, \
# tomcat:9.0.5-jdk8-alpine,java:7-jdk-alpine,java:8-jdk-alpine
# aliyun source
# https://mirrors.aliyun.com/alpine/v3.6/main/
# https://mirrors.aliyun.com/alpine/v3.6/community/
# ustc source
# mirrors.ustc.edu.cn
####################################################
set -e
log_dir="/data/logs/base_images"
[[ -d "$log_dir" ]] || mkdir $log_dir
build_date=`date +%Y-%m-%d_%H-%M-%S`
logfile=${log_dir}/${build_date}.log
function create_dockerfile() {
IMAGE_NAME=$1
DOCKER_REGISTRY="ycr.yonyoucloud.com"
TYPE=`echo $IMAGE_NAME | awk -F':' '{print $1}'`
VERSION=`echo $IMAGE_NAME | awk -F':' '{print $2}'`
if [[ "X$TYPE" == "Xtomcat" ]]; then
TOMCAT_VERSION=`echo $VERSION | awk -F'-' '{print $1}'`
TOMCAT_MAJOR=`echo $TOMCAT_VERSION | awk -F'.' '{print $1}'`
JAVA_VERSION=`echo $VERSION | awk -F'-' '{print $2}'`
JAVA_TYPE=${JAVA_VERSION%%[0-9]*} # 删除字条串中以数字开始的字符及右边所有
JAVA_MAJOR=`echo ${JAVA_VERSION: -1}`
CATALINA_HOME=/usr/local/tomcat
TAG_end=`echo $VERSION|cut -d "-" -f2,3`
TAG="$TOMCAT_MAJOR-$TAG_end"
Dockerfile="Dockerfile.tomcat$VERSION"
WORKDIR="$CATALINA_HOME"
# for prod
FULL_IMAGE_NAME="$DOCKER_REGISTRY/base/tomcat:$TAG"
# for test
#FULL_IMAGE_NAME="tomcat:$TAG"
elif [[ "X$TYPE" == "Xjava" ]]; then
JAVA_VERSION=`echo $VERSION | awk -F'-' '{print $1}'`
JAVA_TYPE=`echo $VERSION | awk -F'-' '{print $2}'`
JAVA_MAJOR=$JAVA_VERSION
Dockerfile="Dockerfile.java$VERSION"
WORKDIR="/app"
# for prod
FULL_IMAGE_NAME="$DOCKER_REGISTRY/base/java:$VERSION"
# for test
#FULL_IMAGE_NAME="java:$VERSION"
fi
######## Dockerfile Part 1 ########
if [[ "$JAVA_TYPE" == "jdk" ]]; then
echo "FROM alpine:latest" > ./$Dockerfile
else
echo "FROM $DOCKER_REGISTRY/official/tomcat/tomcat:$VERSION" > ./$Dockerfile
fi
######## Dockerfile Part 2 ########
cat >> ./$Dockerfile << EOF
ENV LANG=en_US.UTF-8 \\
LANGUAGE=en_US.UTF-8 \\
LC_CTYPE=en_US.UTF-8 \\
LC_ALL=en_US.UTF-8 \\
TZ="Asia/Shanghai" \\
JAVA_MAJOR=${JAVA_MAJOR} \\
WORKDIR=${WORKDIR} \\
BASE_IMAGE=${IMAGE_NAME}
EOF
########JDK#########
if [[ "$TYPE" == "tomcat" && "$JAVA_TYPE" == "jdk" ]]; then
cat >> ./$Dockerfile << EOF
ENV JAVA_HOME="/usr/local/java" \\
CATALINA_HOME="/usr/local/tomcat" \\
TOMCAT_VERSION=${TOMCAT_VERSION}
EOF
cat >> ./$Dockerfile << "EOF"
ENV JRE_HOME="${JAVA_HOME}/jre" \
CLASSPATH="${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" \
PATH="${PATH}:${JAVA_HOME}/bin:${CATALINA_HOME}/lib:${CATALINA_HOME}/bin"
EOF
elif [[ "$TYPE" == "java" && "$JAVA_TYPE" == "jdk" ]]; then
cat >> ./$Dockerfile << "EOF"
ENV JAVA_HOME="/usr/local/java"
EOF
cat >> ./$Dockerfile << "EOF"
ENV JRE_HOME="${JAVA_HOME}/jre" \
CLASSPATH="${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" \
PATH="${PATH}:${JAVA_HOME}/bin"
EOF
fi
######## Dockerfile Part 3 ########
cat >> ./$Dockerfile <<"EOF"
WORKDIR $WORKDIR
RUN set -x \
&& sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories \
&& echo 'http://mirrors.aliyun.com/alpine/edge/testing' >> /etc/apk/repositories \
&& apk update \
&& apk add --no-cache --allow-untrusted --update-cache \
wget vim curl \
openssh-client git perl make less \
bash bash-doc bash-completion \
htop iftop \
tmux fish mdocml-apropos \
busybox-extras \
coreutils \
ca-certificates \
tzdata \
libtool \
gcc \
ttf-dejavu \
fontconfig \
wqy-zenhei@edge wqy-zenhei \
apk-tools \
netcat-openbsd \
bind-tools \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
\
&& sed -i -e 's/\/bin\/ash/\/bin\/bash/' /etc/passwd \
\
\
&& echo '\
PS1='\''\[\e[01;33m\][\h \u:\[\e[01;34m\]\w\[\e[01;33m\]]\[\e[00m\]\$ '\'' ; \
eval `dircolors -b` ; \
alias ls="ls --color=auto" ; \
alias l="ls -lah" ; \
alias ll="ls -lh" ; \
alias l.="ls -d .* --color=auto" ; \
alias mv="mv -i" ; \
alias rm="rm -i" ; \
export PATH='"${PATH}"' \
' >> /etc/profile \
&& echo '. ~/.bashrc' > /root/.bash_profile \
&& echo '. /etc/profile' > /root/.bashrc \
&& echo 'set-option -g default-shell /usr/bin/fish' > /root/.tmux.conf \
&& mkdir -p /root/.config/fish/functions \
&& echo '\
function fish_prompt ;\
if not set -q __fish_prompt_hostname ;\
set -g __fish_prompt_hostname (hostname) ;\
end ;\
set_color -o yellow ;\
echo -n -s "$USER" @ "$__fish_prompt_hostname" " " ;\
set_color -o blue ;\
echo -n (prompt_pwd) ;\
echo -n " # " ;\
set_color normal ;\
end ;\
\
alias l="ls -la" ;\
' > /root/.config/fish/functions/fish_prompt.fish \
&& ln -sf /bin/bash /bin/sh \
\
&& echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf \
\
\
&& mkdir -p $WORKDIR /usr/local/src/confdownload /etc/config/download/ /usr/local/pinpoint-agent \
&& BASE_URL="http://developer.yonyoucloud.com/download/base_images/tomcat" \
&& curl -SL $BASE_URL/packages/fish_greeting.fish -o /root/.config/fish/functions/fish_greeting.fish \
&& curl -SL $BASE_URL/packages/dumb-init_1.2.1_amd64 -o /usr/bin/dumb-init \
&& curl -SL $BASE_URL/packages/java_options.sh -o /usr/local/bin/java_options.sh \
&& curl -SL $BASE_URL/packages/entrypoint.sh -o /usr/local/bin/entrypoint.sh \
&& curl -SL $BASE_URL/packages/confdownload/confcenterdownload -o /usr/local/src/confdownload/confcenterdownload \
&& curl -SL $BASE_URL/packages/glibc/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
# && curl -SL $BASE_URL/packages/etc/inputrc -o /etc/inputrc \
&& wget $BASE_URL/packages/pinpoint-agent.tar.gz \
&& tar -xvf pinpoint-agent.tar.gz --strip-components=1 -C /usr/local/pinpoint-agent \
&& rm -rf pinpoint-agent.tar.gz \
&& curl -SL $BASE_URL/packages/etc/authfile.properties -o /etc/config/download/authfile.properties \
&& curl -SL $BASE_URL/packages/etc/yhtauthfile.properties -o /etc/config/download/yhtauthfile.properties \
\
\
&& ALPINE_GLIBC_BASE_DIR="$BASE_URL/packages/glibc" \
&& ALPINE_GLIBC_PACKAGE_VERSION="2.28-r0" \
&& ALPINE_GLIBC_BASE_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
&& ALPINE_GLIBC_BIN_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
&& ALPINE_GLIBC_I18N_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
&& wget $ALPINE_GLIBC_BASE_PACKAGE_FILENAME \
&& wget $ALPINE_GLIBC_BIN_PACKAGE_FILENAME \
&& wget $ALPINE_GLIBC_I18N_PACKAGE_FILENAME \
&& apk add --no-cache \
"glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
"glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
"glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
\
&& rm -rf "/etc/apk/keys/sgerrand.rsa.pub" *.apk \
&& /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true \
&& echo "export LANG=$LANG" > /etc/profile.d/locale.sh \
\
&& apk del glibc-i18n \
\
\
EOF
####for JDK####
if [[ "$JAVA_TYPE" == "jdk" ]]; then
cat >> ./$Dockerfile <<"EOF"
&& mkdir -p $JAVA_HOME \
&& curl -SL $BASE_URL/jdk/jdk-$JAVA_MAJOR-linux-x64.tar.gz -o $WORKDIR/java.tar.gz \
&& tar -xvf java.tar.gz --strip-components=1 -C $JAVA_HOME/ \
\
&& rm -rf $JAVA_HOME/*src.zip \
$JAVA_HOME/lib/missioncontrol \
$JAVA_HOME/lib/visualvm \
$JAVA_HOME/lib/*javafx* \
$JAVA_HOME/jre/lib/ext/jfxrt.jar \
$JAVA_HOME/jre/bin/javaws \
$JAVA_HOME/jre/lib/javaws.jar \
$JAVA_HOME/jre/lib/desktop \
$JAVA_HOME/jre/plugin \
$JAVA_HOME/jre/lib/deploy* \
$JAVA_HOME/jre/lib/*javafx* \
$JAVA_HOME/jre/lib/*jfx* \
\
&& rm -rf java.tar.gz* \
&& curl -SL $BASE_URL/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/jre/lib/security/local_policy.jar \
&& curl -SL $BASE_URL/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/jre/lib/security/US_export_policy.jar \
EOF
elif [[ "$JAVA_TYPE" == "jre" ]]; then
cat >> ./$Dockerfile <<"EOF"
&& curl -SL $BASE_URL/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/lib/security/local_policy.jar \
&& curl -SL $BASE_URL/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/lib/security/US_export_policy.jar \
EOF
fi
# for tomcat
if [[ "$TYPE" == "tomcat" && "$JAVA_TYPE" == "jdk" ]]; then
cat >> ./$Dockerfile <<"EOF"
&& curl -SL $BASE_URL/jdk/apache-tomcat-$TOMCAT_VERSION.tar.gz -o $WORKDIR/tomcat.tar.gz \
&& tar -xvf tomcat.tar.gz --strip-components=1 \
&& rm -rf tomcat.tar.gz* bin/*.bat $CATALINA_HOME/webapps/* \
&& echo 'export PATH="$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin"' >> /etc/profile \
EOF
fi
if [[ "$TYPE" == "tomcat" ]]; then
cat >> ./$Dockerfile <<"EOF"
&& rm -rf $CATALINA_HOME/bin/*.bat $CATALINA_HOME/webapps/* \
&& sed -i '/tomcat.util.scan.StandardJarScanFilter.jarsToSkip=/a bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,bcprov-*.jar,\\' \
$CATALINA_HOME/conf/catalina.properties \
&& sed -i -e 's/<Connector port="8080"/& URIEncoding="UTF-8"/g' \
-e '/protocol="AJP\/1.3"/s/^/<!--/' -e '/protocol="AJP\/1.3"/s/$/-->/' \
-e '/pattern="%/s/.*/\t\tpattern="%{x-forwarded-for}i %h %l %u %t \"%r\" %s %b %{X-traceId}i %D" \/>/' \
-e '/<\/Host>/i \\t<Valve className="org.apache.catalina.valves.RemoteIpValve"\n\t\tremoteIpHeader="x-forwarded-for"\n\t\tproxiesHeader="x-forwarded-by"\n\t\tprotocolHeader="x-forwarded-proto"/>' \
$CATALINA_HOME/conf/server.xml \
&& ln -sf /usr/local/bin/entrypoint.sh $CATALINA_HOME/bin/entrypoint.sh \
EOF
fi
# final
cat >> ./$Dockerfile <<"EOF"
&& ln -sf /usr/local/src/confdownload/confcenterdownload /usr/local/bin/confcenterdownload \
&& chmod +x /usr/bin/dumb-init /usr/local/bin/* \
&& /bin/rm -rf /tmp/* /var/cache/apk/*
EOF
if [[ "$TYPE" == "tomcat" ]]; then
cat >> ./$Dockerfile <<"EOF"
EXPOSE 8080
ENTRYPOINT ["/usr/bin/dumb-init", "--", "entrypoint.sh"]
CMD ["catalina.sh", "run"]
EOF
# for java
elif [[ "$TYPE" == "java" ]]; then
cat >> ./$Dockerfile << "EOF"
ENTRYPOINT ["/usr/bin/dumb-init", "--", "entrypoint.sh"]
CMD ["bash"]
EOF
fi
}
function build_image() {
#### Build image
# ####for JDK####
# if [[ "$JAVA_TYPE" == "jre" ]]; then
# echo "jdk" > .dockerignore
# elif [[ "$TYPE" == "tomcat" ]] && [[ "$JAVA_TYPE" == "jdk" ]]; then
# echo `ls jdk/apache-tomcat-* | grep -v $TOMCAT_VERSION` | sed 's/ /\n/g' > .dockerignore
# echo `ls jdk/jdk-* | grep -v ${JAVA_MAJOR}u` | sed 's/ /\n/g' >> .dockerignore
# elif [[ "$TYPE" == "java" ]]; then
# echo `ls jdk/apache-tomcat-*` | sed 's/ /\n/g' > .dockerignore
# echo `ls jdk/jdk-* | grep -v ${JAVA_MAJOR}u` | sed 's/ /\n/g' >> .dockerignore
# fi
docker build --rm -t $FULL_IMAGE_NAME -f $Dockerfile . && docker push $FULL_IMAGE_NAME 1>/dev/null
if [[ $? == 0 ]]; then
echo "====> ${FULL_IMAGE_NAME} Builded and Pushed successfully.<====" | tee -a ${logfile}
else
echo "====> ${FULL_IMAGE_NAME} Builded Or Pushed failed!<====" | tee -a ${logfile}
exit 1
fi
}
main() {
echo "========================== Build Info ====================================" | tee -a ${logfile}
echo "--> $build_date Building ${FULL_IMAGE_NAME}..." | tee -a ${logfile}
vs=`echo $IMAGE_NAME|sed 's/,/ /g'`
for v in `echo $vs`;do
create_dockerfile $v
build_image
done
echo "==============================END=========================================" | tee -a ${logfile}
}
main
cat ${logfile}