1. 程式人生 > >Dockerfile格式以及Dockerfile示例

Dockerfile格式以及Dockerfile示例

 


Dockerfile建立映象 –Dockerfile語法

之前我們介紹過通過容器建立映象以及通過模板建立映象,除了這兩種方式之外,我們還可以通過Dockerfile去建立映象。

Dockerfile是由一系列命令和引數構成的指令碼,這些命令應用於基礎映象並最終建立一個新的映象。它們簡化了從頭到尾的流程並極大的簡化了部署工作。Dockerfile從FROM命令開始,緊接著跟隨者各種方法,命令和引數。其產出為一個新的可以用於建立容器的映象。

Dockerfile 語法

在我們深入討論Dockerfile之前,讓我們快速過一下Dockerfile的語法和它們的意義。

什麼是語法?

非常簡單,在程式設計中,語法意味著一個呼叫命令,輸入引數去讓應用執行程式的文法結構。這些語法被規則或明或暗的約束。程式設計師遵循語法規範以和計算機 互動。如果一段程式語法不正確,計算機將無法識別。Dockerfile使用簡單的,清楚的和乾淨的語法結構,極為易於使用。這些語法可以自我釋義,支援註釋。

Dockerfile 語法示例:

Dockerfile語法由兩部分構成,註釋和命令+引數:

# Line blocks used for commenting
command argument argument ..

一個簡單的例子:

# Print "Hello docker!"
RUN echo "Hello docker!"

Dockerfile命令

Dockerfile有十幾條命令可用於構建映象,下文將簡略介紹這些命令:

1.FROM,該命令指定基於哪個基礎映象,因為你要指定一個基礎映象才能基於這個映象之上進行其他操作,因為你不可能憑空創建出一個映象吧,如果基礎映象沒有被發現,Docker將試圖從Docker image index來查詢該映象,而且DockerFile第一條必須為From指令。如果同一個DockerFile建立多個映象時,可使用多個From指令(每個映象一次):

格式:
FROM <image> 或者 FROM <image>:<tag>

例如:

 FROM centos
 FROM centos:latest

2.MAINTAINER,指定作者資訊:

格式:
MAINTAIN <name>

例如:

 MAINTAINER test test@example.com

3.RUN,映象操作指令:

格式:
RUN <command> 或者 RUN ["executable", "param1", "param2"]

例如:

 RUN  yum install  httpd
 RUN ["/bin/bash", "-c", "echo hello"]

4.CMD ,有三種格式:

CMD ["executable", "param1", "param2"]
CMD command param1 param2
CMD ["param1", "param2"]

RUN和CMD看起來挺像,但是CMD只能用來指定容器啟動時用到的命令,所以只能有一條。例如:

CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]

5.EXPOSE ,這個是用來暴露埠的:

格式:

 EXPOSE <port> [<port>...] 

例如,我要將22、80、8443埠暴露出來:

EXPOSE 22 80 8443

這個用來指定要映射出去的埠,比如容器內部我們啟動了sshd和nginx,所以我們需要把22和80埠暴漏出去。這個需要配合-P(大寫)來工作,也就是說在啟動容器時,需要加上-P,讓它自動分配。如果想指定具體的埠,也可以使用-p(小寫)來指定。

6.ENV ,是用於定義環境變數的:

格式:

ENV  <key> <value>

例如:

ENV PATH /usr/local/mysql/bin:$PATH

它主要是為後續的RUN指令提供一個環境變數,我們也可以定義一些自定義的變數:

ENV MYSQL_version 5.6

7.ADD,可以將本地的一個檔案或目錄拷貝到容器的某個目錄裡。 其中src為Dockerfile所在目錄的相對路徑,它也可以是一個url:

格式:

add <src> <dest>

例如:

 ADD <conf/vhosts> </usr/local/nginx/conf>

8.COPY , 格式同ADD,語法格式和ADD一樣,不同的是,它不支援url。

9.ENTRYPOINT ,格式類似CMD:

容器啟動時要執行的命令,它和CMD很像,也是隻有一條生效,如果寫多個只有最後一條有效。和CMD不同是:
CMD 是可以被 docker run 指令覆蓋的,而ENTRYPOINT不能覆蓋。比如,容器名字為test,我們在Dockerfile中指定如下CMD:

CMD ["/bin/echo", "testOne"]

