Dockerfile 笔记

news/2025/1/17 16:42:17/文章来源:https://www.cnblogs.com/TMesh/p/18677298

目录
  • 概述
  • 基本结构
  • 简单示例
    • 示例1
    • 示例2
        • 构建镜像
    • 示例3
      • 发布一个自己编写的 centos
    • 项目中编写 dockerfile 思路
  • Dockerfile 构建过程
  • Dockerfile 指令
    • FROM - 指定基础镜像
    • MAINTAINER - 指定生成镜像的作者名称
    • WORKDIR - 指定工作目录
    • RUN - 运行指定的命令
    • ADD - 复制文件或者目录到容器里指定路径
    • COPY - 复制文件或者目录到容器里指定路径
    • LABEL-为镜像指定标签
    • CMD - 容器启动时要运行的命令
    • ENTRYPOINT - 为容器指定默认运行程序
    • ENV - 设置环境变量
    • ARG-设置环境变量
    • EXPOSE - 为容器打开指定要监听的端口以实现与外部通信
    • VOLUME - 定义匿名数据卷
    • USER - 指定执行后续命令的用户和用户组
    • ONBUILD - 用于延迟构建命令的执行
    • STOPSIGNAL
    • HEALTHCHECK - 容器健康状况检查
    • SHELL - 重写 xxx 指令的 shell 格式所使用的默认 shell
    • CMD和ENTRYPOINT的区别
  • Dockerfile综合实验
    • 构建 Tomcat 镜像
      • 构建步骤
      • Dockerfile文件
  • 练习:构建一个 tomcat,编写首页

概述

[Pasted image 20240731141223.png]
Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义的镜像。
[Pasted image 20240731141307.png]

基本结构

Dockerfile由一行行命令语句组成,并且支持以 # 开头的注释行。一般而言,Dockerfile分为四部分: 基础镜像信息维护者信息镜像操作指令容器启动时执行指令
例如:

##  Dockerfile文件格式 
# 1、第一行必须指定 基础镜像信息
FROM java:8
# 2、维护者信息
MAINTAINER oldGj_  oldGj_@163.com
# 3、镜像操作指令
RUN  echo "wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.55/bin/apache-tomcat-9.0.55.tar.gz"
run tar -zxvf apache-tomcat-9.0.55.tar.gz -C /usr/local
# 4、容器启动执行指令
CMD /usr/local/tomcat/bin/catalina.sh
  • Dockerfile 四部分说明:
    • 一开始必须要指明所基于的镜像名称,关键字是 FROM,这是必须的。
    • 接下来是维护者信息关键字是 MAINTAINER,非必须, 但良好的习惯有利于后期的职责明确。
    • 后面是镜像操作指令,如 RUN 等, 每执行一条 RUN 命令,镜像添加新的一层。
    • 最后是 CMD 指令,来指明运行容器时的操作命令。
      [Pasted image 20240731141445.png]

简单示例

在一个空白的文本文件,命名为Dockerfile

vim  Dockerfile

示例1

Dockerfile 文件内容:

#基础镜像
FROM centos
#维护者
MAINTAINER oldGj_<oldGj_@163.com>
#运行命令
RUN "yum install wget"
#启动容器运行命令
CMD echo "hello Dockerfile"

示例2

Dockerfile 文件内容:

FROM java:8
MAINTAINER WCC 
CMD java -version

构建镜像

docker build -t 镜像名字:版本 . 
  • 注意
    • . 代表 Dockerfile 文件在当前路径

示例3

发布一个自己编写的 centos

Dockerfile 文件内容:

FROM centos7.9.2009
MAINTAINER akuya<123456@qq.com># 配置环境以及工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH# 安装vim、ipconfig等命令
RUN yum -y install vim
RUN yum -y install net-tools# 暴露端口
EXPOSE 80CMD echo $MYPATH
CMD echo "---akuya---"
CMD /bin/bash

由于最新版 centos8 有 bug,故使用 centos7.9版本
根据 dockerfile 构建镜像

docker build .

