DOCKERFILE参数注解

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

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

Dockerfile的指令是忽略大小写的,建议使用大写,使用 # 作为注释,每一行只支持一条指令,每条指令可以携带多个参数。

Dockerfile的指令根据作用可以分为两种:构建指令和设置指令。

  构建指令用于构建image,其指定的操作不会在运行image的容器上执行;
  设置指令用于设置image的属性,其指定的操作将在运行image的容器中执行。

可以在目录下创建.dockerignore文件,让Docker忽略路径下的文件和目录。

DockerFile的每一个指令都会新构建一层。

UnionFS是有最大层数限制的,比如AUFS,曾经是最大不能超过42层,现在是最大不能超过127层。所以,对于一些编译、软件的安装、更新等操作,无需分成好几层来操作,这样会使得镜像非常臃肿,拥有非常多的层,不仅仅增加了构建部署的时间,也很容易出错!!

指令描述格式
from

构建指令。

指定基础镜像,它是最重要的一个且必须为dokefile文件开篇的第一个非注释行,用于为镜像文件构建过程中指定基础镜像,后续的指令运行于此基准镜像所提供的运行环境

默认,docke会在本机寻找指定的镜像,找不到的时候则从docke hub registery拉取所需镜像,如果会找不到,则报错返回报错信息

如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM 指令。

DockerFile还存在一个特殊的镜像srcatch,这个镜像是一个虚拟的概念,并不实际存在,它表示一个空白的镜像。

如果你以scratch作为基础镜像,意味着你将不使用任何镜像为基础,接下来你所写的指令将作为第一层开始存在。不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见。如swarmcoreos/etcd。对Linux下静态编译的程序来说,并不需要其他操作提供其运行时支持,所需的一切库都在可执行文件里了,因此使用scratch作为基础,可以使镜像的体积更加小巧

from  <repository>[:<tag>]或者

from <repository>@<digest>

repository为基础镜像名称   tag为镜像标签为可选项,省略时为latest该image的最后修改的版本

MAINTAINER

构建指令

用于为docke提供作者信息,无顺序限制

用于将image的制作者相关的信息写入到image中。当我们对该image执行docker inspect命令时,输出中有相应的字段记录该信息。

此命令已经过时,可以使用LABEL maintainer=xxx 来替代,定义多个LABEL时,可以使用 【\】反划线来跨行

copy

用于从docker主机复制文件至创建的新镜像文件,但不会自动解压,不能从【 远端URL 】 复制。

目标路径是容器内的绝对路径,也可以是工作目录下的相对路径,工作目录可以使用WORKDIR指令进行指定。

使用COPY指令会将源路径的文件的所有元数据都拷贝,比如读、写、指定全选、时间变更等。

<源路径> 可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的 filepath.Match 规则

目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录

在使用该指令的时候还可以加上 --chown=<user>:<group> 选项来改变文件的所属用户及所属组。

文件复制准则:

1 COPY [--chown=<user>:<group>] <源路径>... <目标路径>
2 COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
add

构建指令

ADD指令和COPY的格式和性质基本一致,只不过是在COPY的基础上增加了一些功能。

如果是一个目录,那么会将该目录下的所有文件添加到container中,不包括目录;

如果<src>是文件且<dest>中不使用斜杠结束,则会将<dest>视为文件,<src>的内容会写入<dest>;

如果<src>是文件且<dest>中使用斜杠结束,则会<src>文件拷贝到<dest>目录下。

目标路径为一个URL时,会将其自动下载到目标路径下,但是其权限被自动设置成了600,如果这并不是你想要的权限,那么你还需要额外增加一层RUN命令进行更改,另外,如果下载的是一个压缩包,同样你还需要额外增加一层RUN命令进行解压缩。所以,在这种情况下,你还不如指定只用一层RUN,使用curl或者wget工具进行下载,并更改权限,然后进行解压缩,最后清理无用文件!

当你的源路径为压缩文件并且不想让Docker引擎将其自动解压缩,这个时候就不可以使用ADD命令,你可以使用COPY命令进行完成

run

构建指令。

每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行

RUN可以运行任何被基础image支持的命令。如基础image选择了ubuntu,那么软件管理部分只能使用ubuntu的命令

shell格式RUN <command> 或

exec格式RUN ["executable", "param1", "param2"]

前者将在 shell 终端中运行命令,即 /bin/sh -c;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]

volume

设置指令

用于构建镜像时定义匿名卷。

