前一篇文章介紹了Dockerfile的關鍵字的意義,接下來要來介紹他到底是怎麼運作的了
一樣附上前一篇的腳本
FROM golang:1.23-bookworm AS builder
WORKDIR /app
COPY go.mod ./go.mod
COPY go.sum ./go.sum
RUN go mod download
COPY . .
RUN GOOS=linux go build -o /app/backend
FROM ubuntu:22.04
WORKDIR /app
COPY --from=builder /app/backend /backend
EXPOSE 5000
CMD ["/backend"]
首先,當你執行build的時候,你會看到terminal上會一行一行的跳出你預先寫好的指令,並且看到執行這些指令的output,而這個每一行都會是一個小小的積木,而最終你要使用的image就會是這些積木拼出來的成品,而上面這些內容代表的是,這裡面的每一行,如果裡面異動到的檔案是沒有更動,Dockerfile的指令也沒變,那這些內容就會被快取,最常見的使用情境就是用在安裝一些第三方依賴套件
舉個例子
在golang中,go.mod跟go.sum就很像是node的package.json跟package.lock,python的requirement.txt,他是定義你所依賴的第三方套件的文字檔
在下方兩個Dockerfile,他都是要build出一個執行檔,但這兩個Dockerfile當你在開發時,每次開發測試時,你會異動你的程式檔,所以會導致複製進去的檔案會有異動,但此時的go.mod跟go.sum卻不會動,所以當你採用方案一,每次改完程式碼重新build image時,就不用重新從網路上拉一次第三方套件,可以直接用快取好的內容開始build,大大節省了時間跟流量
方案一
FROM golang:1.23-bookworm AS builder
WORKDIR /app
COPY go.mod ./go.mod
COPY go.sum ./go.sum
RUN go mod download <-以上內容都會被快取
COPY . .
RUN GOOS=linux go build -o /app/backend
方案二
FROM golang:1.23-bookworm AS builder
WORKDIR /app <-以上內容都會被快取
COPY . .
RUN go mod download <- 這行就沒有辦法被快取
RUN GOOS=linux go build -o /app/backend