咱們能夠了解到,鏡像的定製實際上就是定製每一層所添加的配置、文件。若是咱們能夠把每一層修改、安裝、構建、操做的命令都寫入一個腳本,用這個腳原本構建、定製鏡像,那麼以前說起的沒法重複的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就Dockerfile。
Dockerfile 是一個文本文件,其內包含了一條條的 指令(Instruction),每一條指令構建一層,所以每一條指令的內容,就是描述該層應當如何構建。接下來以nginx爲列經過Dockerfile文件來制定鏡像。php
在一個空白目錄中,創建一個文本文件,並命名爲 Dockerfile :html
$ mkdir mynginx $ cd mynginx $ touch Dockerfile
Dockerfile內容以下:
這個 Dockerfile 很簡單,一共就兩行。涉及到了兩條指令, FROM 和 RUN 。接下來就先了解這兩個指令。node
FROM指令的目的就是來指定基礎鏡像。python
所謂定製鏡像,那必定是以一個鏡像爲基礎,在其上進行定製。而FROM就是指定基礎鏡像,所以一個 Dockerfile 中 FROM 是必備的指令,而且必須是第一條指令。mysql
在 Docker Hub 上有很是多的高質量的官方鏡像,有能夠直接拿來使用的服務類的鏡像,如 nginx 、 redis 、 mongo 、 mysql 、 httpd 、 php 、 tomcat等;也有一些方便開發、構建、運行各類語言應用的鏡像,如node 、 openjdk 、 python 、 ruby 、 golang 等。能夠在其中尋找一個最符合咱們最終目標的鏡像爲基礎鏡像進行定製。nginx
RUN 指令是用來執行命令行命令的。因爲命令行的強大能力, RUN 指令在定製鏡像時是最經常使用的指令之一。其格式有兩種:golang
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
前面的文章有說過,Dockerfile 中每個指令都會創建一層, RUN 也不例外。每個RUN 的行爲,就和剛纔咱們手工創建鏡像的過程同樣:新創建一層,在其上執行這些命令,執行結束後, commit 這一層的修改,構成新的鏡像。redis
這裏咱們使用了 docker build 命令進行鏡像構建。其格式爲:sql
docker build [選項] <上下文路徑/URL/->
在這裏咱們指定了最終鏡像的名稱 -t nginx:v2 ,構建成功後,就能夠運行這個鏡像了。docker
在Dockerfile所在目錄執行以下圖命令來進行鏡像的構建:
從命令的輸出結果中,咱們能夠清晰的看到鏡像的構建過程。在 Step 2/2 中,如同咱們以前所說的那樣, RUN 指令啓動了一個容器 7c6c2f17c3fc ,執行了所要求的命令,並最後提交了這一層 c3d8143457af,隨後刪除了所用到的這個容器 7c6c2f17c3fc 。
能夠看到,咱們剛纔構建的ngnix:v2鏡像就已存在了,那麼就能夠以這個鏡像爲基礎啓動一個容器
這裏再次簡單說下運行一個容器的命令:
mynginx-test 容器名稱。 -d 設置容器在在後臺一直運行。 -p 端口進行映射,將本地 80 端口映射到容器內部的 80 端口。
最後咱們在瀏覽器輸入localhost就能夠在網頁中看到經過Dockerfile文件構建鏡像的文本了。
這裏看到了內容出現編碼致使亂碼的問題,這是由於多數docker基礎鏡像使用locale查看編碼,發現默認編碼都是POSIX,這會致使中文亂碼。解決方法以下:
首先使用locale -a查看容器全部語言環境
其次,dockerfile中加入如下參數從新生成鏡像
ENV LANG=en_US.UTF-8
ENV TZ=Asia/Shanghai
若是有 en_US.utf8 優先使用