Dockerfile 详解,使用 Dockerfile 构建镜像

1、Dockerfile 编写

编写规则:指令不区分大小写,通常采用大写形式。

        有的指令会新增镜像层(如:FROM,RUN,COPY,ADD等),有些只是增加元数据(如:ENV,WORKDIR,EXPOSE,ENTRYPOINT等)。如果是向镜像中添加文件或者程序,就会新建镜像层;如果只是告诉docker如何完成构建或者如何运行程序,只会增加元数据,不会增加新的镜像层。(用于精简镜像,可以使用同一Dockerfile进行多阶段构建,会产生虚悬镜像。)

FROM
# 文件必须从 FROM 开始编写   FROM  或者 FROM :
# 注释:# 代表注释单行
ENV 
# ENV = :定义环境变量,定义PATH等,后面也可以使用 $param 或者 ${param} 进行引用
RUN
# RUN 有两种方式:1)、RUN linux命令   2)、RUN ["executable", "param1", "param2", ....]
# 注:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层,多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错,使用&&连接多个命令用反斜杠(\)换行。
CMD
# 三种方式:
# CMD["executable","paraml","param2"]:相当于执行 executable param1 param2,(推荐方式)
# CMD command paraml param2 :在默认的 Shell 中执行,提供给需要交互的应用;
# CMD ["paraml”, "param2"] :提供给 ENTRYPOINT 的默认参数。
# 注:指定启动容器时默认执行的命令,如果用户启动容器时候手动指定了运行的命令(作为run命令的参数),则会覆盖掉CMD 指定的命令
LABLE (替代MAINTAINER)
# 使用键值对的方式进行定义:LABEL = = = ...
EXPOSE 
# EXPOSE  [/...]:容器对外暴露的端口号,具体写法 EXPOSE 80/udp(80/tcp),在执行 run 的时候使用 -p 可以覆盖此配置
###### 注:注意该指令只是起到声明作用, 并不会自动完成端口映射。如果要映射端口出来, 在启动容器时可以使用-P 参数(Docker主机会自动分配一个宿主机的临时端口)或-p HOST_PORT:CONTAINER_PORT 参数(具体指定所映射的本地端口)。
ADD
# ADD [--chown=:] ["",... ""] : src 和 dest 目录和文件要区别开,目录最后要加/,会自动将压缩文件解压。
COPY
# COPY [--chown=:] ... : 将本地文件拷贝到容器中。不会解压
ENTRYPOINT
# 两种方式:1)、ENTRYPOINT command param1 param2;2)、 ENTRYPOINT ["executable", "param1", "param2"]
# 指定镜像的默认入口命令, 该入口命令会在启动容器时作为根命令执行, 所有传人值作为该命令的参数。每个Dockerfile中只能有一个ENTRYPOINT,在运行时, 可以被--entrypoint参数覆盖掉, 如docker run --entrypoint。
WORKDIR
# 指定容器工作目录
VOLUME
# 指定容器数据卷挂载点 VOLUME ["/data"]
 2、理解RUN、CMD、ENTRYPOINT、VOLUME等参数意义
RUN
# RUN 指令会在 build 镜像的时候,会在基础镜像的基础上生成容器,进入容器执行命令(比如安装一些工具),在进行操作完成之后,会将该容器提交成一个中间镜像,RUN 指令越多,构建的镜像层数越多,镜像size会越大,
# RUN   : 使用shell方式,默认/bin/sh 执行(也可指定/bin/bash)
# RUN [“executable”,”param1”,”param2”]:通过 executable 指定的方式 exec 进入容器,执行命令

CMD
# 以下 第一、第三种方式和 RUN 相同功能,如果存在多条 CMD 只有最后一条生效;如果和 ENTRYPOINT 同时存在,并且 CMD 不是以第二种方式存在,只执行ENTRYPOINT。而且 CMD 会被命令行的参数覆盖。
# CMD [“executable”,”param1”,”param2”] 
# CMD [“param1”,”param2”]   为 ENTRYPOINT 提供参数列表,拼接在 ENTRYPOINT 后面
# CMD  

ENTRYPOINT
# 不会被命令行的参数覆盖,容器启动时运行。Dockerfile 中必须存在 CMD 或者 ENTRYPOINT,两个都不存在会报错。

VOLUME
# VOLUME ["<路径1>","<路径2>“]  VOLUME <路径>
# 容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存到卷(volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在Dockerfile中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向存储层写入大量数据。
3、Dockerfile 编写示例
# 指明构建的镜像是来自于 centos:7 基础镜像
FROM centos:7
 
# 通过镜像标签声明了作者信息
LABEL maintainer="xxxx.com"
 
# 设置工作目录
WORKDIR /usr/local
 
# 新镜像构建成功以后创建指定目录
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
 
# 拷贝文件到镜像中并解压
ADD jdk-11.0.7_linux-x64_bin.tar.gz /usr/local/java
ADD apache-tomcat-9.0.39.tar.gz /usr/local/tomcat
 
# 暴露容器运行时的 8080 监听端口给外部
EXPOSE 8080
 
# 设置容器内 JAVA_HOME 环境变量
ENV JAVA_HOME /usr/local/java/jdk-11.0.7/
ENV PATH $PATH:$JAVA_HOME/bin
 
# 启动容器时启动 tomcat
CMD ["/usr/local/tomcat/apache-tomcat-9.0.39/bin/catalina.sh", "run"]
4、通过 Dockerfile 构建镜像

1)、使用当前 Dockerfile 所在目录进行构建镜像

docker build -t image_name:tag .   # 注意后面的 . 不能丢

2)、指定 Dockerfile 构建镜像

docker build -f /opt/dockerfile/Dockerfile -t image_name:tag .  # 注意后面的 . 不能丢

3)、在构建镜像时,(.)的意思

        构建的时候,由用户指定构建镜像时的上下文路径, 而 docker build 会将这个路径下所有的文件都打包上传给 Docker 引擎,引擎内将这些内容展开后,就能获取到上下文中的文件了,这个上下文路径就是当前 Dockerfile 所在路径,也可以指定其他路径。例如:

docker build -f /opt/dockerfile/Dockerfile -t image_name:tag /opt/docker  
# 这里的 /opt/docker 目录就是在镜像构建的时候 docker 引擎获取文件的路径
# 例如:在 ADD 命令; ADD jdk-8.tar.gz /opt/java,这个 jdk-8.tar.gz 文件要在 /opt/docker 目录下存在。

总结:本文介绍了另一种镜像生成的方式,详细介绍 Dockerfile 语法和使用,Dockerfile 还支持多阶段构建,以后有需求继续更新。

        本人是一个从小白自学计算机技术,对运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:上了年纪的小男孩。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)

Dockerfile 详解,使用 Dockerfile 构建镜像_第1张图片

你可能感兴趣的:(docker)