赞
踩
目录
(4)EXPOSE(只告诉其他人该端口需要被监听映射,由部署人员选择-P或者-p)
Dockerfile 是一种用于构建 Docker 镜像的文本格式文件,其中包含了所有构建镜像所需的指令和参数。使用 Dockerfile 可以将整个镜像构建过程自动化,并生成可重复性的镜像构建流程。
Dockerfile 的格式非常灵活,可以通过编写 Dockerfile 来描述构建镜像所需的一系列操作步骤,包括:
在 Dockerfile 中定义的每个指令都会创建一个新的镜像层,并在最终的镜像中体现出来。这样,在 Docker 运行容器时,可以根据这些层来构建整个容器文件系统。
以下是一个dockerfile构建镜像的示例:
- [root@dockerdemon nginx]# cat dockerfile
- FROM centos
- MAINTAINER xianchao
- RUN rm -rf /etc/yum.repos.d/*
- COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
- RUN yum install wget -y
- RUN yum install nginx -y
- COPY index.html /usr/share/nginx/html/
- EXPOSE 80
- ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
-
- [root@dockerdemon nginx]# ls
- Centos-vault-8.5.2111.repo index.html dockerfile
-
- # 构建镜像
- [root@dockerdemon nginx]# docker build -t "qingkaiping/nginx:v1" .
-
- # 运行容器,-p主机随机分配一个端口跟容器80端口映射
- [root@dockerdemon nginx]# docker run -d -p --name nginx_demo qingkaiping/nginx:v1
-
- # 使用docker ps 可以查看物理机的ip
- [root@dockerdemon nginx]# docker ps
-
- # 此时访问物理机ip:跟上映射端口即可访问到容器内的index.html
- curl localhost:34345
- -----------------------解释-------------------------------
- # FROM 基础镜像,一般是存在dockerhub上的
- FROM centos
-
- # MAINTAINER 作者信息
- MAINTAINER qingkaiping
-
- # RUN 可以理解成容器创建成功后执行的命令
- RUN rm -rf /etc/yum.repos.d/*
-
- # 将本地的repo文件拷贝到容器中去(ADD和COPY都可以实现)
- COPY Centos-baseos.repo /etc/yum.repos.d/
-
- # RUN 容器创建成功后安装wget
- RUN yum install wget -y
-
- # RUN 容器创建成功后安装nginx
- RUN yum install nginx -y
-
- # COPY将本地的index.html拷贝到容器中指定目录
- COPY index.html /usr/share/nginx/html/
-
- # 声明80端口
- EXPOSE 80
-
- # "/usr/sbin/nginx":启动nginx
- # "-g": Nginx 中的全局配置参数
- # "daemon off;": 不将 Nginx 以守护进程方式运行
- ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
Dockerfile 中的 FROM
指令用于指定该镜像所基于的父镜像或基础镜像,即在构建当前镜像时要依赖的镜像。
MAINTAINER
是一个从 Docker 1.13 版本开始被废弃的 Dockerfile 指令,用于指定维护该镜像的开发者信息,比如姓名、邮箱等。
在早期版本的 Docker 中,MAINTAINER
指令是非常重要的一个指令,因为它能够让用户知道该镜像的负责人是谁,当镜像出现问题时可以及时联系到负责人。但自从 Docker 1.13 版本开始,Docker 官方推荐使用 LABEL
指令来代替 MAINTAINER
指令,因为 LABEL
指令提供了更丰富的元数据信息,并且更具有可扩展性和可读性。
因此,如果你正在使用最新版的 Docker,建议使用 LABEL
指令来指定镜像的元数据信息,而不是使用 MAINTAINER
指令。例如,可以使用以下代码来指定镜像的维护者、邮箱和版本号等信息:
- LABEL maintainer="Binjie <qingkaiping@example.com>"
- LABEL version="1.0"
需要注意的是,虽然 MAINTAINER
指令已经被废弃,但它仍然可以在旧版本的 Docker 中使用,并且不影响镜像的构建和使用。
在 Dockerfile 中,RUN
指令有两种常见的形式,分别是 Shell 形式和 exec 形式。
1.Shell 形式
Shell 形式是使用 Shell 解释器来执行命令的形式,它的语法为:
RUN command arg1 arg2 ...
其中,command
是要执行的命令,arg1
、arg2
等是该命令的参数。例如:
RUN apt-get update && apt-get install -y python3-pip
在这个例子中,RUN
指令会执行 apt-get update
和 apt-get install -y python3-pip
两个命令,使用 Shell 解释器来解析并执行这两个命令。
2.exec 形式
exec 形式是直接执行命令,不需要通过 Shell 解释器的形式,它的语法为:
RUN ["executable", "arg1", "arg2", ...]
其中,executable
是要执行的命令,arg1
、arg2
等是该命令的参数。注意,参数必须是一个数组,而不是字符串。例如:
RUN ["/bin/bash", "-c", "echo hello world"]
在这个例子中,RUN
指令会执行 /bin/bash -c 'echo hello world'
命令,直接调用 /bin/bash
执行后面的命令,并输出 hello world
。-c
是 Bash 的一个参数,它的作用是告诉 Bash 解释器后面的字符串作为一条命令来执行。
- RUN ["/bin/bash", "-c", "echo hello world"]
- 等于
- RUN echo hello world
需要注意的是,在使用 RUN
指令时,应该尽量避免在同一个指令中执行多个命令,因为这样会增加镜像的层数,使得镜像变得臃肿和难以维护。如果必须要执行多个命令,应该使用 Shell 脚本或者多个 RUN
指令来完成。
EXPOSE
是 Dockerfile 中的一个指令,用于声明容器需要监听的端口号。它的语法为:
EXPOSE <port> [<port>/<protocol>...]
其中,<port>
是需要监听的端口号,<protocol>
是可选的协议(比如 TCP 或 UDP)。注意,EXPOSE
指令并不会实际上将容器中的端口暴露出去,它只是告诉 Docker 容器中有哪些端口可能需要被映射到主机上。
在 Dockerfile 中,使用 EXPOSE
指令可以让其他人知道该容器所监听的端口号,方便进行后续的交互和操作。例如,如果你的应用程序需要监听 8080 端口来接受 HTTP 请求,那么可以在 Dockerfile 中添加如下指令:
- EXPOSE 8080
- 多个端口用EXPOSE 8080 80
这样,其他人就知道该容器需要监听 8080 端口了。如果要将该端口映射到主机上,则需要使用 -p
或者 -P
参数来启动容器。例如:
docker run -p 8080:8080 myapp
这个命令会将容器中的 8080 端口映射到主机的 8080 端口上,从而允许外部网络访问该端口。如果不带任何参数启动容器,则无法从主机上访问该端口。
EXPOSE
指令是 Dockerfile 中非常重要的一个指令,它可以让我们声明容器需要监听的端口号,方便后续的交互和操作。但是需要注意的是,它并不会实际上将容器中的端口暴露出去,如果需要将端口映射到主机上,则需要使用 -p
或者 -P
参数启动容器。
Docker 提供了两个选项来进行端口映射:
-p
选项,语法为 -p <host_port>:<container_port>
,表示将主机上的 <host_port>
端口映射到容器内部的 <container_port>
端口。
-P
选项,表示随机映射一个主机端口到容器内部的暴露端口。
CMD(CMD
是 Dockerfile 中的一个指令,用于指定容器启动时默认执行的命令。它可以被覆盖,即在运行容器时也可以指定一个新的命令来替换原来的默认命令。)类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
1、CMD (docker启动时运行的命令)在docker run 时运行(所以docker run 指定运行时,CMD会被覆盖)。
2、RUN 是在 docker build构建镜像时运行的
CMD
指令有两种语法:
CMD ["executable","param1","param2"]
这种语法将可执行文件和参数作为 JSON 数组传递给 Docker 容器。例如:
CMD ["nginx", "-g", "daemon off;"]
意思是在容器内部执行 nginx -g "daemon off;"
命令作为默认命令。
CMD command param1 param2
这种语法是使用 shell 执行命令,并且允许在命令中使用 shell 的特殊字符。例如:
CMD echo "Hello, World!"
意思是在容器内部执行 echo "Hello, World!"
命令作为默认命令。
需要注意,Dockerfile 中只能使用一次 CMD
指令,如果在一个 Dockerfile 中定义了多个 CMD
指令,则只有最后一个 CMD
指令会生效。
在运行容器时,可以通过 docker run
命令的 CMD
参数来覆盖默认命令。例如:
- # 很简单,相当云使用docker run 启动的时候dockerfile中的CMD命令就没用了
- docker run nginx /bin/bash
- docker run nginx echo "666666"
这个命令将覆盖默认的 CMD
命令,使容器启动后默认进入 bash
shell,并输出66666而不是原来的“Hello, World!”
总结,CMD
指令用于指定容器启动时默认执行的命令。可以使用 JSON 数组或 shell 命令语法来指定命令,并且在运行容器时可以通过 docker run
命令的 CMD
参数来覆盖默认命令。
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
除非 docker run 时使用了 --entrypoint 选项,将覆盖 entrypoint指令指定的程序。
使用场景:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的固定参数,再使用docker run传变参(这块是一个参数拼接ENTRYPOINT +docker run的参数)。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
- ENTERYPOINT [“executable”,“param1”,“param2”](exec模式)
-
- ENTERYPOINT command (shell模式)
使用场景传参示例:
1.构建dockerfile
- [root@dockerdemon ~]# mkdir nginx
- [root@dockerdemon ~]# cd nginx/
-
- # 编辑dockerfile文件
- [root@dockerdemon nginx]# cat dockerfile
- FROM nginx
- ENTRYPOINT ["nginx", "-c"] # 固定参数
- CMD ["/etc/nginx/nginx.conf"] # 默认参数(可使用docker run覆盖代替它)
-
- # 使用docker build 构建镜像
- [root@dockerdemon nginx]# docker build -t "qingkaiping/nginx-cmd:v2" . --load
-
- ---------------------------------------------------------------------------------
- 解释:
- qingkaiping 是 Docker Hub 中的用户名或组织名
- test-cmd 是镜像的名称
- v2 表示镜像的版本号
- . 表示构建上下文
- --load 如果镜像不存在,Docker 会自动从 Docker Hub 或其他 registry 中下载基础镜像并构建新的镜像
- ---------------------------------------------------------------------------------
-
-
2.1 使用默认传参
2.2 使用变参
ADD
是 Dockerfile 中的指令,用于将本地文件或目录复制到容器中。
ADD
指令的语法如下:
- ADD <src> <dest>
-
- 示例:
-
- # 会将tar.gz 自动文件解压拷贝
- ADD nginx.tar.gz /opt
-
- # 将本地的 app.jar 文件复制到容器中的 /app/ 目录
- ADD app.jar /app/
-
- # 将本地的 src/ 目录及其内容复制到容器中的 /app/ 目录
- ADD src/ /app/
-
- # 将指定 URL 的文件下载并复制到容器中的 /app/file.txt
- ADD https://example.com/file.txt /app/file.txt
其中,<src>
表示要复制的源文件或目录路径,可以是本地路径或 URL,而 <dest>
表示目标路径,指定了文件或目录在容器内的位置。
请注意以下几点:
<dest>
是一个以 /
结尾的目录路径,<src>
将会被复制到该目录中。<dest>
不以 /
结尾,且容器内不存在该路径的文件或目录,则 <src>
的基本名称将会成为 <dest>
的文件名或目录名。<src>
是一个目录,Docker 将递归地复制整个目录结构到容器中。<src>
是一个 URL,Docker 会尝试下载并将其放置到 <dest>
。COPY
是 Dockerfile 中的指令,用于将本地文件或目录复制到容器中。
COPY
指令的语法如下:
- COPY <src> <dest>
-
- 示例:
- # 将本地的 src/ 目录及其内容复制到容器中的 /app/src/ 目录。
- COPY src/ /app/src/
-
- # 将本地的 app.jar 文件复制到容器中的 /app/app.jar。
- COPY app.jar /app/app.jar
VOLUME
VOLUME
是 Dockerfile 中的指令,用于在容器中创建一个或多个挂载点(卷),但是这个命令有一个弊端,我看来只能用作临时测试,华而不实,不如直接docker run -v将其挂载。
VOLUME
指令的语法如下:
- VOLUME <path>
-
- 示例:
- # 在容器内创建一个挂载点 /data,用于存储数据。
- VOLUME /data
-
- # 在容器内创建两个挂载点 /data1 和 /data2。
- VOLUME /data1 /data2
-
- # 在容器内创建三个挂载点,其中前两个是匿名卷,最后一个是命名卷。命名卷允许通过名称进行引用,使其可以在多个容器之间共享和重用。
- VOLUME ["/data1", "/data2", "named_volume:/data3"]
WORKDIR
是 Dockerfile 中的指令,用于设置容器内部的工作目录(简单来说就是切换当前目录所在位置的)。
WORKDIR
指令的语法如下:
- WORKDIR <path>
-
- 示例:
-
- # 在容器内部,将当前工作目录更改为上一个 WORKDIR 指令所设置的目录下的 app 目录。
- WORKDIR app
-
- # 在容器内部,将当前工作目录更改为根目录下的 /usr/src/app 目录,可多次使用并按顺序运行。
- WORKDIR /usr/src/app
- RUN touch ninjia
- WORKDIR /var/www/html
- RUN touch index.html
其中,<path>
表示要设置的工作目录路径。
使用 WORKDIR
指令可以更改容器中的当前工作目录。后续的 RUN
、CMD
、ENTRYPOINT
、COPY
和 ADD
等指令将在此目录下执行或操作文件。
ENV
是 Dockerfile 中的指令,用于设置环境变量(简单来说就是定义一个变量,方便后期使用)。
ENV
指令的语法如下:
- ENV <key>=<value>
-
- 示例:
- # 在容器中设置一个名为 DATABASE_URL 的环境变量
- ENV DATABASE_URL=mysql://user:password@localhost:3306/db_name
- RUN echo DATABASE_URL
-
-
- # 在容器中设置三个环境变量:APP_NAME 的值为 "My App",APP_VERSION 的值为 1.0,以及 DEBUG 的值为 false。
- ENV APP_NAME="My App" \
- APP_VERSION=1.0 \
- DEBUG=false
USER
是 Dockerfile 中的指令,用于设置容器运行时的用户(简单来说就是切换当前执行命令的用户,实际应用中某些权限问题)。
USER
指令的语法如下:
- USER <user>[:<group>]
-
- # 在容器中以 myuser 用户身份运行。
- USER myuser
-
- # 在容器中以 myuser 用户身份,且属于 mygroup 用户组运行。
- USER myuser:mygroup
-
ONBUILD
ONBUILD
是 Dockerfile 中的指令,用于定义触发器指令,以便在派生镜像中延迟执行一组命令。
使用 ONBUILD
指令可以在构建一个基础镜像时,在派生镜像构建过程中自动触发一组命令。这意味着在构建基础镜像时,不会立即执行 ONBUILD
指令中的命令,而是在基于该基础镜像构建的派生镜像中运行。
ONBUILD
指令的语法如下:
- ONBUILD <trigger-instruction>
- # 其中,<trigger-instruction> 可以是任何有效的 Dockerfile 指令(例如 RUN、COPY、CMD 等),作为触发器,将在派生镜像构建过程中执行。
-
- 示例1:
- FROM ubuntu
- ONBUILD RUN echo "This is an example"
- CMD ["echo", "Hello, World!"]
-
- # 构建镜像,此时不会执行echo "This is an example"
- docker build -t "qingkaiping/onbuild:v2" .
-
- 示例2:
- FROM qingkaiping/onbuild:v2
- RUN touch ninjia
-
- # 构建镜像,此时会执行示例1的 RUN echo "This is an example"
- docker build -t "qingkaiping/onbuild:v2" .
-
- 总结:ONBUILD 参数,作为第一个构建镜像,是注释掉的,第二个镜像引用它才会生效
在上面的例子中,当构建这个基础镜像时,CMD
的命令不会被执行。然而,如果有其他 Dockerfile 使用这个作为基础镜像进行构建,echo "This is an example"
将作为触发器命令,并在派生镜像构建过程中执行。
在实际应用中,ONBUILD
指令通常用于创建通用的基础镜像,并为特定需求的派生镜像定义一些自定义操作或配置。这样,可以将公共的构建逻辑封装到基础镜像中,简化了派生镜像的构建过程。
HEALTHCHECK
是 Dockerfile 中的指令,用于定义容器的健康检查行为。
使用 HEALTHCHECK
指令可以告诉 Docker 如何检测容器的健康状态。健康检查可以判断应用程序是否正常运行,并根据检查结果来决定容器是否健康。
HEALTHCHECK
指令的语法如下:
- HEALTHCHECK [OPTIONS] CMD <command>
-
- 其中,OPTIONS 表示健康检查的选项,可以是以下选项之一:
- --interval=<duration>:指定健康检查的间隔时间,默认为 30 秒。
- --timeout=<duration>:指定单次健康检查命令的超时时间,默认为 30 秒。
- --start-period=<duration>:指定容器启动后,等待进行首次健康检查的时间,默认为 0 秒。
- --retries=<num>:指定在判定容器不健康之前尝试的健康检查次数,默认为 3 次。
- CMD <command> 表示要执行的健康检查命令,可以是任意有效的命令。常见的健康检查命令包括使用 curl、wget 或其他网络客户端工具检查服务的可访问性,或者执行自定义脚本来检查服务的状态。
-
- 示例:
- FROM ubuntu
- HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/ || exit 1
-
- 解释:
- --interval=5s 表示每隔 5 秒进行一次健康检查。
- --timeout=3s 表示单次健康检查命令的超时时间为 3 秒。
- CMD <command> 表示要执行的健康检查命令。
- curl -f http://localhost/ 表示请求网址。
- || 是 shell 中的逻辑运算符,表示“或”操作。command1 || command2 的意思是,如果 command1 执行成功(即返回退出状态码为 0),则不执行 command2;如果 command1 执行失败(即返回非零退出状态码),则执行 command2。
- 在容器的健康检查设置中使用 || exit 1 的目的是在命令执行失败时,通过将容器以退出状态码 1 结束来表示健康检查失败。这样,Docker 将会根据容器的重启策略来处理这种情况。如果重启策略允许,Docker 会自动重启容器,以保持应用程序的可用性。
ARG
是用于在构建 Docker 镜像时传递参数的指令。
使用 ARG
指令可以在构建过程中定义一个或多个变量,并将这些变量作为参数传递给 Dockerfile 中的其他指令
- ARG <name>[=<default value>]
- <name>: 参数的名称。
- <default value>(可选):参数的默认值。
-
- 在 Dockerfile 中设置了 ARG 参数后,可以在后续的指令中引用它。例如,可以在 ENV 指令中使用该参数来设置环境变量的值
-
- ARG MY_NAME=John Doe
- ENV NAME $MY_NAME
- RUN echo "Hello, $NAME!"
ARG
用于在构建过程中传递参数,并且只在构建时期有效;而 ENV
用于在容器运行时设置环境变量,在容器内部对应用程序和脚本可见。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。