Dockerfile

Dockerfile

Dockerfile 是用于构建Docker镜像的脚本文件,由一系列指令构成。通过docker build命令构建镜像时,Dockerfile中的指令会由上到下依次执行,每条指令都会构建出一个镜像。这就是镜像的分层。因此,指令越多,层次也就越多,创建的镜像也就越多,效率也会越低。

所以在定义Dockerfile时,能在一个指令完成的动作就不要分为两条。

scratch镜像与ADD指令

scratch镜像是一个空镜像,不能pull、runn。

ENV

【语法1】ENV <key> <value>

用于指定环境变量,这些环境变量,后续可以被RUN指令使用,容器运行起来后,也可以在容器中获取这些环境变量。

【语法2】 ENV <key>=<value1> <key2>=<value2> ...

可以设置多个变量,每个变量为一对<key>=<value>指定。

WORKDIR

【语法】WORKDIR path

容器打开后默认进入的目录,一般在后续的RUN、CMD、ENTRYPOINT、ADD等指令中会引用改目录。可以设置多个WORKDIR指令。后续WORKDIR指令若是用的是相对路径,则会基于之前WORKDIR指令指定的路径。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录

RUN

【语法1】RUN <command>

这里的command就是shell命令。docker build执行的过程中,会使用shell运行指定的command。

【语法2】RUN ["EXECUTABLE","PARAM1","PARAM2",...] 非shell,可执行命令

在docker build执行过程之中,会调用第一个参数"EXECUTABLE"指定的应用程序运行,并使用后面第二、三等参数作为应用程序的运行参数。

CMD

【语法1】CMD ["EXECUTABLE","PARAM1","PARAM2",...]

在容器启动之后,即在执行完 docker run 后会立即调用执行"EXECUTABLE"指定的可执行文件,并使用后面的第二、三等参数作为应用程序的运行参数。

【语法2】 CMD command param1 param2,...

这里的command就是shell命令,在容器启动之后会立即运行指定的shell命令。

【语法3】 CMD ["PARAM1","PARAM2",...]

提供给ENTERYPOINT的默认参数

dockerfile 复制代码
FROM centos:7
CMD cal

FROM centos:7
CMD ["cal"]
bash 复制代码
docker build -t mycal:1.0

我也可以把cal给替换掉

bash 复制代码
docker run mycal:1.0 date
bash 复制代码
docker build -f Dockerfile2 -t mycal:2.0 .
dockerfile 复制代码
FROM centos:7
CMD ["/bin/bash","-c","cal"]  

语法:CMD ["EXECUTABLE","PARAM1","PARAM2",...]

/bin/bash表示可执行文件,-c表示要执行的命令来源于命令行

其实就是用/bin/bash来执行cal

依旧还是不能加参数-y

结论:CMD的都不能用带选项的命令来替换

ENTRYPOINT

【语法1】ENTRYPOINT ["EXECUTABLE","PARAM1","PARAM2",...]

【解析】在容器启动过程中,也就是在执行docker run时,会调用执行"EXECUTABLE"指定的应用程序,并使用后面第二、三等参数作为应用程序的运行参数。

【语法2】ENTRYPOINT command param1 param2,...

【解析】这里的command就是shell命令。在容器启动过程中,也就是在执行docker run时,会运行指定的shell命令。

dockerfile 复制代码
FROM centos:7
ENTRYPOINT ["cal"]
dockerfile 复制代码
FROM centos:7
ENTRYPOINT ["/bin/bash","-c","cal"]
dockerfile 复制代码
FROM centos:7
ENTRYPOINT cal  不起作用
如果ENTRYPOINT发现后面是一个shell,直接就运行shell了,不会去进行拼接

FROM centos:7
ENTRYPOINT ["cal"]  OK
只有这种才会进行拼接

FROM centos:7
ENTRYPOINT ["/bin/bash","-c","cal"]  不起作用
因为这里的-y的作用对象变成/bin/bash了,会被直接忽略

CMD和ENTRYPOINT联用

