建构 Spring boot 容器 Image

要将自己开发的应用程序容器化,想必需要制作自己的 Image。制作 Image 也是一种艺术,我们要如何让自己的应用程序制造的 Image 能有更小的资源来使用。

我们都知道 Dockerfile 是建构 image 的档案。

下面这张图是 Dockerfile 可以使用的关键字

我觉得 cmdENTRYPOINT 这两个可以理解一下,我有时会搞混哈。在 Dockerfile 中,只能有一个 ENTRYPOINT 或 CMD 指令,如果有多个ENTRYPOINT 或 CMD 指令则以最後一个为准。

  • ENTRYPOINT
    • 往往用於设置容器启动後的第一个命令,这对一个容器来说往往是固定的。
    • 执行 docker run 如果带有其他命令参数,不会覆盖 ENTRYPOINT 指令
    • docker run 的 --entrypoint 可以覆盖 Dockerfile 中ENTRYPOINT 设置的命令。
  • CMD
    • 往往用於设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的。docker run 往往用於给出替换 CMD 的临时参数。
    • docker run 如果带有其他命令参数,将会覆盖 CMD 指令。
    • 如果在 Dockerfile 中,还有 ENTRYPOINT 指令,则 CMD 指令中的命令将作为 ENTRYPOINT 指令中的命令的参数。

下面是建立一个 Nginx Image 的 Dockerfile 范例

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y nginx

COPY . /var/www/html/

EXPOSE 80

#ENTRYPOINT ["nginx"]
CMD ["nginx", "-g", "daemon off;"]

有了 Dockerfile 後我们就可以建构 Image 了,使用 docker build -t {ImageName}:{tag01} . 建构

使用 docker images 查看建构的 image

REPOSITORY                                          TAG                 IMAGE ID            CREATED             SIZE
nginx                                               v0                  55077273116a        20 minutes ago      222MB

Image 原则上应该越小越好,下面范例则是会把一些类似快取的东西或是历史纪录给拔掉

FROM ubuntu:14.04
RUN apt-get update && apt-get install -y nginx \
        && rm -rf /var/lib/apt/lists/*
COPY . /var/www/html/
EXPOSE 80
#ENTRYPOINT ["nginx"]
CMD ["nginx", "-g", "daemon off;"]

最後 Image 减少了一些大小。

REPOSITORY                                          TAG                 IMAGE ID            CREATED             SIZE
nginx                                               v0.1                d17658937ea9        2 minutes ago       209MB

接下来直接给一个建构 Spring boot 的范例,专案如果是用 gradle 建立,应当会使用 gradle 进行建构和测试,所以我们使用了 gradle 进行第一层的建构和测试,当这一个 gradle 建构和测试结果成功後会有一个应用程序的 jar 档。

这边我们用运了 multi-stage 方式进行建构,这会使得 CICD 过程更加简易。後续要运行 Jar 档的 Image 透过指令(--from)取得前面键建构所产生的档案 (artifacts)。

FROM gradle:4.10.2-slim as builder
USER root
COPY . .
RUN gradle clean build

FROM  adoptopenjdk/openjdk8-openj9:jdk8u181-b13_openj9-0.9.0-slim
COPY --from=builder /home/gradle/build/libs/test-0.0.1-SNAPSHOT.jar /usr/local/test_workspace/test-0.0.1-SNAPSHOT.jar
RUN apt-get update && \
    apt-get install -y tzdata ttf-dejavu fontconfig && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    mkdir /usr/local/logs
ENV LANG C.UTF-8
# Timezone 
ENV TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "test-0.0.1-SNAPSHOT.jar"]
  1. 透过 multi-stage 使得 CICD 的过程更加简易
  2. FROM 的 Image 应当越小越好,也就是基本的环境应该只须包含需要的内容,这会使的 pull Image 速度更快,网路频宽不会占资源
  3. 在进行建构时应当将 RUN 关键字所安装的物件,进行快取的清除,使 Image 变得更小
  4. 权限应当做一个设置避免使用 root 最高权限

有关权限设置的内容可参考此链结


<<:  铁人赛 Day4 -- XAMPP到底有多神 & MySQL的安全性设定

>>:  DAY4 - 堆

Ruby 学习笔记簿:Metaprogramming Quizzes

Quiz: Missing Lines 题目说明: 下面程序码以图表方式呈现,可看出物件与类别之间的...

D4 第二周 (回忆篇)

今天会是比较划水的回忆篇,可以斟酌看看。 这周开始正式学习 javascript,然後那时候疫情还没...

Day 18 UItableView的练习 (2/3)

上一篇我们讲到建立一个UItable View的一些基本方法,接下来我们可以建立一些资料在上面 va...

第三十天:UI切版 & 元件-第五部分情境练习(注册表单、产品清单、登入页面)

铁人赛的最後一天 以三个前端比较常见的情境练习需求来总结第五部分 今天的内容 一、注册表单 二、产品...

【Day 01】认识资料结构 Data Structure ( 使用 JavaScript )

一、什麽是资料结构 ? 当我们撰写程序时,会宣告变数来存放资料,这些资料会储存在记忆体中,在我们需要...