iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
DevOps

其實沒有那麼難 — Docker系列 第 3

D3 - Docker Image ft. node image 差異

  • 分享至 

  • xImage
  •  

今天我們來深入做點研究,

以前就發現,一項官方的 docker image,總是會有很多不同的 image 版本,
其中有什麼差異,一直都沒有仔細研究,今天就讓我們來觀察看看,Node.Js 的官方 image。


Docker Image

在昨天的文章中,我們建立一個自己的 docker image,
在 Docker 的世界中,所有的應用程式要改用 Docker 執行,就需要先建置成 Docker Image,

定義如何建置的檔案就叫 Dockerfile,其中可以看到第一行總是寫了 FROM 這個關鍵字,意思是新的 Image 是要基於哪一個現有的 Docker image 來製作,又可以稱為 Base Image,

因為我們是用 JavaScript 寫,所以使用了 node image 作為 base image。


Node Official Image

進到 Node.Js 官方 Image 的頁面後,可以看到一整排的版本編號 (aka. image tag),同一排的都是同一個 image,只是定義了多個別名 (tag),

方便起見,我只探討 Long-term support (LTS) 的版本,而目前 Node.JS 本身的 LTS 版本是 16,因此我們只看 lts-xxx 的 image 版本,可以依序看到:

  1. lts-apline3.15
  2. lts-alpine
  3. lts-bullseye
  4. lts-bullseye-slim
  5. lts (lts-buster)
  6. lts-slim (lts-buster-slim)

Image 差異

這些 Image 同樣都可以用來執行 Node.Js 的程式,那它們到底有什麼不一樣呢?

想要深入看 image 的內容,不一定需要實際把 image 跑起來,大部分開源的 docker image 都可以找到 Dockerfile,那我們從 lts 開始,

node image 目前的 lts 被放在 lts-buster 上,buster 是什麼意思呢? 在 Google 搜尋前,我們先找找其他線索,

Base Image

可以看到在 lts-buster 的 Dockerfile 中,定義它是基於一個叫 buildpack-deps:buster 的 docker image,而它又基於 buildpack-deps:buster-scm image。

# node:lts-buster  Dockerfile

FROM buildpack-deps:buster

RUN groupadd --gid 1000 node \
...
ENTRYPOINT ["docker-entrypoint.sh"]

CMD [ "node" ]
# buildpack-deps:buster  Dockerfile

FROM buildpack-deps:buster-scm

RUN set -ex; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
	...

就這樣一路追查下去,會發現它的源頭是基於 debian image,並且 debian 基於 scratch image,

# debian:buster  Dockerfile

FROM scratch
ADD rootfs.tar.xz /
CMD ["bash"]

關於 base image 的線索就到此為止,因為 scratch 不會再有 base image,為什麼呢?

原來 scratch 在 Docker 中是有特殊意義的,它並不是一個真實存在的 docker image,而是代指「空的內容」,所有 docker image 最源頭都是基於它 [1],

OK,那我們可以往回查了,下面一位:debian image,
Debian 本身是一個非常追求穩定的 Linux 發行版本,很適合作為 Server 使用,
而 debian image 就是基於 Debian 版本來製作的 docker image。

接著我們可以找到 Debian 的版本號列表,現在的 LTS 版本號 10 就叫做 buster,下一版 11 叫做 bullseye
這裡就可以對應回 node 的 docker image 版本名稱了,所以 lts-busterlts-bullseye 其實就是由不同的 Debian 製作而來的,

再下一位:buildpack-deps,看 image 的描述,似乎是幫我們裝了一些開發或執行的軟體,

It includes a large number of "development header" packages needed by various things like Ruby Gems, PyPI modules, etc.

所以說,node:lts 就是基於 Debian 10 (buster) 加上一些工具所組成的 docker image,

xxx-slim

那麼 lts-slim 呢?

lts-slim 目前也叫 lts-buster-slim,所以可以知道它是基於 Debian 10,根據 Dockerfile 可以接著追查到 debian:buster-slim image,

# node:lts-buster-slim

FROM debian:buster-slim
...
# debian:buster-slim Dockerfile

FROM scratch
ADD rootfs.tar.xz /
CMD ["bash"]

所以可以知道,node image 的 ltslts-slim 之間的差異,主要在於沒有加入 buildpack-deps 的那些開發工具,lts-slim 是個相較輕量的 Node.Js image 版本。

Alpine

最後輪到了 lts-alpine image,它是一個基於 Alpine image 的版本,alpine image 本身極度輕量化,只有 5 MB,
但我就不針對 Alpine 多做介紹了,有興趣的讀者可以深入去瞭解 Alpine 的細節。

Image Size

我們把這些 image 都 pull 下來看看,觀察一下大小:

$ sudo docker images

REPOSITORY   TAG                 IMAGE ID       CREATED       SIZE
node         lts-buster-slim     572389d8c38d   5 days ago    179MB
node         lts-slim            572389d8c38d   5 days ago    179MB
node         lts                 e90654c39524   5 days ago    911MB
node         lts-buster          e90654c39524   5 days ago    911MB
node         lts-bullseye-slim   8e4ba45a6265   5 days ago    191MB
node         lts-bullseye        e707a730fc3b   5 days ago    941MB
debian       stable-slim         65114df9fe5c   5 days ago    80.5MB
debian       stable              9b4953ae981c   5 days ago    124MB
node         lts-alpine          5dcd1f6157bd   4 weeks ago   115MB
alpine       latest              9c6f07244728   5 weeks ago   5.54MB

可以看到 node image 中,最小的是 lts-alpine 115MB,其次是 lts-slim 179MB,而 lts 本身則是大其他者非常多:911MB。


要選哪一個

最後,
在大致瞭解它們的差異之後,那我們應該要選哪一個 node iamge 版本來使用呢?以下是我個人的主觀意見:

在大部分情況,優先使用 lts-slim,既輕量,又可以完成大部分的事情,

如果想要或需要去追求極致的輕量化,那就使用 lts-alpine

其他有什麼其他理由,就依照當下情境所需跟個人喜好來選擇了,沒有一定的標準,
那我們結束今天對 docker image 的研究,明天見。


Ref

  1. Stack Overflow - What is docker's scratch image?

上一篇
D2 - Hello world
下一篇
D4 - Docker Installation
系列文
其實沒有那麼難 — Docker30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言