容器存储层应该保持无状态化,容器运行时应尽量保持容器内不发生任何写入操作,对于需要保存动态数据的应用,其数据文件应该将其保存在数据卷中。

容器匿名卷目录指定可以通过docker run命令中指定-v参数来进行覆盖。

如果挂载点目录下此前存在文件,docker run命令会在卷挂载完成之后将此前的所有文件复制到新挂载的卷中

运行通过该Dockerfile生成image的容器,/tmp/data目录中的数据在容器关闭后,里面的数据还存在。

例如另一个容器也有持久化数据的需求,且想使用上面容器共享的/tmp/data目录,那么可以运行下面的命令启动一个容器:

docker run -t -i -rm -volumes-from container1 image2bash

其中:container1为第一个容器的ID,image2为第二个容器运行image的名字。

  • VOLUME <路径>
  • VOLUME [“<路径1>”, “<路径2>”, …]
expose

设置指令

EXPOSE指令是声明运行时容器服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。

在Dockerfile中这样声明有两个好处:一个是帮助镜像使用者更好的理解这个镜像服务的守护端口,另一个作用则是在运行时使用随机端口映射时,也就是docker run -p命令时,会自动随机映射EXPOSE端口。

要将EXPOSE和在运行时使用-p <宿主>:<容器端口>区分开来,-p是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而EXPOSE仅仅是声明端口使用什么端口而已,并不会自动在宿主进行端口映射

EXPOSE指令可以一次设置多个端口号,相应的运行容器的时候,可以配套的多次使用-p选项。

EXPOSE 端口号

EXPOSE 端口号/协议

默认协议为TCP

env

设置指令

指定环境变量,它可以被其后的add、copy等调用

可以通过docker inspect查看这个环境变量,也可以通过在docker run --env key=value时设置或修改环境变量

如果你要设置多个环境变量,为了美观,你可以使用\来进行换行。多个环境变量的隔开,使用空格进行隔开的,如果某个环境变量的值是由一组英文单词构成,那么你可以将其使用""进行圈起来

值得注意的是,如果你想通过CMD或者ENTRYPOINT指令的exec格式来打印环境

CMD ["echo", $MODE]

CMD ["echo", "$MODE"]

上面这样都是不能正确输出环境变量的值的,你可以改成exec格式来执行shell命令,如下

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

调用格式$name或者${name}

wokrdir

设置指令

使用WORKDIR指令来制定工作目录(或者称为当前目录),以后各层操作的当前目录就是为指定的目录,如果该目录不存在,WORKDIR会自动帮你创建目录

WORKDIR指令可以通过docker run命令中的-w参数来进行覆盖

user

设置指令

指令用于将会用以什么样的用户去运行默认为root

可以指定用户名或者UID,组名或者GID,或者两者的结合

USER指令可以在docker run命令中的-u参数进行覆盖

后续的 RUN 也会使用指定用户。

当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用 gosu,而不推荐 sudo

healthcheck

告诉Docker该如何判断容器的状态是否正常,这是1.12引入的新指令

在没有HEALTHCHECK指令之前,Docker引擎只可以通过容器内主进程是否退出来判断容器状态是否异常。很多情况下这没有问题,但是如果程序进入了死锁状态,或者死循环状态,应用进程并不退出,但是该容器已经无法继续提供服务了。在1.12之前,Docker引擎不会检测到容器的这种状态,从而不会重新调度,导致可能容器已经无法提供服务了却仍然还在接收用户的请求。

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

HEALTHCHECK [options] CMD <命令>:检查容器健康状态的命令

HEALTHCHECK NONE:如果基础镜像有健康检查指令,这一行将会屏蔽掉其健康检查指令

HEALTHECHECK支持下列选项:

     –interval=<间隔>:两次检查的时间间隔,默认为30s

     –timeout=<时长>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查将会判定                                        为失败,默认为30s

      –retries=<次数>:当连续失败指定次数之后,则将容器状态视为unhealthy,默认为3次

onbuildONBUILD是一个特殊的指令,它后面跟着的是其他指令,比如COPYRUN等,而这些命令在当前镜像被构建时,并不会被执行。只有以当前镜像为基础镜像去构建下一级镜像时,才会被执行ONBUILD <其他指令>
shell

指定Dockerfile中 【 shell form 】命令的默认shell。

Linux中默认shell为 【 “/bin/sh”, “-c”】

arg