参数:

  • -f:等价于--file,指定 dockerfile 文件
  • -t:等价于--tag,指定输出的镜像文件名:版本号
    命令最后一定要加一个.
# 构建镜像命令
docker build -f Dockerfile -t mycentos:1.0 .

项目中编写 dockerfile 思路

  1. 基于一个空的镜像
  2. 下载需要的环境 ADD
  3. 执行环境变量的配置 ENV
  4. 执行一些Linux命令 RUN
  5. 日志 CMD
  6. 端口暴露 EXPOSE
  7. 挂载数据卷 VOLUMES
    这个过程就是你手动部署项目的过程,你通过 docker 可以再未来实现自动化构建。

Dockerfile 构建过程

  • 基础知识:
    • 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
    • 指令按照从上到下,顺序执行
    • # 表示注释
    • 每条指令都会创建一个新的镜像层,并对镜像进行提交
  • 流程:
    1. docker 从基础镜像运行一个容器
    2. 执行一条指令并对容器做出修改
    3. 执行类似 docker commit 的操作提交一个新的镜像层
    4. docker 再基于刚提交的镜像运行一个新容器
    5. 执行 dockerfile 中的下一条指令直到所有指令都执行完成!
      说明:
      从应用软件的角度来看,dockerfile,docker 镜像与 docker 容器分别代表软件的三个不同阶段。
  • dockerfile 是软件的原材料(代码)
  • docker 镜像则是软件的交付品(.apk)
  • docker 容器则是软件的运行状态(客户下载安装执行)
    dockerfile 面向开发,docker 镜像成为交付标准,docker 容器则涉及部署与运维,三者缺一不可!
    [Pasted image 20240731153729.png]
  • dockerfile:需要定义一个 dockerfile,dockerfile 定义了进程需要的一切东西。dockerfile 涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当引用进行需要和系统服务和内核进程打交道,这时需要考虑如何设计 namespace 的权限控制)等等。
  • docker 镜像:在 dockerfile 定义了一个文件之后,docker build 时会产生一个 docker 镜像,当运行 docker 镜像时,会真正开始提供服务;
  • docker 容器:容器是直接提供服务的。

Dockerfile 指令

FROM         # 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER   # 镜像维护者的姓名混合邮箱地址
RUN          # 容器构建时需要运行的命令
EXPOSE       # 当前容器对外保留出的端口
WORKDIR      # 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点
ENV          # 用来在构建镜像过程中设置环境变量
ADD          # 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY         # 类似ADD,拷贝文件和目录到镜像中!
VOLUME       # 容器数据卷,用于数据保存和持久化工作
CMD          # 指定一个容器启动时要运行的命令,dockerFile中可以有多个CMD指令,但只有最后一个生效!
ENTRYPOINT   # 指定一个容器启动时要运行的命令!和CMD一样
ONBUILD      # 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的ONBUILD被触发

FROM - 指定基础镜像

指定基础镜像,并且 Dockerfile 中第一条指令必须是 FROM 指令,且在同一个 Dockerfile 中创建多个镜像时,可以使用多个 FROM 指令。
指令格式:

FROM <image>  
FROM <image>:<tag>  

其中<tag>是可选项,如果没有选择,那么默认值为latest
如果不以任何镜像为基础,那么写法为:FROM scratch

MAINTAINER - 指定生成镜像的作者名称

维护者信息
指令格式:

MAINTAINER <name>

示例

 MAINTAINER TMesh   MAINTAINER TMesh@163.com  

MAINTAINER指令已经被弃用,可以使用LABEL指令进行替代,样例如下:

LABEL maintainer='Stephen Chow'

说明:
LABEL 会继承基础镜像中的 LABEL,如遇到 key 相同,则值覆盖。

WORKDIR - 指定工作目录

工作目录,类似于 cd 命令
用于为 Dockerfile 中所有的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指令设定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
在 Dockerfile 文件中,WORKDIR 指令可出现多次,其路径也可以为相对路径,不过,它的路径是相对此前一个 WORKDIR 指令指定的路径。另外,WORKDIR 也可调用由 ENV 指定定义的变量。
指令格式:

