目錄
一、Dockerfile基本結構
拿到Dockerfile(可以命名為其他名字,但是不推薦)后就可以通過docker build實現鏡像的復制。在同一文件夾下存在多個Dockerfile的情況,可以修改Dockerfile文件名,如Dockerfile.first、Dockerfile.second,只需要在構建時加上-f參數即可。
1.1 Dockerfile書寫規則
- 注釋://
- 語法結構: 指令 參數
- 大小寫問題: 官方允許小寫的指令,但是為了代碼的可讀性,指令用大寫
1.2 Dockerfile書寫思想
- 注意自動化: 文件是否可以一直持續不斷的運行下去,遇到交互節點時候可以自動應答
- Dockerfile順序: Dockerfile構建是從上到下的,所以書寫時需要考慮命令執行情況適當調整指令位置(例如軟件依賴應在軟件執行源命令前安裝)
- 注意清理: 在構建完成后,清除構建過程中產生的臨時文件(並不是刪除文件后體積一定會減小),以保證鏡像的體積節省資源
- 文件易讀性: 例如,一條很長的命令,不要一行寫到底,可以加\分隔
二、Dockerfile指令介紹
2.1 FROM
2.1.1 作用
指定基礎鏡像
2.1.2 語法
FROM <imageName:tag>
案例:
FROM aprine
2.2 MAINTAINER
2.2.1 作用
設置維護者信息
2.1.2 語法
MAINTAINER Name <Email>
2.3 RUN
2.3.1 作用
執行構建命令,RUN會在shell或者exec環境下執行命令
2.3.2 語法
shell指令會在當前命令頂層執行命令
2.3.2.1 shell格式案例
RUN echo Hello World
2.3.2.2 exec格式案例
exec使用JSON格式將程序名和所需參數組成一個字符串數組,如果參數中有引號等特殊字符,需要轉義。使用exec的格式避免了調用/bin/sh的消耗,但是exec不會觸發shell,所以$HOME等環境變量不能使用。但是他可以在沒有shell的環境中執行,可以避免解析命令錯誤字符串
RUN ["程序名","參數1","參數2", ...]
2.4 ENV
2.4.1 作用
設置鏡像環境變量指令
2.4.2 語法
ENV <key> <value>
案例:
ENV TARGET_DIR /app
// 使用環境變量
WORKDIR $TARGET_DIR
2.5 COPY
2.5.1 作用
復制文件
2.5.2 語法
ENV <文件原路徑> <目標路徑>
2.6 ADD
2.6.1 作用
添加文件,可以從一個URL地址下載內容復制到容器的文件系統中,還可以將壓縮打包格式的文件解壓后復制到指定位置
2.6.2 語法
ADD File /Images/Path/File
ADD Itaest.tar.gz /var/www/
注意: ADD構建鏡像大小比COPY要大,如果只是賦值文件,建議COPY
注意2:
- ADD不能使用相對路徑
- 如果目的路徑不存在,會自動創建
- ADD指令會使得構建緩存無效
2.7 EXPOSE
2.6.1 作用
指定端口暴露。表明這個景象中的應用將會監聽某個端口,並且希望這個端口映射到網絡界面上。一般為了安裝,docker run命令日過沒有帶上響應的端口映射參數,docker將不會安把端口映射出去
2.6.2 語法
EXPOSE <端口> [<端口> ···]
2.8 CMD
2.8.1 作用
設置鏡像啟動命令。Docherfile只允許使用一次CMD命令 ,使用多個CMD會低效之前所有的指令,只有最后一個執行生效。一般來說這是整個Dockerfile最后一條命令。
2.8.2 語法
CMD ["executable", "param1", "param2", ···]
案例:
ENV TARGET_DIR /app
// 使用環境變量
WORKDIR $TARGET_DIR
注意: docker run可以覆蓋CMD命令。如果docker run 后面出現與CMD后相同的指令,那么CMD會被覆蓋
案例
# 沒有被覆蓋案例
[root@localhost docker]# docker run hello
Hello World
# 被覆蓋案例
[root@localhost docker]# docker run hello echo "這個指令被覆蓋了"
這個指令被覆蓋了
[root@localhost docker]#
2.8.3 CMD和RUN的區別
RUN是在build時就運行的,所以RUN只在創建鏡像時執行一次,固化在image中,CMD在每次啟動容器時都會執行。
2.9 ENTRYPORINT
2.9.1 作用
設置接入點
2.9.2 案例
Dockerfile內容
FROM ubuntu
ENTRYPORINT ["echo"]
使用
docker build -t test .
...
docker run test 'Hellp Docker'
2.10 VOLUME(后面有單獨章節介紹)
2.10.1 作用
基於鏡像創建容器添加數據卷,即在容器中設置一個掛載點,可以讓其他容器掛載或讓宿主機訪問,以實現數據共享或對容器數據的備份、恢復或遷移。
2.10.2 VOLUME特點
- 數據卷可以在容器間共享和重用
- 數據卷的修改是立即生效的
- 數據卷的修改不會對更新鏡像產生影響
- 數據卷會一直存在,知道容器沒有使用它
2.10.3 VOLUME使用格式
VOLUME ["/data", "/data2"]
VOLUME /data
2.11 USER
2.11.1 作用
設置構建用戶,這個命令可以通過docker run命令的-u選項來覆蓋
2.11.2 VOLUME使用格式
USER user
USER user:group
User user:gid
2.12 WORKDIR
2.12.1 作用
指定RUN、CMD和ENTRYPOINT命令工作目錄。若指定多次,后面的路徑會覆蓋前面的路徑
2.12.2 WORKDIR使用格式
WORKDIR path
2.13 ONBUILD
2.13.1 作用
設置二次構建指令。ONBUILD指定在構建鏡像時並不執行,而是在它的子鏡像中執行。
2.13.2 ONBUILDE使用案例
# 父容器中Dockerfile內容
FROM busybox
ONBUILD RUN echo "第二次構建(子構建)才執行"
# 構建父鏡像
docker build -t father .
# 構建過程中不會打印第二次構建(子構建)才執行
創建子容器
# 子容器中Dockerfile內容
FORM father
# 構建子鏡像
docker build -t child .
# 構架過程中打印了第二次構建(子構建)才執行
2.14 LABEL
2.14.1 作用
設置元數據的LABEL。該指令添加元數據到鏡像,每一個標簽都會生成一個layer,所以精良使用一個LABEL標簽
2.14.2 LABEL使用案例
LABEL multi.label1="value1" \
multi.label2="value2" \
multi.label3="value3"
2.15 ARG
2.15.1 作用
設置可以在構建時使用的變量,這個參數只會在構建時存在。效果同docker build --build-arg
2.16 STOPSIGNAL
2.16.1 作用
允許用戶定制化docker stop時的信號
2.16.2 案例
STOPSINGAL SIGKILL
上述容器在停止時,會發送SIGKILL信號(一些不能接受正常退出信號的容器)
2.17 HEALTHCHECK
2.17.1 作用
檢查健康狀態。用來檢查容器啟動運行時是否正常,正常返回healthy,否則返回unhealthy
2.17.2 語法
HEALTHCHECK [OPTIONS] CMD command
''''
OPTIONS詳解:
--interval=DURATION
設置在容器啟動多長時間后開始檢查容器狀態,默認30s
--timeout=DURATION
設置超時時間,超過這個時間不返回信息,默認30s
--retries=N
設置重試次數,默認為3
'''
2.17.4 案例
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/ || exit 1
2.18 SHELL
2.18.1 作用
設置命令執行環境的SHELL命令。linux默認SHELL命令使用/bin/sh。windows默認使用cmd。如果要更換,使用這個命令
2.17.2 案例
# 在Windows下更換powershell為默認shell環境
SHELL ["powershell", "-command"]
三、實戰案例
3.1 項目內容
構建pageKit CMS鏡像
3.2 Dockerfile內容
// 填寫鏡像維護者信息
FROM ubuntu:trusty
MAINTAINER Username<email@email.com>
// 安裝運行環境
RUN apt-get update && \
apt-get -y install \
nginx \
unzip \
wget \
ca-certification\
php5 php5-fpm php5-cli php5-json php5-mysql php5-curl
// 安裝pagekit
ENV PAGEJIT_VERSION 1.0.2
RUN mkdir /pagekit
WORKDIR /pagekit
VOLUME ["/pagekit/storage", "/pagekit/app/cache"]
// 從GitHub上拉取相應版本的Pagekit包
RUN Wget https://github.como/pagekit/release/download/$PAGEJIT_VERSION/pagekit-$PAGEJIT_VERSION/zip -O /pagekit/pagekit.zip && \
unzip /pagekit/pagekit.zip && rm /pagekit/pagekit.zip
// 配置Nginx和清理鏡像
ADD nginx.conf /etc/ngix/nginx.conf
RUN chown -R www-data: /pagekit && \
apt-get autoremove wget unzip -y && \
apy-get autoclean -y && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
CMD ["sh", "-c", "service php5-fpm" start && nginx]