官方文檔地址:https://docs.docker.com/engine/reference/builder/
Dockerfile是一個文本格式的配置文件,其內容包含衆多指令,用戶可使用它快速的建立自定義鏡像。linux
指令 | 做用 | 備註 |
---|---|---|
FROM | 指定基礎鏡像 | 任何Dockerfile中的第一條指令都必須是FROM 一個文件中能夠存在多個FROM指令。 |
LABEL | 爲鏡像添加元數據標籤信息。 | |
ARG | 定義建立鏡像過程當中使用的變量,編譯成功後不存在。 | 在運行docker build時,指定--builder-arg爲變量賦值。 |
ENV | 設置環境變量 | 在鏡像啓動時也會存在。 docker run --env key=value 會覆蓋同名變量 |
WORKDIR | 指定工做目錄 | 可使用多個,建議使用絕對路徑。 |
VOLUME | 建立數據卷掛載點 | 例如VOLUME ["/data/a","/data/b"] |
EXPOSE | 聲明鏡像內服務監聽的端口 | 只起聲明做用,不會自動完成映射。 |
USER | 指定運行容器時的用戶名或ID | 後續RUN指令也會以這個用戶身份運行。 |
STOPSIGNAL | 指定所建立鏡像啓動的容器接收退出的信號值 |
COPY src dst / ADD src dst
其相同點是:做用都是複製內容到鏡像中;dst不存在時會建立;路徑支持正則。
不一樣點在於:golang
除了目的明確是要將一個URL或者tar文件做爲src的狀況下,其餘狀況推薦使用COPY。docker
CMD與ENTRYPOINT兩種方式都支持,但推薦使用exec方式。shell
在任意一個Dockerfile下:ubuntu
finallyCommand = "" if exists(ENTRYPOINT) { finallyCommand = ENTRYPOINT if exists(dockerRunCommandParam){ // 情景一 finallyCommand += dockerRunCommandParam }elseif exists(CMD) { // 情景二。除了CMD指令自己,包括後面JSON數組全部 finallyCommand += CMDParams } // 情景三 }elseif exists(dockerRunCommandParam){ // 情景四 finallyCommand = dockerRunCommandParams }elseif exists(CMD){ // 情景五 finallyCommand = CMD }
總結起來一句話:有ENTRYPOINT,CMD和docker run指定的命令都做爲參數追加到ENTRYPOINT的參數後;沒有ENTRYPOINT,docker run指定了命令就執行,不然執行CMD(若是有的話)。數組
Dockerfile內容、構建鏡像緩存
FROM alpine:latest ENTRYPOINT ["/bin/echo","entrypoint"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景三 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test entrypoint // 情景一 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test 12 34 entrypoint 12 34
Dockerfile添加CMD指令、構建鏡像bash
FROM alpine:latest ENTRYPOINT ["/bin/echo","entrypoint"] CMD ["/bin/echo","cmd"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景二:CMD中的 "/bin/echo" 沒有被當作命令執行,而是與"cmd"一塊兒成爲了ENTRYPOINT的參數。 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test entrypoint /bin/echo cmd
Dockerfile刪除ENTRYPOINT指令、構建鏡像app
FROM alpine:latest CMD ["/bin/echo","cmd"] -> [feifei@ffmac.local] [~/work/docker] docker build -t test . // 情景五 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test cmd // 情景四 -> [feifei@ffmac.local] [~/work/docker] docker run --rm test echo 33 33
exec方式:RUN ["executable","param1","param2"]
shell方式:RUN command param1 param2
每條RUN指令將在當前鏡像基礎上執行指令,而且提交爲新的鏡像層。當命令較長時可使用\來換行ui
ONBUILD [INSTRUCTION]
做爲父鏡像被使用時自動執行的命令。對孫子鏡像無效。可用於自動編譯,檢查等。
假如父鏡像ParentImage的Dockerfile中有以下指令:
ONBUILD RUN mkdir /root/test
使用docker build基於ParentImage建立子鏡像ChildImage的時候,會先執行ParentImage中的ONBUILD指令。等價於在ChildImage中添加了:
RUN mkdir /root/test
健康檢查
HEALTHCHECK [OPTIONS] CMD command :根據執行命令返回值判斷,0是成功,1是不健康。
HEALTHCHECK NONE :禁止健康檢查
OPTIONS參數以下:
docker build [OPTIONS] PATH | URL | -
該命令默認讀取指定路徑下的Dockerfile(也可以使用 -f 指定),並將該路徑下的全部數據做爲上下文發送給Docker服務端。逐條執行指令,生成鏡像。
通常狀況下都須要使用FROM來指定父鏡像,因此父鏡像會影響到新生成鏡像的大小和功能。
一般有兩種鏡像可做爲父鏡像:基礎鏡像和普通鏡像(由第三方建立,基於基礎鏡像)。基礎鏡像通常是基於scratch或者Dockerfile中不存在FROM指令。
對於編譯型語言一般須要編譯環境和運行環境兩個鏡像:
app.go
package main import "fmt" func main() { fmt.Println("Hello World") }
Dockerfile中使用兩次FROM
FROM golang:1.14-alpine as builder WORKDIR /go/src/test COPY app.go . RUN CGO_ENABLED=0 GOOS=linux go build -o app app.go FROM alpine:latest COPY --from=builder /go/src/test/app /root/ #此處 --from=builder 也能夠改成 --from=0 CMD ["/root/app"]
構建、運行
-> [feifei@ffmac.local] [~/work/docker] docker build -t hello . -> [feifei@ffmac.local] [~/work/docker] docker run --rm hello Hello World
多階段構建會生成編譯環境鏡像,也會將以前的同名鏡像變爲<none>:<none>
,清理此類鏡像可執行如下命令:
docker rmi $(docker images --filter dangling=true -q)
COPY指令的--from選項也能夠指定本地或者遠程倉庫的鏡像
準備一個Dockerfile,內容是從ubuntu鏡像中COPY一個文件到新鏡像的/root/下
FROM alpine:latest COPY --from=ubuntu:latest /bin/bash /root/ CMD ["/bin/ls","/root/"]
dokcer build 構建鏡像
-> [feifei@ffmac.local] [~/work/docker] docker build -t test . Sending build context to Docker daemon 19.46kB Step 1/3 : FROM alpine:latest ---> f70734b6a266 Step 2/3 : COPY --from=ubuntu:latest /bin/bash /root/ latest: Pulling from library/ubuntu d51af753c3d3: Pull complete fc878cd0a91c: Pull complete 6154df8ff988: Pull complete fee5db0ff82f: Pull complete Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7 Status: Downloaded newer image for ubuntu:latest ---> Using cache ---> 082f95ffaa69 Step 3/3 : CMD ["/bin/ls","/root/"] ---> Using cache ---> 76fa9d9a1abd Successfully built 76fa9d9a1abd Successfully tagged test:latest
dokcer run 運行鏡像
-> [feifei@ffmac.local] [~/work/docker] docker run --rm test bash
.dockerignore
文件,避免發送沒必要要的數據