dockerfile 复制代码
FROM centos:7
CMD ["hello world"]
ENTRYPOINT ["echo"]

CMD中的内容就是ENTRYPOINT的参数。

也就是 echo "hello world"

总结:Dockerfile中的[command]或者["EXCUTABLE"]如果是通过CMD指定的,该镜像的启动命令docker run 中是不能添加参数[ARG]的。一位内Dockerfile中的CMD是可以被命令中[COMMAND]替代的。

如果命令中的IMAGE后依旧有内容,此时对于docker daemon来说,其首先认为是替代用的[COMMAND],如果有两个或者两个以上的内容,后面的内容才会认为是[ARG]。所以,添加的-y会报错,因为没有-y这样的[COMMAND]。

ADD

【语法1】ADD<src> <dest>

【语法2】ADD ["<src>","<dest>"] #路径中存在空格时使用双引号引起来

【解析】该指令将赋值当前宿主机中指定文件src到容器中的指定目录dest中。src可以是宿主机中的绝对路径,也可以是相对路径。但是相对路径是相对于docker build命令所指定的路径的。src指定的文件可以是一个压缩文件,压缩文件复制到容器后会自动解压为目录。src也可以是一个URL,此时ADD指令相当于wget。src最好不要使目录,其会将该目录中的所有内容复制到指定目录中。dest是一个绝对路径,其最后面的路径必须要加上斜杠,否则系统会将最后的目录名称当作是文件名的。

COPY

【说明】功能和ADD指令相同,不过src不能是URL,如果src为压缩文件,复制到容器后也不会自动解压。

如果COPY zookeeper.tar.gz /opt/copy/ 没有最后的 / ,表示copy是一个文件

【建议】全都加上/

dockerfile 复制代码
FROM centos:7
WORKDIR /opt
ADD zookeeper.tar.gz /opt/add/
COPY zookeeper.tar.gz /opt/copy/
CMD ["/bin/bash"]

ARG

【语法】ARG <varname>[=<default value>]

【解析】定义一个变量,该变量将会使用于镜像构建时。若要定义多个变量,则需要定义多个ARG指令。

dockerfile 复制代码
FROM centos:7
ARG name=TOM
RUN echo $name

指定变量

bash 复制代码
docker build -t myargs:2.0 --build-arg name=Jerry .

前提是这个ARG在Dockerfile中存在

ONBUILD

【语法】ONUILD [INSTRUCTION]

【解析】该指令用于指定当前镜像的子镜像进行构建时要执行的指令。

dockerfile 复制代码
FROM centos:7
ENV WORKPATH /usr/local
WORKDIR $WORKPATH
ONBUILD RUN yum install -y wget
CMD ["/bin/bash"]
dockerfile 复制代码
FROM parent:1.0
bash 复制代码
docker build -f Dockerfile2 -t son:1.0 .

会在子镜像中安装wget

EXPOSE

【语法】RUN <port> [<port>...]

指定容器准备对外暴露的端口号,但该端口号并不会真正的对外暴露。如果要真的暴露,需要在执行docker run命令的时候使用-p来指定。

构建新镜像的方式总结

可以构建出新镜像的方式:

docker build

docker commit

docker import

docker compose

docker hub中完成Automated Builds

注意:docker load并没有构建出新的镜像,和原镜像是同一个镜像。

相关推荐
_.Switch13 分钟前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
2401_8504108314 分钟前
文件系统和日志管理
linux·运维·服务器
JokerSZ.18 分钟前
【基于LSM的ELF文件安全模块设计】参考
运维·网络·安全
芯盾时代1 小时前
数字身份发展趋势前瞻:身份韧性与安全
运维·安全·网络安全·密码学·信息与通信
测开小菜鸟1 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
心灵彼岸-诗和远方2 小时前
DevOps业务价值流:架构设计最佳实践
运维·产品经理·devops
一只哒布刘2 小时前
NFS服务器
运维·服务器
P.H. Infinity2 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天2 小时前
java的threadlocal为何内存泄漏
java
caridle3 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express