基于dockerfile制作鏡像
dockerfile是什么?
Dockerfile可以說是一種可以被docker程序解釋的腳本诀浪,Dockerfile是由一條條的命令組成的棋返,每條命令對應(yīng)Linux下面的一條命令,docker程序?qū)⑦@些Dockerfile指令再翻譯成真正的Linux命令雷猪,其有自己的書寫方式和支持的命令射沟,docker程序讀取Dockerfile并根據(jù)指令生成docker鏡像嚷辅。
結(jié)構(gòu)規(guī)整
將每個不同的系統(tǒng)以及web鏡像都創(chuàng)建對應(yīng)的目錄和dockerfile趁俊,制作基礎(chǔ)鏡像怔软,然后是基于這些基礎(chǔ)鏡像進(jìn)一步的構(gòu)建生產(chǎn)中用的環(huán)境家坎,就不用每次都重新去底層開始構(gòu)建鏡像了,直接去鏡像倉庫拉取就行穿扳。
[root@localhost opt]# tree dockerfile/
dockerfile/
├── system
│ ├── alpine
│ │ ├── Dockerfile
│ │ └── repositories
│ ├── centos
│ │ └── Dockerfile
│ ├── debian
│ ├── redhat
│ └── ubuntu
└── web
├── apache
├── jdk
│ ├── Dockerfile
│ └── jdk-8u191
│ ├── Dockerfile
│ └── jdk-8u191-linux-x64.tar.gz
├── nginx
│ ├── alpine
│ │ ├── Dockerfile
│ │ ├── nginx-1.16.1.tar.gz
│ │ └── repositories
│ ├── centos
│ │ ├── Dockerfile
│ │ └── nginx-1.16.1.tar.gz
│ └── ubuntu
├── php
└── tomcat
├── tomcat7
└── tomcat8
├── apache-tomcat-8.5.42.tar.gz
├── build-tomcat.sh
├── Dockerfile
└── run.sh
dockerfile文件中使用命令
dockerfile官方文檔:https://docs.docker.com/engine/reference/builder/
參考鏈接:https://blog.csdn.net/qq_41734645/article/details/105012588
FROM
FROM:基于那個鏡像構(gòu)建當(dāng)前鏡像爱榔,構(gòu)建鏡像時會先在本地尋找基礎(chǔ)鏡像浸锨,如果本地沒有會去dockerhub或者遠(yuǎn)程倉庫去下載。
LABEL表制,MAINTAINER
- 解釋
LABEL:作者信息或者描述夭拌。(現(xiàn)在都是用這個)
MAINTAINER:作者信息或者描述。
- 例
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates that label-values can span multiple lines."
USER
USER:指定該容器運(yùn)行時使用的用戶名和UID(即設(shè)置構(gòu)建用戶),后續(xù)的RUN命令也會使用這個指定用戶婆赠。生成容器之后登錄進(jìn)去會是user指定的用戶,不是root拭嫁。
USER <user>[:<group>]
USER <uid>:<gid>
USER nginx
WORKDIR
指定工作目錄逮刨,和cd一樣片仿,這個指定的目錄會成為容器啟動后登陸進(jìn)去的第一個目錄。
VOLUME
- 解釋
設(shè)置容器掛載宿主機(jī)的目錄
- 例
VOLUME ["/dir_1","/dir_2",...]
VOLUME [“/data”,”/data2”]
VOLUME /data
ENV咖熟,ARG
- 解釋
ENV:設(shè)置鏡像環(huán)境變量张惹,在構(gòu)建鏡像時有效屎暇,在鏡像被創(chuàng)建后和啟動容器時環(huán)境變量依舊也有效,并且可以重寫覆蓋糊肤。print env可查看其值常用于向容器內(nèi)傳遞用戶密碼等。
ARG:在構(gòu)建鏡像時君纫,指定一些參數(shù),僅在build docker imag的過程中有效 - 例
例:ENV Name tiemrovers
#無默認(rèn)值
ENV hey
#默認(rèn)值
ENV foo /bar
#或ENV foo=/bar
#在構(gòu)建過程中可以使用ENV值
ADD . $foo
#or ADD . ${foo}
#翻譯為:添加。/酒吧
#使用以下docker命令設(shè)置env
docker run -e "env_var_name=another_value" alpine env
docker run -e env_var_name alpine env
docker run --env-file=env_file_name alpine env
#在Dockerfile中
ARG some_variable_name
#或硬編碼默認(rèn)值:
#ARG some_variable_name=默認(rèn)值
RUN echo "Oh dang look at that $some_variable_name"
#在shell命令中
docker build --build-arg some_variable_name=a_value
#然后你會得到
Oh dang look at that a_value
- 配合使用
#需要一個構(gòu)建時變量
ARG A_VARIABLE
#使用該值設(shè)置ENV var默認(rèn)值
ENV an_env_var=$A_VARIABLE
#如果不被覆蓋,您的容器將繼續(xù)使用an_env_var的值!
RUN
- 解釋
它接受命令作為參數(shù)并用于創(chuàng)建鏡像梧田。RUN會在shell或者exec的環(huán)境下執(zhí)行命令穿稳。
- 例
例:RUN cd /opt
RUN echo helloworld
RUN [“命令”,“參數(shù)1”骤菠,“參數(shù)2”] #可以免除運(yùn)行/bin/sh的消耗,如果參數(shù)中引號等特殊字符抹凳,需要進(jìn)行轉(zhuǎn)義
ADD,COPY
- 解釋
ADD:ADD和COPY作用相似督惰,可以從一個URL地址下載內(nèi)容復(fù)制到容器的文件系統(tǒng)中,還可以將壓縮打包格式的文件解壓后復(fù)制到指定位置秘车。
文件復(fù)制均使用 COPY 指令,在需要自動解壓縮的場合使用 ADD
COPY:用來將本地的文件或者文件夾復(fù)制到鏡像的指定路徑下典勇,但是不會解壓
- 例
COPY /local/path/file /images/path/file
ADD file /images/path/file
ADD latest.tar.gz /var/www
EXPOSE
- 解釋
標(biāo)明這個鏡像中的應(yīng)用將會監(jiān)聽某個端口,并且希望能將這個端口映射到主機(jī)的網(wǎng)絡(luò)界面上叮趴,使容器內(nèi)的應(yīng)用可以通過端口和外界交互割笙。
這里只是暴露了容器的端口,具體指定映射需要在運(yùn)行容器的時候指定-p(小寫)眯亦。
- 例
例:EXPOSE 80 443 多個端口空格隔開
ENTRYPOINT伤溉,CMD
1.ENTRYPOINT 解釋
類似CMD配置容器啟動后執(zhí)行的命令,但是它不可被 docker run 提供的參數(shù)覆蓋;
每個 Dockerfile 中只能有一個 ENTRYPOINT妻率,當(dāng)指定多個時谈火,只有最后一個起效
- ENTRYPOINT例:
ENTRYPOINT [ "sh", "-c", "echo $HOME" ]
ENTRYPOINT ["executable", "param1", "param2"] #exec 格式
ENTRYPOINT command param1 param2 #shell格式
1.Exec 格式
這種格式在容器run的時候指定的命令會覆蓋ENTRYPOINT,CMD同樣會覆蓋
ENTRYPOINT 的 Exec 格式用于設(shè)置要執(zhí)行的命令及其參數(shù)舌涨,同時可通過 CMD 提供額外的參數(shù)糯耍。
ENTRYPOINT 中的參數(shù)始終會被使用,而 CMD 的額外參數(shù)可以在容器啟動時動態(tài)替換掉囊嘉。
2.Shell 格式
ENTRYPOINT 的 Shell 格式會忽略任何 CMD 或 docker run 提供的參數(shù)温技。
Dockerfile 片段:
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
#當(dāng)容器通過 docker run -it [image] 啟動時,輸出為:
Hello world
#而如果通過 docker run -it [image] haha啟動扭粱,則輸出為:
Hello haha
- CMD解釋
CMD和RUN命令相似舵鳞,CMD可以用于執(zhí)行特定的命令。CMD每次啟動容器時運(yùn)行琢蛤,RUN在創(chuàng)建鏡像時執(zhí)行一次蜓堕,固化在image中。RUN命令先于CMD和ENTRYPOINT博其。
Dockerfile只允許使用一次CMD指令套才,一般都是腳本中最后一條指令。
如果docker run后面出現(xiàn)與CMD指定的相同的命令慕淡,那么CMD就會被覆蓋背伴。而ENTRYPOINT會把容器名后面的所有內(nèi)容都當(dāng)成參數(shù)傳遞給其指定的命令
CMD:設(shè)置鏡像在啟動容器時執(zhí)行的命令。
- CMD例:
CMD ["sbin/nginx","-g","daemon off;"]
CMD ["executable","param1","param2"] #CMD 的推薦格式。
CMD ["param1","param2"] #為 ENTRYPOINT 提供額外的參數(shù)傻寂,此時 ENTRYPOINT 必須使用 Exec 格式息尺。
CMD command param1 param2 #Shell 格式
STOPSIGNAL(停止)
- 解釋
該STOPSIGNAL指令設(shè)置將被發(fā)送到容器退出的系統(tǒng)調(diào)用信號。該信號可以是與內(nèi)核syscall表中的位置匹配的有效無符號數(shù)字(例如9)疾掰,也可以是格式為SIGNAME的信號名稱(例如SIGKILL)搂誉。
默認(rèn)的stop-signal是SIGTERM,在docker stop的時候會給容器內(nèi)PID為1的進(jìn)程發(fā)送這個signal静檬,通過--stop-signal可以設(shè)置自己需要的signal勒葱,主要的目的是為了讓容器內(nèi)的應(yīng)用程序在接收到signal之后可以先做一些事情,實現(xiàn)容器的平滑退出巴柿,如果不做任何處理,容器將在一段時間之后強(qiáng)制退出死遭,會造成業(yè)務(wù)的強(qiáng)制中斷广恢,這個時間默認(rèn)是10s。
- 例
#STOPSIGNAL 信號
STOPSIGNAL 9
ONBUILD
- 解釋
為鏡像添加觸發(fā)器呀潭。其指令在構(gòu)建鏡像時候并不執(zhí)行钉迷,而是在其子鏡像中執(zhí)行
當(dāng)我們在一個Dockerfile文件中加上ONBUILD指令,該指令對利用該Dockerfile構(gòu)建鏡像(比如為A鏡像)不會產(chǎn)生實質(zhì)性影響钠署。但是當(dāng)我們編寫一個新的Dockerfile文件來基于A鏡像構(gòu)建一個鏡像(比如為B鏡像)時糠聪,這時構(gòu)造A鏡像的Dockerfile文件中的ONBUILD指令就生效了,在構(gòu)建B鏡像的過程中谐鼎,首先會執(zhí)行ONBUILD指令指定的指令舰蟆,然后才會執(zhí)行其它指令。需要注意的是狸棍,如果是再利用B鏡像構(gòu)造新的鏡像時身害,那個ONBUILD指令就無效了,也就是說只能再構(gòu)建子鏡像中執(zhí)行草戈,對孫子鏡像構(gòu)建無效塌鸯。
- 例
FROM ubuntu:14.04
ONBUILD RUN echo “you not see me later”
基于dockerfile構(gòu)建鏡像命令
1. 指定其他路徑的dockerfile
docker build -t 鏡像名:tag -f dockerfile文件 .
2. 本目錄構(gòu)建鏡像
docker build -t 鏡像名:tag .
docker build -t 倉庫名/鏡像名:tag .
3. 可以將一個dockerfile構(gòu)建成不同名稱的鏡像
docker build -t 鏡像名01:tag01 -t 鏡像名02:tag02 .
docker build -t 倉庫名01/鏡像名01:tag01 -t 倉庫名02/鏡像名02:tag02 .
基于dockerfile制作nginx鏡像
dockerfile文件分類
mkdir -p /opt/dockerfile/{web/{nginx,tomcat,php,jdk,apache},system/{centos,ubuntu,redhat}}
Nginx yum安裝Dockerfile內(nèi)容
#Docker image for nginx
FROM centos:7.7.1908
LABEL description=timerovers<18932665502@163.com>
ENV NGINX-VERSION nginx-1.16.1
RUN yum -y install epel-release && yum -y install $NGINX-VERSION
Nginx編譯安裝Dockerfile內(nèi)容
準(zhǔn)備好nginx-1.16.1.tar.gz放到構(gòu)建鏡像的目錄
#Docker image for nginx
FROM centos:7.7.1908
LABEL description=timerovers<18932665502@163.com>
ARG NGINX-VERSION=nginx-1.16.1
RUN yum -y install epel-release && yum -y install gcc gcc-c++ automake pcre pcre-devel zlib \
zlib-devel openssl openssl-devel libxml2 libxml2-dev libxslt-devel gd-devel perl-devel \
perl-ExtUtils-Embed GeoIP GeoIP-devel GeoIP-data
ADD $NGINX-VERSION.tar.gz /usr/local/src/
RUN cd /usr/local/src/$NGINX-VERSION && useradd -M -s /sbin/nologin nginx \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
--with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module \
--with-http_realip_module --with-http_addition_module --with-http_xslt_module \
--with-http_image_filter_module --with-http_geoip_module --with-http_sub_module \
--with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module \
--with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module \
--with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module \
&& make && make install && yum clean all && rm -rf /usr/local/src/$NGINX-VERSION
EXPOSE 80
EXPOSE 443
WORKDIR /usr/local/nginx/
CMD ["sbin/nginx","-g","daemon off;"]
啟動生成鏡像
把配置和存放代碼的目錄映射出來
nginx-data可以提前創(chuàng)建好
docker run -d -p 50000:80 -p 50001:443 -v nginx-data:/usr/local/nginx --name nginx nginx:1.14.2