什麼是 Dockerfile?
Dockerfile 是一個用來構建鏡像的文本文件,文本內容包含了一條條構建鏡像所需的指令和說明。
指令詳解
點擊參考:使用 Dockerfile 定製鏡像
注意事項
-
RUN (docker鏡像越來越大的原因之一)
RUN <命令行命令> # <命令行命令> 等同於,在終端操作的 shell 命令。
注意: Dockerfile 的指令每執行一次都會在 docker 上新建一層。所以過多無意義的層,會造成鏡像膨脹過大。例如:
FROM centos RUN yum install wget RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" RUN tar -xvf redis.tar.gz 以上執行會創建 3 層鏡像。可簡化爲以下格式: FROM centos RUN yum install wget \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && tar -xvf redis.tar.gz
如上,以 && 符號連接命令,這樣執行後,只會創建 1 層鏡像。
-
CMD
作用:爲啓動的容器指定默認要運行的程序,程序運行結束,容器也就結束。CMD 指令指定的程序可被 docker run 命令行參數中指定要運行的程序所覆蓋。
注意:如果 Dockerfile 中如果存在多個 CMD 指令,僅最後一個生效。
格式:
CMD <shell 命令>
CMD ["<可執行文件或命令>","","",…]
CMD ["","",…] # 該寫法是爲 ENTRYPOINT 指令指定的程序提供默認參數推薦使用第二種格式,執行過程比較明確。第一種格式實際上在運行的過程中也會自動轉換成第二種格式運行,並且默認可執行文件是 sh。
-
ENTRYPOINT
類似於 CMD 指令,但其不會被 docker run 的命令行參數指定的指令所覆蓋,而且這些命令行參數會被當作參數送給 ENTRYPOINT 指令指定的程序。
但是, 如果運行 docker run 時使用了 --entrypoint 選項,此選項的參數可當作要運行的程序覆蓋 ENTRYPOINT 指令指定的程序。
優點:在執行 docker run 的時候可以指定 ENTRYPOINT 運行所需的參數。
注意:如果 Dockerfile 中如果存在多個 ENTRYPOINT 指令,僅最後一個生效。
格式:
ENTRYPOINT ["","","",…]
可以搭配 CMD 命令使用:一般是變參纔會使用 CMD ,這裏的 CMD 等於是在給 ENTRYPOINT 傳參。
示例:
假設已通過 Dockerfile 構建了 nginx:test 鏡像:
FROM nginx
ENTRYPOINT [“nginx”, “-c”] # 定參
CMD ["/etc/nginx/nginx.conf"] # 變參1、不傳參運行
docker run nginx:test
容器內會默認運行以下命令,啓動主進程。
nginx -c /etc/nginx/nginx.conf
2、傳參運行
docker run nginx:test -c /etc/nginx/new.conf
容器內會默認運行以下命令,啓動主進程(/etc/nginx/new.conf:假設容器內已有此文件)
nginx -c /etc/nginx/new.conf
-
FROM
多個FROM聲明
嘗試使用多個FROM聲明來將不同的鏡像組合到一起,這樣不會起任何作用。Docker僅使用最後一個FROM並且忽略前面所有的。所以如果你有這樣的Dockerfile:
# !!! ANTIPATTERN !!! FROM node:6.2.1 FROM python:3.5 CMD ["sleep", "infinity"] # !!! ANTIPATTERN !!!
那麼docker exec進入運行的容器中,會得到下面的結果:
$ docker exec -it d86fcf0775d3 bash root@d86fcf0775d3:/# which python /usr/local/bin/python root@d86fcf0775d3:/# which node root@d86fcf0775d3:/#
這其實是GitHub上的一個問題:合併不同的鏡像,但它看起來不會很快就增加的功能。
dockerfile常見錯誤
-
COPY時提示no such file or directory
例如如下錯誤信息:
COPY failed: stat /var/lib/docker/..... no such file or directory
可能的原因:
文件不存在 文件路徑寫法錯誤
docker鏡像打包的COPY 指令將從構建上下文目錄中 <源路徑> 的文件/目錄複製到新的一層的鏡像內的 <目標路徑> 位置。
實際操作中正確的方式和錯誤的方式參考如下:
正確:COPY ./package.json /app/ COPY package.json /usr/src/app/
錯誤:
COPY ../package.json /app 或者 COPY /opt/xxxx /app
-
Permission denied問題
執行
RUN chmod +x configure
時報錯
chmod: cannot access 'configure': Permission denied
提升權限即可,如數據/程序在‘/home/’
RUN chmod 777 /home/