构建参数ARGENV指令一样,都是设置环境变量。与之不同的是,ARG设置的环境变量只是在镜像构建时所设置的,在将来容器运行时是不会存在这些环境变量的。但是不要因此就用ARG来保存密码之类的信息,因为通过docker history还是能够看得到的。ARG指令与ENV指令的使用类似

ARG构建参数可以通过docker run命令中的--build-arg参数来进行覆盖

cmd

设置指令。

Docker不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,就需要指定运行的程序及参数。CMD就是指定默认的容器主进程的启动命令的

每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令

这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。

原因是参数传递后,docker解析的是一个JSON array

一些命令在加上sh -c之后,有可能会发生意想不到的错误,因此在Dockerfile中使用RUN指令时,更加推荐使用exec格式!最后需要牢记,使用docker run命令指定要执行的命令可以覆盖RUN指令,如果我们的docker run中指定了我们将要执行的命令,并且在Dockerfile中也指定了CMD命令

exec格式CMD ["executable","param1","param2"] 

使用 exec 执行,推荐方式;

shell格式CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用。

CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数,如果CMD指令使用上面的形式,那么Dockerfile中必须要有配套的ENTRYPOINT

entrypoint

设置指令

指定容器运行程序及参数

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效

ENTRYPOINT也更加推荐使用exec格式,ENTRYPOINTdocker run命令中同样也可以进行指定,只不过比CMD指令来的繁琐一些,需要指定--entrypoint参数。同样,在docker run命令中指定了--entrypoint参数的话,会覆盖Dockerfile中ENTRYPOINT上的指令。

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

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

CMDecho “Hello, World!” 

ENTRYPOINT ls -l 

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

ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。

