# Docker入門教程(三)Dockerfile
> 【編者的話】DockerOne組織翻譯了Flux7的Docker入門教程,本文是系列入門教程的第三篇,介紹了Dockerfile的語法,DockerOne目前在代碼高亮部分還有些Bug,我們會盡快修復,目前在代碼部分有會些字符會被轉義。
在[Docker系列教程的上一篇文章](http://dockerone.com/article/102)中,我們介紹了15個Docker命令,你應該對Docker有個大致的了解了。那15個命令在手動創建鏡像時會用到,它們涵蓋了鏡像的創建、提交、搜索、pull和push的功能。
現在問題來了,既然Docker能自動創建鏡像,那為什么要選擇耗時而又乏味的方式來創建鏡像呢?
Docker為我們提供了Dockerfile來解決自動化的問題。在這篇文章中,我們將討論什么是Dockerfile,它能夠做到的事情以及Dockerfile的一些基本語法。
### 易于自動化的命令
Dockerfile包含創建鏡像所需要的全部指令。基于在Dockerfile中的指令,我們可以使用`Docker build`命令來創建鏡像。通過減少鏡像和容器的創建過程來簡化部署。
Dockerfile支持支持的語法命令如下:
~~~
INSTRUCTION?argument
~~~
指令不區分大小寫。但是,命名約定為全部大寫。
所有Dockerfile都必須以`FROM`命令開始。?`FROM`命令會指定鏡像基于哪個基礎鏡像創建,接下來的命令也會基于這個基礎鏡像(譯者注:CentOS和Ubuntu有些命令可是不一樣的)。`FROM`命令可以多次使用,表示會創建多個鏡像。具體語法如下:
~~~
FROM?<image?name>
~~~
例如:
~~~
FROM?ubuntu
~~~
上面的指定告訴我們,新的鏡像將基于Ubuntu的鏡像來構建。
繼`FROM`命令,DockefFile還提供了一些其它的命令以實現自動化。在文本文件或Dockerfile文件中這些命令的順序就是它們被執行的順序。
讓我們了解一下這些有趣的Dockerfile命令吧。
1\. MAINTAINER:設置該鏡像的作者。語法如下:
~~~
MAINTAINER?<author?name>
~~~
2\. RUN:在shell或者exec的環境下執行的命令。`RUN`指令會在新創建的鏡像上添加新的層面,接下來提交的結果用在Dockerfile的下一條指令中。語法如下:
~~~
RUN?《command》
~~~
3\. ADD:復制文件指令。它有兩個參數和。destination是容器內的路徑。source可以是URL或者是啟動配置上下文中的一個文件。語法如下:
~~~
ADD?《src》?《destination》
~~~
4\. CMD:提供了容器默認的執行命令。 Dockerfile只允許使用一次CMD指令。 使用多個CMD會抵消之前所有的指令,只有最后一個指令生效。 CMD有三種形式:
~~~
CMD?["executable","param1","param2"]
CMD?["param1","param2"]
CMD?command?param1?param2
~~~
5\. EXPOSE:指定容器在運行時監聽的端口。語法如下:
~~~
EXPOSE?<port>;
~~~
6\. ENTRYPOINT:配置給容器一個可執行的命令,這意味著在每次使用鏡像創建容器時一個特定的應用程序可以被設置為默認程序。同時也意味著該鏡像每次被調用時僅能運行指定的應用。類似于`CMD`,Docker只允許一個ENTRYPOINT,多個ENTRYPOINT會抵消之前所有的指令,只執行最后的ENTRYPOINT指令。語法如下:
~~~
ENTRYPOINT?["executable",?"param1","param2"]
ENTRYPOINT?command?param1?param2
~~~
7\. WORKDIR:指定`RUN`、`CMD`與`ENTRYPOINT`命令的工作目錄。語法如下:
~~~
WORKDIR?/path/to/workdir
~~~
8\. ENV:設置環境變量。它們使用鍵值對,增加運行程序的靈活性。語法如下:
~~~
ENV?<key>?<value>
~~~
9\. USER:鏡像正在運行時設置一個UID。語法如下:
~~~
USER?<uid>
~~~
10\. VOLUME:授權訪問從容器內到主機上的目錄。語法如下:
~~~
VOLUME?["/data"]
~~~
### Dockerfile最佳實踐
與使用的其他任何應用程序一樣,總會有可以遵循的最佳實踐。你可以閱讀更多有關[Dockerfile的最佳實踐](http://crosbymichael.com/dockerfile-best-practices.html)。
以下是我們列出的基本的Dockerfile最佳實踐:
* 保持常見的指令像`MAINTAINER`以及從上至下更新Dockerfile命令;
* 當構建鏡像時使用可理解的標簽,以便更好地管理鏡像;
* 避免在Dockerfile中映射公有端口;
* `CMD`與`ENTRYPOINT`命令請使用數組語法。
在接下來的文章中,我們將討論[Docker Registry及其工作流程](http://dockerone.com/article/104)。
> 出處:http://dockone.io/article/103
> 原文鏈接:[Part 3: Automation is the word using Dockerfile](http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)(翻譯:[田浩浩](https://github.com/llitfkitfk)?審校:李穎杰)