百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

Docker-dockerfile指令介绍

wptr33 2025-01-09 16:34 12 浏览

简介:Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像的定制实际上就是定制每一层所添加的配置、文件。如果可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了 Dockerfile,当需要定制自己额外的需求时,只需在 Dockerfile 上添加或者修改指令,重新生成 image 即可,省去了敲命令的麻烦。

本文将介绍Dockerfile指令及其使用方法,详细情况请参考下文。

一、Dockerfile文件格式

说明:Dockerfile分为四部分,基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令。一开始必须要指明所基于的镜像名称,接下来一般会说明维护者信息;后面则是镜像操作指令,例如 RUN 指令。每执行一条RUN 指令,镜像添加新的一层,并提交;最后是 CMD 指令,来指明运行容器时的操作命令。比如:

二、Dockerfile 指令详解

1、FROM:指定基础镜像,必须为dockerfile中的第一个命令

格式:

  FROM <image>

  FROM <image>:<tag>

  FROM <image>@<digest>

示例:

  FROM mysql:5.6

注:

tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像

2、MAINTAINER: 维护者信息

格式:

MAINTAINER <name>

示例:

MAINTAINER JasonTang

MAINTAINER jasontang@163.com

MAINTAINER jasontang <jasontang@163.com>

3、LABEL:用于为镜像添加元数据

格式:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例:

  LABEL version="1.0" description="这是一项软件项目测试工程"

注:

使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。

4、RUN:构建镜像时执行的命令,一个文件中可以包含多个RUN命令

RUN用于在镜像容器中执行命令,有以下两种命令执行方式:

①shell执行,即/bin/sh

格式:

RUN <command>

②exec执行

格式:

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

要注意的是,executable是命令,后面的param是参数

示例: RUN yum install -y nginx

RUN ["yum", "install", "-y", "nginx"]

注意:

RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache。

另外:由于RUN命令会生成一个镜像层,所以RUN并不是越多越好,需要合理使用,如果一个RUN中执行多个命令,可以使用 && 连接,如果命令过长,可以使用 \ 换行,例如:

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

bzr \

cvs \

git \

mercurial \

subversion

并且这样写还有个优点,apt-get update 和 apt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。

5、CMD:构建容器后调用,也就是在容器启动时才进行调用,存在多个CMD时只有最后一个生效,也支持exec语法。

格式:

CMD ["executable","param1","param2"] (执行可执行文件,优先)

CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)

CMD command param1 param2 (执行shell内部命令)

示例:

CMD echo "This is a test." | wc -

CMD ["/usr/bin/wc","--help"]

注意:

CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

6、ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数。

格式:

ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)

ENTRYPOINT command param1 param2 (shell内部命令)

示例:

FROM ubuntu

ENTRYPOINT ["top", "-b"]

CMD ["-c"]

注意:

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

另外:需要注意CMD和ENTRYPOINT的区别

CMD和ENTRYPOINT同样作为容器启动时执行的命令,区别有以下几点:

CMD的命令会被 docker run 的命令覆盖而ENTRYPOINT不会;如使用CMD ["/bin/bash"]或ENTRYPOINT ["/bin/bash"]后,再使用docker run -ti image启动容器,它会自动进入容器内部的交互终端,如同使用docker run -ti image /bin/bash。

但是如果启动镜像的命令为docker run -ti image /bin/ps,使用CMD后面的命令就会被覆盖转而执行bin/ps命令,而ENTRYPOINT的则不会,而是会把docker run 后面的命令当做ENTRYPOINT执行命令的参数。

7、EXPOSE:指定暴露镜像的端口供主机做映射

格式:

EXPOSE <port> [<port>...]

示例:

EXPOSE 80 443

EXPOSE 8080

EXPOSE 11211/tcp 11211/udp

注意:

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

8、ENV:设置环境变量

格式:

ENV <key> <value> #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量

ENV <key>=<value> ... #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行

示例:

ENV JAVA_HOME=/usr/jdk

ENV JRE_HOME=$JAVA_HOME/jre

9、ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget。如果目的位置不存在,Docker会自动创建所需要的目录。

格式:

ADD <src>... <dest>

ADD ["<src>",... "<dest>"] 用于支持包含空格的路径

示例:

ADD hom* /mydir/ # 添加所有以"hom"开头的文件

ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"

ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/

ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/

注意:

需要复制的本地文件一定要放在Dockerfile文件的同级目录下

原因:

因为构建环境将会先上传到Docker守护进程,而复制是在Docker守护进程中进行的。任何位于构建环境之外的东西都是不可用的。ADD指令的目的的位置则必须是容器内部的一个绝对路径。

10、COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源。就是不能解压,也不能访问网络资源,其他限制条件跟ADD一样。

格式:

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

COPY ["<源路径1>",... "<目标路径>"]

比如:COPY package.json /usr/src/app/

11、VOLUME:添加卷,用于指定持久化目录

格式:

VOLUME ["/path/to/dir"]

示例:

VOLUME ["/data"]

VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]

注:

  一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

1.卷可以容器间共享和重用;

2.容器并不一定要和其它容器共享卷;

3.修改卷后会立即生效;

