使用 Dockerfile 定制鏡像
鏡像的定制實際上就是定制每一層所添加的配置、文件。如果我們可以把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定制鏡像,那么無法重復的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就是 Dockerfile。
Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。
此處以定制 nginx 鏡像為例,使用 Dockerfile 來定制。
在一個空白目錄中,建立一個文本文件,并命名為 Dockerfile :
$ mkdir mynginx$ cd mynginx$ touch Dockerfile
其內容為:
FROM nginxRUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
這個 Dockerfile 很簡單,一共就兩行。涉及到了兩條指令, FROM 和 RUN 。
Dockerfile 指令詳解
FROM 指定基礎鏡像
所謂定制鏡像,那一定是以一個鏡像為基礎,在其上進行定制。而 FROM 就是指定基礎鏡像,因此一個 Dockerfile 中 FROM 是必備的指令,并且必須是第一條指令。
在 Docker Store 上有非常多的高質量的官方鏡像,有可以直接拿來使用的服務類的鏡像,如nginx 、 redis 、 mongo 、mysql 等;也有一些方便開發、構建、運行各種語言應用的鏡像,如 node 、 openjdk 、 python 等??梢栽谄渲袑ふ乙粋€最符合我們最終目標的鏡像為基礎鏡像進行定制。
如果沒有找到對應服務的鏡像,官方鏡像中還提供了一些更為基礎的操作系統鏡像,如ubuntu 、 debian 、 centos 等,這些操作系統的軟件庫為我們提供了更廣闊的擴展空間。
除了選擇現有鏡像為基礎鏡像外,Docker 還存在一個特殊的鏡像,名為 scratch 。這個鏡像是虛擬的概念,并不實際存在,它表示一個空白的鏡像。
FROM scratch...
如果你以 scratch 為基礎鏡像的話,意味著你不以任何鏡像為基礎,接下來所寫的指令將作為鏡像第一層開始存在。
不以任何系統為基礎,直接將可執行文件復制進鏡像的做法并不罕見,比如 swarm 、 coreos/etcd 。對于 Linux 下靜態編譯的程序來說,并不需要有操作系統提供運行時支持,所需的一切庫都已經在可執行文件里了,因此直接 FROM scratch 會讓鏡像體積更加小巧。使用 Go 語言 開發的應用很多會使用這種方式來制作鏡像,這也是為什么有人認為 Go是特別適合容器微服務架構的語言的原因之一。
RUN 執行命令
RUN 指令是用來執行命令行命令的。由于命令行的強大能力, RUN 指令在定制鏡像時是最常用的指令之一。其格式有兩種:
shell 格式: RUN <命令> ,就像直接在命令行中輸入的命令一樣。剛才寫的 Dockerfile 中的 RUN 指令就是這種格式。
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
exec 格式: RUN ["可執行文件", "參數1", "參數2"],這更像是函數調用中的格式。
既然 RUN 就像 Shell 腳本一樣可以執行命令,那么我們是否就可以像 Shell 腳本一樣把每個命令對應一個 RUN 呢?比如這樣:
FROM debian:jessieRUN apt-get updateRUN apt-get install -y gcc libc6-dev makeRUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"RUN mkdir -p /usr/src/redisRUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1RUN make -C /usr/src/redisRUN make -C /usr/src/redis install
新聞熱點
疑難解答