啟動容器的命令是 docker run test 這樣會輸出 testOne
假如啟動容器的命令是 docker run -it test /bin/bash 則什麼都不會輸出,因為 /bin/bash 把 /bin/echo testOne 給覆蓋了。

而 ENTRYPOINT 則不會被覆蓋,並且會比CMD或者docker run指定的命令要靠前執行:

ENTRYPOINT ["echo", "testOne"]
docker run -it test  123

則會輸出 testOne 123 ,這相當於要執行命令 echo testOne 123

10.VOLUME,這個是用來指定掛載點的:

格式:

 VOLUME ["/data"]

VOLUME命令將建立一個可以從本地主機或其他容器掛載的掛載點,與我們之前使用的-v選項是一樣的。

11.USER , 指定執行容器的使用者:

格式:

 USER daemon

12.WORKDIR ,指定命令的工作目錄:

格式:

WORKDIR  /path/to/workdir

為後續的RUN、CMD或者ENTRYPOINT執行的命令指定一個工作目錄。


Dockerfile建立映象 –Dockerfile示例

以上簡單介紹了一下Dockerfile的一些命令以及格式,下面我們來實踐一下Dockerfile,通過Dockerfile來建立一個nginx的映象。

首先我這裡之前拉取了一個centos7的基礎映象,我就基於這個映象上來建立一個nginx環境的映象。

[[email protected] ~]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
centos                        latest              ff426288ea90        4 weeks ago         207MB
[[email protected] ~]# 

1.建立Dockerfile,編輯內容如下:

## Set the base image to CentOS  基於centos映象
FROM centos
# File Author / Maintainer  作者資訊
MAINTAINER test test@example.com
# Install necessary tools  安裝一些依賴的包
RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
# Install Nginx  安裝nginx
ADD http://nginx.org/download/nginx-1.8.0.tar.gz .  # 新增nginx的壓縮包到當前目錄下
RUN tar zxvf nginx-1.8.0.tar.gz  # 解包
RUN mkdir -p /usr/local/nginx  # 建立nginx目錄
RUN cd nginx-1.8.0 && ./configure --prefix=/usr/local/nginx && make && make install  # 編譯安裝
RUN rm -fv /usr/local/nginx/conf/nginx.conf  # 刪除自帶的nginx配置檔案
ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf  # 新增nginx配置檔案
# Expose ports  開放80端口出來
EXPOSE 80
# Set the default command to execute when creating a new container  這裡是因為防止服務啟動後容器會停止的情況,所以需要多執行一句tail命令
ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd

如果你本地的宿主機上,已經有nginx配置檔案了,則可以把ADD更改為使用COPY來進行拷貝:

COPY /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf

編輯完Dockerfile之後就可以通過Dockerfile來建立映象了:

2.建立映象:

[[email protected] ~]# docker build -t centos_nginx .

命令說明:

  • build -t 指定通過Dockerfile來建立映象
  • centos_nginx 則是新映象的名稱
  • . 表示在當前路徑尋找Dockerfile

3.建立完成後,檢視一下我們新建的映象:

[[email protected] ~]# docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
centos_nginx                  latest              167ba72ca0b2        3 minutes ago       374MB
centos                        latest              ff426288ea90        4 weeks ago         207MB
[[email protected] ~]# 

4.然後我們再把該容器的80埠對映到本地的81埠,這樣在外部也可以訪問該容器的nginx服務了:

[[email protected] ~]# docker run -itd -p 81:80 centos_nginx bash
ef4d1bb6b288baab4e7e0c81645894c752e85ba3a4be70900b0dd627eddf43ef
[[email protected] ~]# docker exec -it ef4d1b bash
[[email protected] /]# ps aux |grep nginx
root          1  0.1  0.0  11640  1336 pts/0    Ss+  15:39   0:00 /bin/sh -c /usr/local/nginx/sbin/nginx && tail -f /etc/passwd bash
root          8  0.0  0.0  24840   784 ?        Ss   15:39   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody        9  0.0  0.1  27284  3356 ?        S    15:39   0:00 nginx: worker process
nobody       10  0.0  0.1  27284  3360 ?        S    15:39   0:00 nginx: worker process
root         27  0.0  0.0   9048   664 pts/1    S+   15:39   0:00 grep --color=auto nginx
[[email protected] /]# netstat -lntp |grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      8/nginx: master pro 
[[email protected] /]# exit

5.最後使用curl來測試一下是否能通過訪問宿主機的81埠來訪問到容器的nginx服務:

[[email protected] ~]# curl localhost:81