WORKDIR <工作目录路径>WORKDIR /usr/workdir

示例

WORKDIR /var/log 
# 解析环境变量 
ENV DIRPATH /path 
WORKDIR $DIRPATHWORKDIR /a  (这时工作目录为/a)
WORKDIR b  (这时工作目录为/a/b)
WORKDIR c  (这时工作目录为/a/b/c)
# pwd执行的结果是/a/b/c

示例

WORKDIR /OPT
RUN mkdir docker
WORKDIR /usr/local
RUN echo "test" > a.info

注意: 通过 WORKDIR 设置工作目录后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。在使用 docker run 运行容器时,可以通过 -w 参数覆盖构建时所设置的工作目录。

RUN - 运行指定的命令

构建镜像时执行的命令
指令语法:

# 1. shell格式:就像在命令行中输入的Shell脚本命令一样。
格式 RUN <command>
# 2. exec格式:就像是函数调用的格式。
格式 RUN ["executable", "param1", "param2"]

第一种后边直接跟 shell 命令。

  • 在linux操作系统上默认为/bin/sh -c
  • 在windows操作系统上默认为cmd /S /C
    第二种是类似于函数调用。可将 executable 理解成为可执行文件,后面就是两个参数。
    样例:
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'RUN ["/bin/bash", "-c", "echo hello"] 

示例

WORKDIR /OPT
RUN mkdir docker
WORKDIR /usr/local
RUN echo "test" > a.info

注意:
RUN 指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定 –no-cache 参数,如:docker build --no-cache
多行命令不要写多个 RUN,原因是 Dockerfile 中每一个指令都会建立一层。多少个 RUN 就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。RUN 书写时的换行符是 \

ADD - 复制文件或者目录到容器里指定路径

将本地文件添加到容器中,tar 类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似 wget。
ADD 指令和 COPY 的使用类似 (同样需求下,官方推荐使用 COPY) ,功能也类似。除此之外,ADD 还支持使用 TAR 文件和 URL 路径,并且会将 tar 压缩文件(gzip, bzip2 以及 xz 格式)解压缩,如果指定的是 url,会从指定的 url 下载文件放到目录中( 如果 url 下载的文件为 tar 文件,则不会展开)。
指令格式:

ADD <src>... <dest>  
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径示例:  
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

示例

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

添加所有以"hom"开头的文件

ADD hom* /mydir/ 

? 替代一个单字符,例如:“home.txt”

ADD hom?.txt /mydir/   

添加 “test” 到 WORKDIR/relativeDir/

ADD test relativeDir

添加 “test” 到 /absoluteDir/

ADD test /absoluteDir/

COPY - 复制文件或者目录到容器里指定路径

从上下文目录中复制文件或者目录到容器里指定路径。
功能类似 ADD,但是是不会自动解压文件,也不能访问网络资源。
语法格式:

COPY <源路径>  <目标路径>
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

参数说明:

  • [–chown=:] :可选参数,用户改变复制到容器内文件的拥有者和属组。
  • <源路径> :源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:COPY hom* /mydir/COPY hom?.txt /mydir/。源路径必须是build上下文中的路径,不能是其父目录中的文件。如果源路径是目录,则其内部文件或子目录会被递归复制,但源路径目录自身不会被复制。如果指定了多个源路径,或在源路径中使用了通配符,则目标路径必须是一个目录,且必须以/结尾。
  • <目标路径> :容器内的指定路径,建议为目标路径使用绝对路径,否则,COPY 指令则以 WORKDIR 为其起始路径;如果目标路径事先不存在,它将会被自动创建,这包括其父目录路径。
    示例
COPY ./start.sh /start.sh# 复制宿主机文件 index.html 到容器 /data/html/index.html
COPY index.html /data/html/index.html   # 复制宿主机 data 目录下文件(包括子目录)到容器 /data/ 目录下,并不会复制目录本身
COPY data  /data/    

LABEL-为镜像指定标签