4.对卷的修改不会对镜像产生影响;

5.卷会一直存在,直到没有任何容器在使用它。

12、WORKDIR:指定工作目录,类似于cd命令,之后的命令都是基于此工作目录

格式:

WORKDIR /path/to/workdir

示例:

WORKDIR /a (这时工作目录为/a)

WORKDIR b (这时工作目录为/a/b)

WORKDIR c (这时工作目录为/a/b/c)

注意:

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

13、USER:指定运行容器时的用户名或 UID,后续的操作都会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户。

格式:

  USER user

  USER user:group

  USER uid

  USER uid:gid

  USER user:gid

  USER uid:group

示例:

  USER www

注意:

使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

14、ARG:用于指定传递给构建运行时的变量

格式:

ARG <name>[=<default value>]

示例:

ARG site

ARG build_user=www

15、ONBUILD:用于设置镜像触发器

格式:

  ONBUILD [INSTRUCTION]

示例:

  ONBUILD ADD . /app/src

  ONBUILD RUN /usr/local/bin/python-build --dir /app/src

注意:

  当所构建的镜像被用做其它镜像的基础镜像时(比如用户的镜像需要从某为准备好的位置添加源代码,或者用户需要执行特定于构建镜像的环境的构建脚本),该镜像中的触发器将会被钥触发。

例如创建镜像image-A FROM ubuntu ... ONBUILD ADD . /var/www ...

然后创建镜像image-B,指定image-A为基础镜像,如 FROM image-A ...

然后在构建image-B的时候,日志上显示如下: Step 0 : FROM image-A # Execting 1 build triggers Step onbuild-0 : ADD . /var/www ...

16、STOPSIGNAL:用于设置停止容器所要发送的系统调用信号

格式:

STOPSIGNAL signal

注意:所使用的信号必须是内核系统调用表中的合法的值,如:SIGKILL。

17、HEALTHCHECK:用于指定某个程序或者指令来监控 docker 容器服务的运行状

格式:

HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令;

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

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

18、SHELL:用于设置执行命令(shell式)所使用的的默认 shell 类型

格式:

SHELL ["executable", "parameters"]

三、Dockerfile应用实例

1、通过Dockerfile创建Nginx服务器

2、通过Dockerfile创建Tomcat服务器

相关推荐

【推荐】一款开源免费、美观实用的后台管理系统模版

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍...

Android架构组件-App架构指南,你还不收藏嘛

本指南适用于那些已经拥有开发Android应用基础知识的开发人员,现在想了解能够开发出更加健壮、优质的应用程序架构。首先需要说明的是:AndroidArchitectureComponents翻...

高德地图经纬度坐标批量拾取(高德地图批量查询经纬度)

使用方法在桌面上新建一个index.txt文件,把下面的代码复制进去保存,再把文件名改成index.html保存,双击运行打开即可...

flutter系列之:UI layout简介(flutter ui设计)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。...

Android开发基础入门(一):UI与基础控件

Android基础入门前言:...

iOS的布局体系-流式布局MyFlowLayout

iOS布局体系的概览在我的CSDN博客中的几篇文章分别介绍MyLayout布局体系中的视图从一个方向依次排列的线性布局(MyLinearLayout)、视图层叠且停靠于父布局视图某个位置的框架布局(M...

TDesign企业级开源设计系统越发成熟稳定,支持 Vue3 / 小程序

TDesing发展越来越好了,出了好几套组件库,很成熟稳定了,新项目完全可以考虑使用。...

WinForm实现窗体自适应缩放(winform窗口缩放)

众所周知,...

winform项目——仿QQ即时通讯程序03:搭建登录界面

上两篇文章已经对CIM仿QQ即时通讯项目进行了需求分析和数据库设计。winform项目——仿QQ即时通讯程序01:原理及项目分析...

App自动化测试|原生app元素定位方法

元素定位方法介绍及应用Appium方法定位原生app元素...

61.C# TableLayoutPanel控件(c# tabcontrol)

摘要TableLayoutPanel在网格中排列内容,提供类似于HTML元素的功能。TableLayoutPanel控件允许你将控件放在网格布局中,而无需精确指定每个控件的位置。其单元格...

想要深入学习Android性能优化?看完这篇直接让你一步到位

...

12个python数据处理常用内置函数(python 的内置函数)

在python数据分析中,经常需要对字符串进行各种处理,例如拼接字符串、检索字符串等。下面我将对python中常用的内置字符串操作函数进行介绍。1.计算字符串的长度-len()函数str1='我爱py...

如何用Python程序将几十个PDF文件合并成一个PDF?其实只要这四步

假定你有一个很无聊的任务,需要将几十个PDF文件合并成一个PDF文件。每一个文件都有一个封面作为第一页,但你不希望合并后的文件中重复出现这些封面。即使有许多免费的程序可以合并PDF,很多也只是简单的将...

Python入门知识点总结,Python三大数据类型、数据结构、控制流

Python基础的重要性不言而喻,是每一个入门Python学习者所必备的知识点,作为Python入门,这部分知识点显得很庞杂,内容分支很多,大部分同学在刚刚学习时一头雾水。...