鏡像的Layer
在docker docs里面有一句話:
We’ve already seen that Docker images are read-only templates from which Docker containers are launched. Each image consists of a series of layers. Docker makes use of union file systems to combine these layers into a single image. Union file systems allow files and directories of separate file systems, known as branches, to be transparently overlaid, forming a single coherent file system.
對于docker的images,是由一層層的layer組成的,然后通過聯合掛載的方式掛載成一個文件系統。
假設你有以下的dockerfile:
FROM ubuntu
ENV http_proxy 10.144.xx.xx:8080
ENTRYPOINT ["/usr/bin/bash"]
首先你選擇了基礎鏡像ubuntu,這個鏡像有很多層。可以從/val/lib/docker下面找到該鏡像的信息和每一層的信息。
然后ENV是設置了一個環境變量,這句命令同樣會產生一個layer,再然后就是需要執行的命令,同樣會產生一個layer。如果你更改了某一層的信息,那么從這層之后所有的層都需要重新build。
更多的關于docker images的原理,可以自行百度。
DockerFile的ARG和ENV
ARG主要是定義一個變量,在你使用docker build的時候可以通過參數來設定。
docker build --build-arg <varname>=<value>
因此如果你需要在build期間使用某些變量,那么ARG是最好的選擇。
如果你是想在運行期間使用,那么ENV是唯一的選擇。
ENV主要是定義環境變量,在docker run的時候ENV的配置會加載到容易內部,但ARG的參數在內部是沒法看到的。同時也可以通過下面命令更改ENV的默認值:
docker run -e var=yyy
這個時候就就可以兩者結合使用。
ARG var
ENV var=${var}
在dockerfile內部可以這樣控制命令的參數。
ARG protocal
ARG address
ARG port
ENV protocal=${protocal} \
address=${address} \
port=${port}
CMD /usr/bin/lightweightservicediscovery --listen=${PROTOCAL:-ipv4}:${ADDRESS:-0.0.0.0}:${port:-49188}
//如果讀取環境變量失敗再采用后面的默認值。
這樣既可以在build的時候通過docker build --build-arg var=xxx 來傳遞參數,也可以通過在運行的時候通過docker run -e var=yyy 來傳遞參數。
https://stackoverflow.com/questions/31222377/what-are-docker-image-layers/33836848#33836848
https://stackoverflow.com/questions/41916386/arg-or-env-which-one-to-use-in-this-case
https://stackoverflow.com/questions/33935807/how-to-define-a-variable-in-a-dockerfile/33936014#33936014
https://docs.docker.com/engine/reference/builder/#arg