为镜像指定标签,其格式为:

LABEL <key1>=<value1> <key2>=<value2> ...

LABEL后面是键值对,多个键值对以空格进行隔开,如果 value 中包含空格,请使用""将 value 进行圈起来。

# 如果太长需要换行的话,则使用\符号
LABEL name=test \description="a container is used to test"

我们可以使用docker inspect命令,来查看镜像的标签:

docker inspect --format '{{json .Config.Labels}}' test | python3 -m json.tool

其中,“test”为容器名称,”python3 -m json.tool“为将其格式化为 JSON 输出。

CMD - 容器启动时要运行的命令

构建容器后调用,也就是在容器启动时才进行调用。指定这个容器启动的时候要运行的命令只有最后一个会生效可被替换。
指令格式:
CMD指令与RUN指令相似,也具有两种格式:

  1. shell格式:CMD <命令>
  2. exec格式: CMD ["可执行文件", "参数1", "参数2", …]
  3. ENTRYPOINT 指令程序
# 第一种就是shell这种执行方式和写法
CMD command param1 param2# 第二种是可执行文件加上参数的形式(推荐)
CMD ["executable","param1","param2"] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
CMD ["<param1>","<param2>",...]  

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh
样例:

CMD [ "sh", "-c", "echo $HOME" ]CMD [ "echo", "$HOME" ] 

注意:
这里边包括参数的一定要用双引号,不能是单引号。千万不能写成单引号。原因是参数传递后,docker 解析的是一个 JSON array.
CMD 不同于 RUN,CMD 用于指定在容器启动时所要执行的命令,而 RUN 用于指定镜像构建时所要执行的命令。

ENTRYPOINT - 为容器指定默认运行程序

配置容器,使其可执行化。配合 CMD 可省去"application",只使用参数。
指定容器启动的要运行的命令,可以追加命令
类似 CMD 指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序。
在写 Dockerfile 时,ENTRYPOINT 或者 CMD 指令会自动覆盖之前的 ENTRYPOINT 或者 CMD 指令。即 ENTRYPOINT 或者 CMD 指令只能写一条,如果写了多条,那么, ENTRYPOINT 或者 CMD 都只有最后一条生效。
在 Docker 镜像运行时, 用户也可以在命令行指定具体命令,覆盖在 Dockerfile 里的命令。
与 CMD 不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给 ENTRYPOINT 指令指定的程序,不过,docker run命令的--entrypoint选项的参数可覆盖 ENTRYPOINT 指令指定的程序。
指令格式:

# exec格式(推荐)
ENTRYPOINT ["executable", "param1", "param2"] # shell格式
ENTRYPOINT command param1 param2

第一种就是可执行文件加参数。与CMD指令一样,ENTRYPOINT也更加推荐使用exec格式。
第二种就是 shell 格式。
样例:

FROM ubuntu 
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* 
ENTRYPOINT ["curl", "-s", "http://ip.cn"]
# 将其构建成镜像 ubuntu:v1.2,下面我们创建并启动容器:
docker run -it ubuntu:v1.2# 将会在控制台输出我们相应的公网 IP 信息!
# 此时,如果我们还需要获取 HTTP 头信息时,我们可以这样:
docker run -it ubuntu:v1.2 -i

注意:
ENTRYPOINT 与 CMD 非常类似,不同的是通过 docker run 执行的命令不会覆盖 ENTRYPOINT,而 docker run 命令中指定的任何参数,都会被当做参数再次传递给 ENTRYPOINT。Dockerfile 中只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令。

ENV - 设置环境变量

设置环境变量,无论是接下来的指令(如ENVADDCOPY等,其调用格式为$variable_name${variable_name}),还是在容器中运行的程序,都可以使用这里定义的环境变量。
指令格式:

ENV <key> <value> ENV <key1>=<value1> <key2>=<value2> ... 

示例

ENV JAVA_HOME=/usr/local/jdk1.7.0_79
ENV PATH=$JAVA_HOME/bin:$PATHENV word hello
ENV guodong xxxx    
ENV name1=ping name2=on_ipRUN echo $word

注意:
如果你想通过 CMD 或者 ENTRYPOINT 指令的 exec 格式来打印环境,就像下面这样:
CMD ["echo", $MODE]
CMD ["echo", "$MODE"]
这样都是不能正确输出环境变量的值的,你可以改成exec格式来执行shell命令,如下所示:
CMD ["sh", "-c", "echo $MODE"]
如此,就能正确输出环境变量的值了!

ARG-设置环境变量

构建参数ARGENV指令一样,都是设置环境变量。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有docker build 的过程中有效,构建好的镜像内不存在此环境变量。即在将来容器运行时是不会存在这些环境变量的。但是不要因此就用ARG来保存密码之类的信息,因为通过docker history还是能够看得到的。
ARG构建命令在docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
语法格式如下:

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

示例:

FROM ubuntu:16.04
ARG app="python-pip"
RUN apt-get update && apt-get install -y $app && rm -rf /var/lib/apt/lists/*# 我们可以定义多个参数
FROM busybox
ARG user1
ARG buildno# 也可以给参数一个默认值
FROM busybox
ARG user1=someuser
ARG buildno=1
# 如果我们给 ARG 定义了参数默认值,那么当 build 镜像时,如果没有指定参数值,将会使用这个默认值。

EXPOSE - 为容器打开指定要监听的端口以实现与外部通信

用于为容器打开指定要监听的端口以实现与外部通信,这个只是声明,真正要暴露这个端口需要再构建容器的时候使用"-P"选项。其格式为:
指令格式:

EXPOSE <port> [<port>/<protocol>...]

示例

EXPOSE 80
EXPOSE 80/tcp
EXPOSE 80/udp

如果想使得容器与主机的端口有映射关系,需要在启动容器时指定-P.

# 这里的“-P”选项是关键,在启动容器的使用使用-P,
# Docker会自动分配一个端口和转发指定的端口,
# 使用-p可以具体指定使用哪个本地的端口来映射对外开放的端口。
docker run --rm --name nginx -itd -P nginx:v1.4

注意:
EXPOSE并 不会让容器的端口访问到主机。要使其可访问,需要在 docker run 运行容器时通过 -p 来发布这些端口,或通过 -P 参数来发布 EXPOSE 导出的所有端口。

VOLUME - 定义匿名数据卷

用于指定持久化目录
定义匿名数据卷,可实现挂载功能,可以将内地文件夹或者其他容器中得文件夹挂在到这个容器中。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:

  • 避免重要的数据,因容器重启而丢失,这是非常致命的。(容器使用的是 AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。)
  • 避免容器不断变大。
    指令格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>VOLUME ["/path/to/dir"]

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
示例

VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2"]# 定义一个匿名卷
FROM ubuntu:16.04
VOLUME /data# 定义多个匿名卷
FROM ubuntu:16.04
VOLUME ["/data", "/command"]

这里的/data/command目录在容器运行时会自动挂载为匿名卷,任何向/data/command目录中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化!容器匿名卷目录指定可以通过docker run命令中指定-v参数来进行覆盖。
注意:
一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

1 卷可以容器间共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后会立即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它

USER - 指定执行后续命令的用户和用户组

USER 指令用于将会用以什么样的用户去运行
用于指定执行后续命令的用户和用户组,这里只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。在 USER 命令之前可以使用 RUN 命令创建需要的用户。
默认情况下,容器的运行身份为 root 用户。
指令格式:

# 可以指定用户名或者UID,组名或者GID
USER <user>[:<group>]
USER <UID>[:<GID>]USER user
USER user:group

样例:

RUN groupadd -r docker && useradd -r -g docker dockerUSER docker

ONBUILD - 用于延迟构建命令的执行

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
ONBUILD是一个特殊的指令,它后面跟着的是其他指令,比如COPYRUN等,而这些命令在当前镜像被构建时,并不会被执行。只有以当前镜像为基础镜像去构建下一级镜像时,才会被执行。
Dockerfile中的其他指令都是为了构建当前镜像准备的,只有ONBUILD指令是为了帮助别人定制而准备的。
指令格式:

ONBUILD [INSTRUCTION]ONBUILD <其他指令>

示例

FROM centos
WORKDIR /data
ONBUILD RUN mkdir testFROM test:02FROM ubuntu:16.04
WORKDIR /data
ONBUILD RUN mkdir test

STOPSIGNAL

设置将发送到容器以退出的系统调用信号。这个信号可以是一个有效的无符号数字,与内核的syscall表中的位置相匹配,如9,或者是SIGNAME格式的信号名,如SIGKILL
语法格式如下:

STOPSIGNAL signal

默认的停止信号是SIGTERM,在docker stop的时候会给容器内 PID 为 1 的进程发送这个 signal,通过--stop-signal可以设置自己需要的 signal,主要的目的是为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出。如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是 10s。

HEALTHCHECK - 容器健康状况检查

用于指定某个程序或者指令来监控 docker 容器服务的运行状态是否正常。
语法格式如下:

# 设置检查容器健康状况的命令
HEALTHCHECK [OPTIONS] CMD <命令># 如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK NONE
  • OPTIONS 参数说明:
    • –interval=<间隔> :两次检查的时间间隔,默认为 30s
    • –timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次健康检查将会判定为失败,默认为 30s
    • –retries=<次数> :当连续失败指定次数之后,则将容器状态视为unhealthy,默认为 3 次。
    • –start-period=DURATION:启动时间,默认为 0s, 如果指定这个参数, 则必须大于 0s ;--start-period 为需要启动的容器提供了初始化的时间段, 在这个时间段内如果检查失败, 则不会记录失败次数。 如果在启动时间内成功执行了健康检查, 则容器将被视为已经启动, 如果在启动时间内再次出现检查失败, 则会记录失败次数。
      在 CMD 关键字之后的 command 可以是一个 shell 命令(例如: HEALTHCHECK CMD /bin/check-running)或者一个 exec 数组(与其它 Dockerfile 命令相同, 参考 [ENTRYPOINT])。
      该命令的返回值说明了容器的状态, 可能是值为:
  • 0: healthy - 容器健康,可以使用;
  • 1: unhealthy - 容器工作不正常,需要诊断;
  • 2: reserved - 保留,不要使用这个返回值;
    当容器的健康状态发生变化时,会生成一个带有新状态的 health_status 事件。
    样例:
HEALTHCHECK --interval=5m --timeout=3s \CMD curl -f http://localhost/ || exit 1

注意:
CMDNETRYPOINT一样,HEALTHCHECK指令只可以出现一次,如果有多个HEALTHCHECK指令,那么只有最后一个才会生效!

SHELL - 重写 xxx 指令的 shell 格式所使用的默认 shell

SHELL指令允许重写xxx指令的shell格式所使用的默认shell。关于默认的shellLinux["/bin/sh", "-c"]Windows["cmd", "/S", "/C"]
SHELL 指令必须在dockerfile中以JSON格式编写。
SHELL 指令在 Windows 上特别有用,Windows 有两种常用且截然不同的本机 shell:cmd 和 powershell,以及可用的备用 shell,包括 sh
SHELL 指令可以出现多次。 每条 SHELL 指令都会覆盖所有先前的 SHELL 指令,并影响所有后续指令。
样例:

FROM microsoft/windowsservercore# Executed as cmd /S /C echo default
RUN echo default# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S", "/C"]
RUN echo hello

当在 Dockerfile 中使用它们的 shell 格式时,以下指令可能会受到 SHELL 指令的影响:RUNCMD 和 ENTRYPOINT

CMD和ENTRYPOINT的区别

区别:

  • CMD #指定这个容器启动的时候要运行的命令,可被替换
  • ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
    这俩命令非常像,而且还可以配合使用。
  • 相同点:
    • 只能写一条,如果写了多条,那么只有最后一条生效。
    • 容器启动时才运行,运行时机相同。
  • 不同点:
    • ENTRYPOINT 不会被运行的 command 覆盖,而 CMD 则会被覆盖。
    • 如果我们在 Dockerfile 中同时写了 ENTRYPOINT 和 CMD,并且 CMD 指令不是一个完整的可执行命令,那么 CMD 指定的内容将会作为 ENTRYPOINT 的参数。如下所示:
      FROM ubuntu 
      ENTRYPOINT ["rm", "docker2"] 
      CMD ["-rf"]
      
      它真正执行的命令将会是:rm docker2 -rf
    • 如果我们在 Dockerfile 种同时写了 ENTRYPOINT 和 CMD,并且 CMD 是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效。如下所示
      FROM ubuntu
      ENTRYPOINT ["top", "-b"]  
      CMD ls -al
      
      那么将执行ls -al,top -b不会执行。

例子
Dockerfile文件

#基础镜像
from centos
#启动容器运行命令
CMD ["ls" ,"-a"]

构建镜像

docker build -t test04:v1 .

Dockerfile综合实验

构建 Tomcat 镜像

[Pasted image 20240731142544.png]
首先,尝试在 DockerHub 上搜索 Tomcat 相关镜像的个数

docker search tomcat |wc -l

构建步骤

  1. 编写一个 dockerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像

Dockerfile文件

#基础镜像
FROM  openjdk:11
#维护者
MAINTAINER TMesh_<TMesh_@163.com>
#拷贝tomcat包
ADD  ./apache-tomcat-9.0.50.tar.gz /usr/local
#设置工作目录
WORKDIR /usr/local
#设置tomcat环境变量
ENV TOMCAT_HOME=/usr/local/apache-tomcat-9.0.50
ENV PATH=$PATH:$TOMCAT_HOME/bin
#保留端口
EXPOSE 8080
#启动容器运行命令
CMD startup.sh && tail -F /usr/local/apache-tomcat-9.0.50/bin/catalina.bat

练习:构建一个 tomcat,编写首页

使用空镜像从零构建一个完整的 tomcat
一般一个项目都在一个文件夹中,我们只需要在项目目录下编辑一个 Dockerfile 文件即可
当执行docker bulid指定时如果没有-f参数指定 dockerfile 文件,会默认寻找项目目录下的 Dockerfile 来构建镜像,所以我们名字通常设定为Dockerfile
准备工作:准备 tomcat 和 jdk 的 jar 包,创建Dockerfile文件,以及一个任意内容的readme.md即可
[Pasted image 20240731154106.png]
编辑Dockerfile,内容如下:

FROM centos:7.9.2009
MAINTAINER akuya<123456@qq.com># 宿主机目录下文件拷贝到容器内,文件如果不是绝对路径会默认寻找 dockerfile 文件的同级目录下,所以最好所有文件都在同一个目录下
COPY readme.md /usr/local/readme.md# 添加我们自己的安装包
ADD jdk-8u11-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.22.tar.gz /usr/local#安装vim编辑器
RUN yum -y install vim# 配置工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH# 配置环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin# 暴露端口
EXPOSE 8080# 启动的时候自动运行tomcat,打印日志
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out

构建并运行:

# 构建,不指定 dockerfile 文件会自动寻找该目录下的 Dockerfile
docker build -t mytomcat .
# 运行
docker run -d -p 8080:8080 --name mytomcat \
-v /root/mytomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test \
-v /root/mytomcat/logs:/usr/local/apache-tomcat-9.0.22/logs \
--privileged=true \
mytomcat

运行成功后打开浏览器,输入ip地址:8080,即可访问到 tomcat 主页

在我们自定义的 tomcat 服务器中上传一个项目,在本地挂载目录,丢一个项目上去。
首先进入到我们挂载的宿主机目录下/root/mytomcat

cd /root/mytomcat/
lltotal 8
drwxr-xr-x 2 root root 4096 Mar 21 14:45 logs
drwxr-xr-x 2 root root 4096 Mar 21 14:45 test

在 test 目录下丢项目即可
示例:编写一个index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>docker test</title>
</head>
<body><h1>----------hello TMesh----------------</h1><br><h2>my docker tomcattest</h2>
</body>
<script>console.log("my docker tomcat log")
</script>
</html>

浏览器访问ip地址:8080/test/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/870846.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图标获取、页面设计

当大家在写安卓端及小程序时,是不是在为导航栏的小图标而发愁这里推荐一个网页--即时设计 页面中有很多开源的图标,以及根据选定状态不同的两种形态 选定你所需要的图标,再右下方可以找到图片的导出,大多数情况选择.png格式导出,再移动到自己的项目中,就可以使用啦 图标大…

SendMail Python版

tkinter制作的Python界面 使用前需要设置config.ini的发件人账户 点击 发送之后,对方收到邮件

NOIP邮寄

Day -1 下午出发,一路观察@Acoipp 。图片待会发出来。真服了,如有侵权请私信我。 最左边是基科班学长,左二是lzm (sage NOIP 260+ CSPS 300+ 什么实力不用多说),右二是Acoipp,最右边也是基科班学长。 笑点解析:Acoipp:“我真的想骂人了。”点名表扬BZ电脑,感觉良好!…

Docker Compose 笔记

目录Docker-Compose 简介Docker Compose 的定义和目的Docker-Compose 用来实现 Docker 容器快速编排Docker-Compose 模板文件简介eg:Docker-Compose 的编排处出来的部署架构Docker-Compose 的编排结构安装 Docker-Compose验证Docker-compose是否安装成功卸载docker compose:D…

Regexp for Python

使用PyInstaller打包的Python正则表达式

Ubuntu20.04取消root账号自动登录方法触觉智能RK3568开发板演示

Ubuntu20.04默认情况下为root账号自动登录,本文介绍如何取消root账号自动登录,改为通过输入账号密码登录,使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持OpenHarmony5.0及Linux、Android等操作系统,接口丰富,开发评估…

库卡机器人示教器维修的参考措施

开课啦!!!“工业机器人维修”之“库卡机器人示教器维修”先来看看这个库卡机器人示教器:1. KUKA 控制屏 (简称“KCP”)是人机交流的接口,它用于简化机器人“KRC”控制部分的操作。所有用于机器人系统编程和操作的部分(除了总开关以外)皆直接布置在 KCP 上。1. KCP 的握把凸…

【UWP】让 UWP 自己托管自己 —— Windows SDK 篇

众所周知,UWP 使用的窗口模型是 CoreWindow,但是 UWP 本身只是一个应用模型,所以完全可以创建 win32 窗口,那么我们可以不可以创建一个 win32 窗口,然后像 XAML 岛 (XAML Islands) 一样把 XAML 托管上去呢?本篇将讲述如何在 UWP 创建一个 XAML 岛窗口。众所周知,UWP 使用…

5 分钟复刻你的声音,一键实现 GPT-Sovits 模型部署

本文将详细介绍如何利用函数计算平台部署 GPT-Sovits 模型,以构建一个高效、可扩展的 AI 语音交互系统。通过这一部署方案,开发者和企业能够快速集成语音合成功能,实现从文本到语音的无缝转换,进而推动智能语音应用的创新和发展。想象一下,只需简单几步操作,就能生成逼真…

sam模型迁移昇腾训练loss不收敛问题的解决办法

一、问题描述:在进行sam模型迁移到昇腾的时候存在精度问题,模型链接: https://github.com/facebookresearch/segment-anything 两台机器上训练loss图对比,发现从一开始训练的时候就出现了差别,从图中对比看出来npu第一步 就开始没有向下收敛,而gpu是向下收敛。二、问题分…

Ansible - 自动化利器

Ansible 概念介绍 Ansible是自由开源的配置和自动化工具。官方网站 https://www.ansible.com/ 官方文档 https://docs.ansible.com/ansible/latest/ 安装包 https://releases.ansible.com/主要特点 - 无客户端模式(agentless),无侵入性,只需在主控端部署Ansible环境,被控端…