CMD ["-l"

ENTRYPOINT ["/usr/bin/ls"

exec格式ENTRYPOINT ["executable", "param1", "param2"]

shell格式ENTRYPOINT command param1 param2(shell中执行)

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

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

相关文章

Zookeeper:分布式过程协同技术

Zookeeper 是一个高性能的分布式一致系统&#xff0c;在分布式系统中有着广泛的应用。基于它&#xff0c;可以实现诸如“分布式同步”、“配置管理”、“命名空间管理”等众多功能&#xff0c;是分布式系统中常见的基础系统。Zookeeper 主要用来解决分布式集群中应用系统的一致…

Linux namespace概述

操作系统通过虚拟内存技术&#xff0c;使得每个用户进程都认为自己拥有所有的物理内存&#xff0c;这是操作系统对内存的虚拟化。操作系统通过分时调度系统&#xff0c;每个进程都能被【公平地】调度执行&#xff0c;即每个进程都能获取到CPU&#xff0c;使得每个进程都认为自己…

Zookeeper:Zookeeper的主从选举机制

ZAB 协议&#xff0c;全称 Zookeeper Atomic Broadcast&#xff08;Zookeeper 原子广播协议&#xff09;&#xff0c;是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的一致性协议。基于该协议&#xff0c;ZooKeeper 实现了一种主从模式的系统架构来保持集群中各个副…

Linux namespace之:uts namespace

理解uts namespace uts(UNIX Time-Sharing System) namespace可隔离hostname和NIS Domain name资源&#xff0c;使得一个宿主机可拥有多个主机名或Domain Name。换句话说&#xff0c;可让不同namespace中的进程看到不同的主机名。 例如&#xff0c;使用unshare命令(较新版本L…

Kubernetes 的原理

kubernetes 已经成为容器编排领域的王者&#xff0c;它是基于容器的集群编排引擎&#xff0c;具备扩展集群、滚动升级回滚、弹性伸缩、自动治愈、服务发现等多种特性能力。 本文将带着大家快速了解 kubernetes &#xff0c;了解我们谈论 kubernetes 都是在谈论什么。 kuberne…

CPU 是如何执行任务的

前言 你清楚下面这几个问题吗&#xff1f; 有了内存&#xff0c;为什么还需要 CPU Cache&#xff1f; CPU 是怎么读写数据的&#xff1f; 如何让 CPU 能读取数据更快一些&#xff1f; CPU 伪共享是如何发生的&#xff1f;又该如何避免&#xff1f; CPU 是如何调度任务的&a…

Ansible 的自动化运维

1、Ansible 特点 Ansible 自 2012 年发布以来&#xff0c;很快在全球流行&#xff0c;其特点如下&#xff1a; Ansible 基于 Python 开发&#xff0c;运维工程师对其二次开发相对比较容易&#xff1b; Ansible 丰富的内置模块&#xff0c;几乎可以满足一切要求&#xff1b; …

图文并茂 VLAN 详解,让你看一遍就理解 VLAN

一、为什么需要VLAN 1.1、什么是VLAN? VLAN(Virtual LAN)&#xff0c;翻译成中文是“虚拟局域网”。LAN可以是由少数几台家用计算机构成的网络&#xff0c;也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络——也就是广播域。 在此让我们先复习…

认识VLAN,并学会VLAN的划分和网络配置实例

VLAN的划分和网络的配置实例 1、VLAN基础知识 VLAN&#xff08;Virtual Local Area Network&#xff09;的中文名为&#xff1a;“虚拟局域网”&#xff0c;注意和VPN&#xff08;虚拟专用网&#xff09;进行区分。 VLAN是一种将局域网设备从逻辑上划分&#xff08;不是从物…

VLAN划分及配置注意事项

VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。VLAN内的主机间可以直接通信&#xff0c;而VLAN间不能直接通信&#xff0c;从而将广播报文限制在一个VLAN内。VLAN之间的通信是通过第3…

Docker原理剖析

一、简介 1、了解Docker的前生LXC LXC为Linux Container的简写。可以提供轻量级的虚拟化&#xff0c;以便隔离进程和资源&#xff0c;而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中&#…

Docker容器网络解析

Docker 容器网络的发展历史 在 Dokcer 发布之初&#xff0c;Docker 是将网络、管理、安全等集成在一起的&#xff0c;其中网络模块可以为容器提供桥接网络、主机网络等简单的网络功能。 从 1.7 版本开始&#xff0c;Docker正是把网络和存储这两部分的功能都以插件化形式剥离出来…

Docker 数据管理介绍

默认容器的数据是保存在容器的可读写层&#xff0c;当容器被删除时其上的数据也会丢失&#xff0c;所以为了实现数据的持久性则需要选择一种数据持久技术来保存数据。官方提供了三种存储方式&#xff1a;Volumes、Bind mounts和tmpfs。前面还介绍了&#xff1a;Docker 服务终端…

Docker 数据持久化的三种方案

容器中的数据可以存储在容器层。但是将数据存放在容器层存在以下问题&#xff1a; 数据不是持久化。意思是如果容器删除了&#xff0c;这些数据也就没了 主机上的其它进程不方便访问这些数据 对这些数据的I/O会经过存储驱动&#xff0c;然后到达主机&#xff0c;引入了一层间…

Git 存储原理及相关实现

Git 是目前最流行的版本控制系统&#xff0c;从本地开发到生产部署&#xff0c;我们每天都在使用 Git 进行我们的版本控制&#xff0c;除了日常使用的命令之外&#xff0c;如果想要对 Git 有更深一步的了解&#xff0c;那么研究下 Git 的底层存储原理将会对理解 Git 及其使用非…

Git内部原理

Git有什么特点&#xff1f; fast&#xff0c;scalable&#xff0c;distributed revision control system&#xff08;快速&#xff0c;可扩展的分布式版本控制系统&#xff09; 几乎所有操作都是本地执行 每一个clone都是整个生命周期的完整副本 the stupid content tracker&a…

详解设计模式:中介者模式

中介者模式&#xff08;Mediator Pattern&#xff09;也被称为调停者模式&#xff0c;是在 GoF 23 种设计模式中定义了的行为型模式。 中介者模式 是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类&#xff0c;该类通常处理不同类之间的通信&#xff0c;并支…

RPC 服务 与 HTTP 服务的区别

1、什么是RPC RPC&#xff08;Remote Procedure Call&#xff09;—远程过程调用&#xff0c;它是一种通过网络从远程计算机程序上请求服务&#xff0c;而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在&#xff0c;如TCP或UDP&#xff0c;为通信程序之间携带信…

缓存雪崩、击穿、穿透解决方案

用户的数据一般都是存储于数据库&#xff0c;数据库的数据是落在磁盘上的&#xff0c;磁盘的读写速度可以说是计算机里最慢的硬件了。 当用户的请求&#xff0c;都访问数据库的话&#xff0c;请求数量一上来&#xff0c;数据库很容易就奔溃的了&#xff0c;所以为了避免用户直…

【Docker】容器镜像有哪些特性

首先解释一下什么是Docker镜像&#xff1f; Docker镜像它其实是一个模板&#xff0c;拥有这个模板我们才能创建我们的Docker容器&#xff0c;镜像里含有启动 docker 容器所需的文件系统结构及其内容&#xff0c;因此是启动一个 docker 容器的基础。docker 镜像的文件内容以及一…