前言

經過前幾次的docker教學,相信大家都已經體會到,docker快速佈署環境的厲害。

其中docker image的可謂功勞重大。但如果今天要使用別人的image,可是卻不知道image的作者之前在裡面安裝了什麼??就好比一個黑箱子,要你把手伸進去一樣,但你卻不知道自己會摸到什麼,很恐怖吧!

“人類最古老而強烈的情緒,便是恐懼;而最古老最強烈的恐懼,便是對未知的恐懼。”—霍華德·菲利普·洛夫克拉夫特

所以!這個時候就有Dockerfile出現了,可以讓大家知道這個image用了哪個版本的作業系統或基底,是誰製作了這個image,安裝了神麼東西,啟動時執行什麼。這樣一來,不管是誰要接手或利用你的image,就清楚透明許多。

什麼是Dockerfile?

dockerfile簡單來說就是一個容器container自定義的安裝

由一行行命令語句組成,並且支援以 # 開頭的註解行。

他大致上會擁有四個東西

  • 基底映像檔
  • 維護者(建議加入)
  • 操作指令
  • 容器啟動時執行指令(不一定每個都有)

這四個東西,可以說是組成了dockerfile的重要因素,接下來我們來好好說下關於這四個因素。

基底映像檔

湯有湯底,房子有地基,開頭都說是基底了,相信大家都很聰明,沒錯!這個東西就是基底….(說了跟沒說一樣

好了不開玩笑www

所謂的基底映像檔,就是你要拿什麼當作這個image的底層,比如說ubuntu:14.04
當然這邊也可以拿自己已經製作完成的映像檔。

指令:

FROM ubuntu:14.04

格式為 FROM 或FROM :。

真的不開玩笑基底映像檔就一個FROM後面加上你要的基底的指令。
如果在一個Dockerfile內加入多個FROM,那麼會一次製作多個映像檔。

維護者(建議加入)

一般的Dockerfile都會放在dockerhub或github提供給各路大神觀看
讓大家知道這是誰的名作,又該如何找到這位大神。
當然如果各路大神發現了什麼重大bug,想通知作者,卻找不到人!!?那麼這個時候,Dockerfile裡的維護者,也起了一個重大作用,讓別人可以知道該聯絡誰。
當然啦,如果不加入也是可以的。

指令:

MAINTAINER hs hs@xxxx.gmail.com

格式為 MAINTAINER ,指定維護者訊息。

這邊也是只有一個MAINTAINER加上作者資訊的指令

操作指令

這邊的操作指令,可以說是整份Dockerfile最重要的地方,因為你安裝了什麼,複製了什麼,引入了什麼,又加入了什麼東西,可以說全部都在這邊執行了。
例如 RUN 指令,RUN 指令將對映像檔執行相對應的命令。每運行一條 RUN 指令,映像檔就會新增一層。

指令:

RUN apt-get update

格式為 RUN 或 RUN [“executable”, “param1”, “param2”]。

前者將在 shell 終端中運行命令,即 /bin/sh -c;後者則使用 exec 執行。指定使用其它終端可以透過第二種方式實作,例如 RUN [“/bin/bash”, “-c”, “echo hello”]。
每條 RUN 指令將在當前映像檔基底上執行指定命令,並產生新的映像檔。當命令較長時可以使用 來換行。

EXPOSE 80

格式為 EXPOSE […]。

設定 Docker 伺服器容器對外的埠號,供外界使用。在啟動容器時需要透過 -P,Docker 會自動分配一個埠號轉發到指定的埠號(當然也可以自己給,例如 -p 1055:80)。

ADD 000-default.conf /etc/apache2/sites-available/000-default.conf

格式為 ADD 。

該命令將複製指定的 到容器中的 。 其中 可以是 Dockerfile 所在目錄的相對路徑;也可以是一個 URL;還可以是一個 tar 檔案(其複製後會自動解壓縮)。
000-default.conf為本機內的檔案,當然我自己是把這個檔案跟Dockerfile放在同一個資料夾

容器啟動時執行指令

有些指令,我們希望在容器啟動時,自動開啟

CMD /etc/bash.bashrc

支援三種格式

CMD [“executable”,”param1″,”param2″] 使用 exec 執行,推薦使用;

CMD command param1 param2 在 /bin/sh 中執行,使用在給需要互動的指令;

CMD [“param1″,”param2”] 提供給 ENTRYPOINT 的預設參數;

指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,只有最後一條會被執行。
如果使用者啟動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。

例如

下面來寫個Dockerfile並可以拿來使用在drupal上


FROM ubuntu:14.04

RUN apt-get update
RUN apt-get upgrade -y 

# apache2 php5
RUN apt-get install apache2 -y
RUN apt-get install php5 -y 
RUN apt-get install php5-gd -y
RUN apt-get install libapache2-mod-auth-mysql -y
RUN apt-get install php5-mysql -y
RUN apt-get install php5-cli -y

RUN apt-get install nano git wget -y
RUN a2enmod rewrite

# drush
RUN wget http://files.drush.org/drush.phar
RUN php drush.phar core-status
RUN chmod +x drush.phar
RUN sudo mv drush.phar /usr/local/bin/drush
RUN drush init -y


# mysql

 RUN apt-get update 
    && apt-get install -y debconf-utils 
    && echo mysql-server mysql-server/root_password password YOURPASSWORD | debconf-set-selections 
    && echo mysql-server mysql-server/root_password_again password YOURPASSWORD | debconf-set-selections 
    && apt-get install -y mysql-server 

EXPOSE 80

CMD ["bash"]

當我們寫好了Dockerfile,接下來就是要把這個image建立起來啦
我們可以使用docker build 命令建立image。

基本的格式為 docekr build [選項] 路徑
該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下所有內容發送給 Docker 伺服端,由伺服端來建立映像檔。
因此一般會建議放置 Dockerfile 的目錄為空目錄。也可以透過 .dockerignore 檔案(每一行新增一條排除模式:exclusion patterns)來讓 Docker 忽略路徑下的目錄和檔案。

$ sudo docker build -t  test/test:type1  .

“.”為當下路徑

就這樣完成docker image的建立了

結論

以上,就是一個簡單的dockerfile說明,當然在操作指令那邊,仍然有些參數,本篇並未提及,想深入了解的朋友,可以觀看docker的官網查看「這篇

歡迎大家留言討論,當然也希望這邊文章能夠幫到剛接觸docker的所有人

Facebook 功能: