DockerFile | 简介

1.Dockerfile概念

Dockerfile是一个文本格式的配置文件,用于定义Docker镜像的内容和构建步骤。它包含一系列指令,每个指令代表一个构建步骤,从基础镜像开始,逐步构建出最终的镜像。通过Dockerfile,用户可以精确地描述应用程序运行环境的配置、依赖项安装、文件复制等操作。这使得应用程序的部署和分发变得更加可控和可重复。Dockerfile的内容可以根据需求自定义,允许开发者根据应用程序的特性和需求来灵活配置镜像的构建过程,从而实现高效、可靠的容器化部署

2.Dockerfile的优缺点

优点:

简化部署:Dockerfile 使得应用的部署过程变得标准化和可重复

容器为单位的应用交付:开发者可以将应用和它的依赖打包到一个容器中,这就意味着应用可以在任何支持 Docker 的机器上运行

易于维护:Dockerfile 是代码,所以有版本控制

易于理解:Dockerfile 是一种声明式语言,可以让用户理解镜像是如何构建的

高效:使用 Dockerfile 构建的镜像层可以高度重用,因此镜像的大小也会小

缺点:

构建时间:每次构建都会重新安装所有依赖,这可能会增加构建时间

构建大小:每一层都会增加最终镜像的大小

安全问题:如果在 Dockerfile 中使用错误的指令或者将敏感信息暴露在 Dockerfile中,可能会引起安全问题

3.基本结构

Dockerfile由一行行命令语句组成,并且支持以 # 开头的注释行。

一般而言,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

4.Dockerfile 指令详解

  1. FROM:指定基础镜像,用于后续的指令构建

该指令有两种格式:

FROM

指定基础image为该image的最后修改的版本。或者:

FROM :

指定基础image为该image的一个tag版本。

例如:FROM ubuntu:20.04

2.RUN:构建镜像时运行的指令

shell格式:就像在命令行中输入的Shell脚本命令一样。

RUN

exec格式:就像是函数调用的格式。

RUN ["executable", "param1", "param2"]

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大

RUN apt-get update && apt-get install -y nginx

3.CMD:容器启动时要运行的命令

包含三种语法格式,如下所示:

第一种就是shell这种执行方式和写法

CMD command param1 param2

第二种是可执行文件加上参数的形式(推荐)

CMD ["executable","param1","param2"]

该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

CMD ["","",...]

需要注意的是,一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用。CMD会被docker run之后的参数替换,如果我们在Dockerfile中指定了CMD指令,通过在docker run命令行中也指定了要运行的命令,命令行中的指令会覆盖Dockerfile中的CMD指令

4.COPY:从上下文目录中复制文件或者目录到容器里指定路径

COPY <源路径> <目标路径>

复制宿主机文件index.html到容器/data/html/index.html

COPY index.html /data/html/index.html

复制宿主机data目录下文件(包括子目录)到容器/data/目录下,并不会复制目录本身

例:COPY data /data/

5.ADD:ADD 指令和 COPY 的使用类似(同样需求下,官方推荐使用COPY),功能也类似。除 此之外,ADD还支持使用tar文件和URL路径,并且会将tar压缩文件(gzip, bzip2以及 xz格式) 解压缩,如果指定的是url,会从指定的url下载文件放到目录中(如果url下载的文件为tar文件,则不会展开)

ADD

例:ADD /data/src/nginx-1.14.0.tar.gz /data/src/

6.ENV:在容器内部设置环境变量

ENV=

例:ENV JAVA_HOME=/usr/local/jdk1.7.0_79

ENV PATH=JAVA_HOME/bin:PATH

7.ENTRYPOINT:设置指令,指定容器启动时执行的命令,可以多次设置,但是只有最后一个有效

该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。

当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command param1 param2 (shell内部命令)

比如:

CMD指令将不会被执行,只有ENTRYPOINT指令被执行

CMD echo "Hello, World!"

ENTRYPOINT ls -l

另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分。ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。

FROM centos7

CMD ["-l"]

ENTRYPOINT ["/usr/bin/ls"]

8.EXPOSE:EXPOSE指令用于告诉Docker容器监听哪些网络端口。在Dockerfile中使用EXPOSE指令并不会自动将容器的端口暴露出来,需要使用docker run命令的-p或者-P选项来映射容器内部端口到宿主机的端口

EXPOSE指令的语法格式为:

EXPOSE[/...]

其中,表示需要监听的端口号,可以是1-65535之间的整数;表示需要监听的协议,可以是tcp或udp。

如果需要监听多个端口,则可以在EXPOSE指令中多次指定端口号,或者使用","分隔多个端口号。

下面是一个示例:

FROM ubuntu:18.04

EXPOSE 80/tcp

EXPOSE 443/tcp

以上Dockerfile告诉Docker容器需要监听80和443端口,并使用tcp协议。在运行容器时,可以使用如下命令将容器内部的80端口映射到宿主机的8080端口:

docker run -p 8080:80 myimage

这样,就可以通过访问宿主机的8080端口来访问容器内部的80端口了

9.VOLUME:为容器创建挂载点或声明卷

作用:

避免重要的数据,因容器重启而丢失,这是非常致命的。

避免容器不断变大。

格式:VOLUME ["<路径1>", "<路径2>"...]

VOLUME <路径>

定义一个匿名卷

FROM ubuntu:16.04

VOLUME /data

定义多个匿名卷

FROM ubuntu:16.04

VOLUME ["/data", "/command"]

使用VOLUME指令后,Docker会在容器中创建一个或多个匿名卷(anonymous volume),这些匿名卷将持久化存储容器中的数据。当容器删除时,这些匿名卷不会被自动删除,需要手动删除它们。

10.USER:用于指定执行后续命令的用户和用户组

格式:USER <用户名>[:<用户组>]

USER user

USER user:group

11.ONBUILD:用于延迟构建命令的执行。简单的说,就是Dockerfile里用ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的Dockerfile 使用了之前构建的镜像FROM test-buil,这时执行新镜像的Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令

格式:ONBUILD <其它指令>

ONBUILD RUN mkdir test

12.ARG:构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile内有效,也就是说只有docker build 的过程中有效,构建好的镜像内不存在此环境变量。构建命令docker build 中可以用 --build-arg <参数名>=<值> 来覆盖

格式:ARG <参数名>[=<默认值>]

13.WORKDIR:指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录

格式:WORKDIR <工作目录路径>

WORKDIR /path/to/workdir

在 /p1/p2 下执行 vim a.txt

WORKDIR /p1 WORKDIR p2 RUN vim a.txt

14.LABEL:使用LABEL指令可以为镜像添加元数据,这些元数据可以包含关于镜像的描述、版本号、维护者信息等

LABEL指令的语法如下:

LABEL===...

比如我们可以添加镜像的作者:

LABEL org.opencontainers.image.authors="runoob"

15.HEALTHCHECK:用于指定某个程序或者指令来监控 docker 容器服务的运行状态是否正常

语法格式如下:

设置检查容器健康状况的命令

HEALTHCHECK [OPTIONS] CMD <命令>

如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK NONE

5.示例

相关推荐
程序猿阿伟4 分钟前
《C++中的魔法:实现类似 Python 的装饰器模式》
java·c++·装饰器模式
Mr. zhihao6 分钟前
装饰器模式详解:动态扩展对象功能的优雅解决方案
java·开发语言·装饰器模式
zyhomepage6 分钟前
科技的成就(六十四)
开发语言·人工智能·科技·算法·内容运营
Ethan Wilson12 分钟前
C++/QT可用的websocket库
开发语言·c++·websocket
2401_8576009513 分钟前
商场应急管理:SpringBoot技术解决方案
java·spring boot·后端
Ivanqhz13 分钟前
Spark RDD
大数据·分布式·spark
想做白天梦24 分钟前
多级反馈队列
java·windows·算法
潇雷26 分钟前
算法Day12|226-翻转二叉树;101-对称二叉树;104-二叉树最大深度;111-二叉树最小深度
java·算法·leetcode
一颗甜苞谷33 分钟前
开源一套基于若依的wms仓库管理系统,支持lodop和网页打印入库单、出库单的源码
java·开源