DevOps CI/CD 分析(二)之编写Dockerfile文件

本节我们开始编写Dockerfile文件,编写Dockerfile所涉及相关命令都在前面的文章进行过讲解,如果对Dockerfile基础命令不熟悉可以参阅DevOps CI/CD 分析(一)之Dockerfile基础命令,熟悉基础命令之后,可以让我们快速理解本节的内容!


Dockerfile

FROM maven:3.6.1-jdk-8 AS mavenBuilder
MAINTAINER userName 
WORKDIR /mavenBuild
ENV MAVEN_REPO "-Dmaven.repo.local=/mavenBuild/.m2"
ARG PROJECT_SERVER_DIR
ADD ./ /mavenBuild/
RUN mvn $MAVEN_REPO clean package
RUN cp $PROJECT_SERVER_DIR/target/*.jar /server.jar

FROM registry-vpc.cn-beijing.aliyuncs.com/company/openjdk:8u222-jdk-v1.2
WORKDIR /data
ENV SERVER_PORT 80
EXPOSE $SERVER_PORT
ENV RAMPERCENTAGE 75.0
COPY --from=mavenBuilder /mavenBuild/entrypoint.sh /data/entrypoint.sh
RUN chmod +x /data/entrypoint.sh && \
    groupadd -r java_group && \
    useradd -m -r -g java_group java_user
COPY --from=mavenBuilder server.jar /data/server.jar
RUN chown -R java_user:java_group /data
USER java_user:java_group
ENTRYPOINT ["/data/entrypoint.sh"]

代码块中展示了Dockerfile文件的内容,或许单看这个Dockerfile文件内容,不利于理解,所以为了帮助大家更好的理解整个Dockerfile文件内容,下面我们对每一行都进行讲解!


Dockerfile内容详解

  1. FROM maven:3.6.1-jdk-8 AS mavenBuilder 指定基础镜像,扩展的基础镜像,在遇到下一个FROM命令之前,我们的命令执行都在这个基础镜像中,然后我们给这个基础镜像起一个mavenBuilder别名,便于后续使用。
  2. MAINTAINER userName [email protected] 指定镜像的作者,主要是用于标志而已。
  3. WORKDIR /mavenBuild 指定我们执行RUN命令的工作目录,因为我们这个基础镜像是需要编译我们的Java项目,所以我们指定一个mavenBuild目录用于编译。
  4. ENV MAVEN_REPO "-Dmaven.repo.local=/mavenBuild/.m2" 设置一个环境变量,主要是用于设置我们执行maven的仓库目录,我们的maven仓库也还是放到/mavenBuild/.m2 这个目录中。
  5. ARG PROJECT_SERVER_DIR 定义一个参数,因为我们的每个项目的路径是不同的,所以需要定义一个参数,在gitlab-ci.yml文件中执行docker build --build-arg PROJECT_SERVER_DIR=项目路径,执行docker build时传入进来的。
  6. ADD ./ /mavenBuild/ 将当前主机目录中的文件添加到我们mavenBuilder这个基础镜像中,也就是把我们项目源代码等文件添加到/mavenBuild/这个目录。
  7. RUN mvn $MAVEN_REPO clean package 执行maven命令编译项目,我们可以看见我们使用$ 这个符号来使用我们之前定义的值。
  8. RUN cp $PROJECT_SERVER_DIR/target/*.jar /server.jar 将我们编译完成的jar包文件拷贝到基础镜像的/server.jar中。
  9. FROM registry-vpc.cn-beijing.aliyuncs.com/company/openjdk:8u222-jdk-v1.2 指定我们的运行环境的基础镜像了,这里我们是基于阿里云的openjdk:8u222-jdk-v1.2基础镜像。其中company 这个值需要替换成真实的路径。
  10. WORKDIR /data 指定工作目录,我们目前是使用基础openjdk:8u222-jdk-v1.2的 /data目录
  11. ENV SERVER_PORT 80 定义我们的端口环境变量值
  12. EXPOSE $SERVER_PORT 设置openjdk:8u222-jdk-v1.2容器内的进程对外开放的端口,这里我们开放的是80端口。
  13. ENV RAMPERCENTAGE 75.0 设置一个JVM相关的配置,这个参数会在entrypoint.sh中用到,下文会解释参数的作用。
  14. COPY --from=mavenBuilder /mavenBuild/entrypoint.sh /data/entrypoint.sh 我们通过--from=mavenBuilder 指定要从哪个镜像中拷贝文件,这里我们从mavenBuilder这个镜像中拷贝/mavenBuild/entrypoint.sh到openjdk:8u222-jdk-v1.2这个镜像的/data/entrypoint.sh目录。
  15. RUN chmod +x /data/entrypoint.sh &&
    groupadd -r java_group &&
    useradd -m -r -g java_group java_user 一个shell命令,增加一个java_group的组,然后给这个组添加一个用户为java_user,然后设置这个java_group组的java_user具备/data/entrypoint.sh 脚本执行权限
  16. COPY --from=mavenBuilder server.jar /data/server.jar 从mavenBuilder镜像中拷贝server.jar到openjdk:8u222-jdk-v1.2镜像的/data/server.jar 文件中。
  17. RUN chown -R java_user:java_group /data 将指定文件的拥有者改为指定的用户或组,这里我们就把/data这个文件指定给了 java_user:java_group这个组的用户。
  18. USER java_user:java_group 设置容器启动时的用户。
  19. ENTRYPOINT ["/data/entrypoint.sh"] 容器启动时执行的命令 ,entrypoint.sh脚本文件往下看。

entrypoint.sh

#!/bin/sh
## shell打印字体加粗和绿色
GREEN="\033[1;32m"
END="\033[0m"
JAVA_OPTS="-DJM.LOG.PATH=/data/logs -DJM.SNAPSHOT.PATH=/data/logs"

echoWrap() {
    echo "${GREEN}$1${END}"
}

echoWrap "entrypoint.sh begin running"
if [ $RAMPERCENTAGE ]; then
    echoWrap "append RAMPERCENTAGE $RAMPERCENTAGE to JAVA_OPTS"
    JAVA_OPTS="$JAVA_OPTS -XX:InitialRAMPercentage=$RAMPERCENTAGE -XX:MaxRAMPercentage=$RAMPERCENTAGE -XX:MinRAMPercentage=$RAMPERCENTAGE"
fi

echoWrap "------------------------ running java jar -----------------------------"
java $JAVA_OPTS -jar server.jar $*

我们可以看到,ENTRYPOINT ["/data/entrypoint.sh"] 容器启动时执行的命令,在entrypoint.sh这个脚本中,我们添加了一些JVM参数,然后启动我们的server.jar 运行我们的应用程序,其中有个比较重要的一点,就是设置-XX:InitialRAMPercentage 这些参数,具体为什么要设置可以参阅至少保证容器拥有512M 的内存可以用在非heap堆内存。


至此,本节的核心重点=>编写Dockerfile也告一段落,整个Dockfile文件内容也做了充分的讲解,相信这样的讲解会帮助绝大多数同学,也可以更好的理解我们后续CI/CD章节的内容!

你可能感兴趣的:(DevOps CI/CD 分析(二)之编写Dockerfile文件)