Dockerfile撰寫
- 前言
- 一、Dockerfile創建鏡像
- 二、Dockerfile常用指令
- 三、示例
- 1、Dockerfile構建nginx鏡像
- 2、Dockerfile構建微服務
- 四、CMD與ENTRYPOINT比較
前言
Dockerfile 說白了就是構建鏡像的一個檔案,它里面描述了一條條的指令,每一條指令都會構建新的一層,當執行
docker build時,docker會按照我們Dockefile里預撰寫好的指令,去一層層構建,從而構建出一個新的鏡像,
一、Dockerfile創建鏡像
- 創建目錄
mkdir any_name
cd any_name
- 撰寫Dockerfile檔案
vim Dockerfile
# This is a comment
FROM daocloud.io/library/nginx
MAINTAINER liang liang@localhost.localdomain
RUN mkdir /test
*注: 如果檔案中有執行失敗的指令,那么創建出來的鏡像名字和tag都為none
- 構建鏡像
docker build -t liang/nginx:v1 . # . 一定要有 表示Dockerfile在當前目錄 如果檔案名不是Dockerfile 使用 -f 指定檔案
二、Dockerfile常用指令
1、FROM 拉取基礎鏡像
功能為指定基礎鏡像,并且必須是第一條指令,如果不以任何鏡像為基礎,那么寫法為:FROM scratch,
語法:FROM <image>:<tag> 其中<tag>為可選項,默認為latest
2、RUN 構建容器時執行命令
RUN命令有兩種格式
Ⅰ. RUN <command> # shell方式
Ⅱ. RUN ["executable", "param1", "param2"] # 類似于函式呼叫,可將executable理解成為可執行檔案,后面就是兩個引數
*注:多行命令不要寫多個RUN,寫在一個RUN里,原因是Dockerfile中每一個指令都會建立一層
3、MAINTAINER
MAINTAINER <name> # 指定作者
4、CMD 容器啟動時要運行的命令
語法:Ⅰ. CMD ["executable","param1","param2"] # CMD [ "sh", "-c", "echo $HOME" ]
Ⅱ. CMD ["param1","param2"] # CMD [ "echo", "$HOME" ]
Ⅲ. CMD command param1 param2 # shell形式
*注:Ⅰ和Ⅱ兩種方式一定要用雙引號,千萬不能寫成單引號
5、ENV 設定環境變數
語法:ENV <key>=<value> ... # 可一次設定多個
6、ADD 復制命令 類似于scp,只是scp需要加用戶名和密碼的權限驗證,而ADD不用
語法:Ⅰ. ADD <src>... <dest>
Ⅱ. ADD ["<src>",... "<dest>"]
<dest>路徑的填寫可以是容器內的絕對路徑,也可以是相對于作業目錄的相對路徑
<src>可以是一個本地檔案或者是一個本地壓縮檔案,還可以是一個url
7、COPY 復制命令
語法:Ⅰ. COPY <src>... <dest>
Ⅱ. COPY ["<src>",... "<dest>"]
8、EXPOSE 暴露監聽埠給外部
*注:EXPOSE并不會使容器訪問主機的埠,如果想使得容器與主機的埠有映射關系,必須在容器啟動的時候加上-p引數
9、WORKDIR 設定作業目錄
語法:WORKDIR /path/to/workdir
對RUN,CMD,ENTRYPOINT,COPY,ADD生效,如果不存在則會創建,也可以設定多次,
10、VOLUME 實作掛載功能,可以將本地檔案夾或者其他容器中的檔案夾掛在到這個容器
語法:VOLUME ["/data"]
*注:一般不會在Dockerfile中用到,更常見的還是在docker run的時候指定-v資料卷
三、示例
1、Dockerfile構建nginx鏡像
FROM centos:7.2.1511
ENV TZ=Asia/Shanghai
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8
RUN yum -y install epel* gcc openssl openssl-devel pcre-devel zlib-devel
ADD nginx-1.14.0.tar.gz /opt/
WORKDIR /opt/nginx-1.14.0
RUN ./configure --prefix=/opt/nginx --http-log-path=/opt/nginx/logs/access.log --error-log-path=/opt/nginx/logs/error.log --http-client-body-temp-path=/opt/nginx/client/ --http-proxy-temp-path=/opt/nginx/proxy/ --with-http_stub_status_module --with-file-aio --with-http_flv_module --with-http_gzip_static_module --with-stream --with-threads --user=www --group=www
RUN make && make install
RUN groupadd www && useradd -g www www
WORKDIR /opt/nginx
RUN rm -rf /opt/nginx-1.14.0
ENV NGINX_HOME=/opt/nginx
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/nginx/sbin
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
*注:此只是個例子,實際中如果沒有滿足需求的base image,如java程式使用java:8作為base image,可以使用Alpine鏡像作為base image,輕量級且命令豐富,比centos鏡像更適合做base image
2、Dockerfile構建微服務
#cat Dockerfile
FROM java:8
MAINTAINER liang_20210511
#ENV TZ=Asia/Shanghai
#ENV LANG=en_US.UTF-8
#ENV LANGUAGE=en_US:en
#ENV LC_ALL=en_US.UTF-8
ENV JAVA_OPTS="-Xms512m -Xmx512m"
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ADD cmdb-server.tar /
WORKDIR /cmdb-server
EXPOSE 10013
#CMD ["java","-jar","cmdb-server.jar","-Dfile.encoding=utf-8"]
ENTRYPOINT ["/cmdb-server/entrypoint.sh"]
#cat entrypoint.sh
#!/bin/sh
nohup java -server $JAVA_OPTS -jar cmdb-server.jar >/dev/null 2>&1 &
sleep 1
if [ $? -eq 0 ];then
tail -f logs/cmdb-server.log
fi
四、CMD與ENTRYPOINT比較
??cmd 和 entrypoint 指令都是用來指定容器啟動時運行的命令,并且都有exec與shell兩種模式,推薦使用exec模式,這樣可以使容器接收的KILL信號,從而優雅的退出,這里牽扯到容器的daemon行程來管理容器的生命周期,以后有機會我們以后專門拿出來去探討,
??cmd 指令
??cmd 指令的目的是:為容器提供默認的執行命令,
??cmd 指令有三種使用方式,其中的一種是為 entrypoint 提供默認的引數:
cmd ["param1","param2"]
??另外兩種使用方式分別是 exec 模式和 shell 模式:
cmd ["executable","param1","param2"]
cmd command param1 param2
??注意命令列引數可以覆寫 cmd 指令的設定,但是只能是重寫,卻不能給 cmd 中的命令通過命令列傳遞引數,我們可以通過docker run引數的方式覆寫 cmd 指令提供的默認命令,
??entrypoint 指令
??entrypoint 指令的目的也是為容器指定默認執行的任務,
??entrypoint 指令有兩種使用方式, exec 模式和 shell 模式:
entrypoint ["executable", "param1", "param2"]
entrypoint command param1 param2
??在這里entrypoint 有一個特殊的用法,傳參,
??1、當我們使用exec模式時,docker run的指令可以作為引數傳遞給entrypoint 命令,比如:
from centos
entrypoint [ "top", "-n" ]
當我們執行docker run -- rm centos:test 1
此時容器里執行的命令:top -n 1
??2、cmd指令給entrypoint 傳參,比如:
from centos
entrypoint [ "top", "-n" ]
cmd [ "1" ]
當我們執行docker run -- rm centos:test
此時容器里執行的命令:top -n -1
??3、docker run的指令覆寫cmd指令,傳參給entrypoint
from centos
entrypoint [ "top", "-n" ]
cmd [ "1" ]
當我們執行docker run -- rm centos:test 3
此時容器里執行的命令:top -n -3
??其實cmd指令與entrypoint指令遠比這些要復雜:

??當然,大家想深入了解的也可以參考官方給的解釋自行實踐對比一下:官方鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292608.html
標籤:其他
下一篇:虛擬機下的客戶機實驗
