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

Dockerfile详解 dockerfile示例

wptr33 2024-11-13 15:04 39 浏览

一、关于Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

一个完整的Docker有以下几个部分组成:

DockerClient客户端

Docker Daemon守护进程

Docker Image镜像

DockerContainer容器

1、Docker为什么比虚拟机快

Docker有着比虚拟机更少的抽象层,由于Docker不需要Hypervisor实现硬件资源虚拟化,运行在Docker容器上的程序直接使用的都是实际物理机的硬件资源,因此在Cpu、内存利用率上Docker将会在效率上有明显优势。

Docker利用的是宿主机的内核,而不需要Guest OS,因此,当新建一个容器时,Docker不需要和虚拟机一样重新加载一个操作系统,避免了引导、加载操作系统内核这个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,这个新建过程是分钟级别的,而Docker由于直接利用宿主机的操作系统则省略了这个过程,因此新建一个Docker容器只需要几秒钟。

2、镜像命令

docker images #查看所有本地主机上的镜像 可以使用docker image ls代替。

docker images -aq #显示所有镜像id

docker search 镜像名称 #搜索镜像

docker pull 镜像名称 #下载镜像

docker rmi -f 镜像id #删除单个镜像

docker rmi -f 镜像id 镜像id 镜像id #删除多个镜像

3、容器命令

docker run 镜像id #新建容器并启动

docker ps #列出所有运行的容器

docker rm 容器id #删除指定容器

docker start 容器id #启动容器

docker restart 容器id #重启容器

docker stop 容器id #停止当前正在运行的容器

docker kill 容器id #强制停止当前容器

二、关于Dockerfile

在Docker中创建镜像最常用的方式,就是使用Dockerfile。Dockerfile是一个Docker镜像的描述文件,我们可以理解成火箭发射的A、B、C、D…的步骤。Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

一个Dockerfile的示例如下所示:

#基于centos镜像

FROM centos

#维护人的信息

MAINTAINER The CentOS Project <303323496@qq.com>

#安装httpd软件包

RUN yum -y update

RUN yum -y install httpd

#开启80端口

EXPOSE 80

#复制网站首页文件至镜像中web站点下

ADD index.html /var/www/html/index.html

#复制该脚本至镜像中,并修改其权限

ADD run.sh /run.sh

RUN chmod 775 /run.sh

#当启动容器时执行的脚本文件

CMD ["/run.sh"]

由上可知,Dockerfile结构大致分为四个部分:

(1)基础镜像信息

(2)维护者信息

(3)镜像操作指令

(4)容器启动时执行指令。

Dockerfile每行支持一条指令,每条指令可带多个参数,支持使用以#号开头的注释。下面会对上面使用到的一些常用指令做一些介绍。

三、Dockerfile常用指令

首先,来一张通俗易懂的全景图:

2.1 FROM

定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。

格式:

  FROM <image>

  FROM <image>:<tag>

  FROM <image>@<digest>
示例:
  FROM mysql:5.6
注:
  tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像

2.2 MAINTAINER

维护者信息,例如:

格式:

MAINTAINER <name>

示例:

MAINTAINER Jasper Xu

MAINTAINER sorex@163.com

MAINTAINER Jasper Xu <sorex@163.com>

2.3 RUN

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

RUN <command>

exec执行格式:

RUN ["executable", "param1", "param2"]示例:

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

RUN apk update

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

2.4 CMD

启动容器时执行的Shell命令,例如:

格式:

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用于指定镜像构建时所要执行的命令。

2.5 EXPOSE

声明容器运行的服务端口,例如:

格式:

EXPOSE <port> [<port>...]示例:

EXPOSE 80 443

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

2.6 ENV

设置环境内环境变量,例如:

格式:

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

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

ENV myName John Doe

ENV myDog Rex The Dog

ENV myCat=fluffy

2.7 ADD

拷贝文件或目录到镜像中,例如:

格式:

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/

2.8 COPY

拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压,例如:

COPY ./start.sh /start.sh

2.9 ENTRYPOINT

启动容器时执行的Shell命令,同CMD类似,只是由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序,例如:

格式:

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指令。

2.10 VOLUME

指定容器挂载点到宿主机自动生成的目录或其他容器,例如:

格式:

VOLUME ["/path/to/dir"]

示例:

VOLUME ["/data"]

VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:
  一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

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

2.11 USER

为RUN、CMD和ENTRYPOINT执行Shell命令指定运行用户,例如:

格式:
  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参数来覆盖所指定的用户。

2.12 WORKDIR

  为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录,例如:

格式:

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参数覆盖构建时所设置的工作目录。

2.13 HEALTHCHECK

告诉Docker如何测试容器以检查它是否仍在工作,即健康检查,例如:

HEALTHCHECK --interval=5m --timeout=3s --retries=3 \

CMD curl -f http:/localhost/ || exit 1

  其中,一些选项的说明:

  • --interval=DURATION (default: 30s):每隔多长时间探测一次,默认30秒
  • -- timeout= DURATION (default: 30s):服务响应超时时长,默认30秒
  • --start-period= DURATION (default: 0s):服务启动多久后开始探测,默认0秒
  • --retries=N (default: 3):认为检测失败几次为宕机,默认3次

  一些返回值的说明:

  • 0:容器成功是健康的,随时可以使用
  • 1:不健康的容器无法正常工作
  • 2:保留不使用此退出代码

2.14 ARG

在构建镜像时,指定一些参数,例如:

FROM centos:6

ARG user # ARG user=root

USER $user

这时,我们在docker build时可以带上自定义参数user了,如下所示:

docker build --build-arg user=edisonzhou Dockerfile .

四、综合Dockerfile案例

下面是一个Java Web应用的镜像Dockerfile,综合使用到了上述介绍中最常用的几个命令:

# Maven build container

FROM maven:3.8.5-openjdk-11 AS maven_build

COPY pom.xml /tmp/

COPY src /tmp/src/

WORKDIR /tmp/

RUN mvn package

#pull base image

FROM openjdk

#maintainer

MAINTAINER dstar55@yahoo.com

#expose port 8080

EXPOSE 8080

#default command

CMD java -jar /data/hello-world-0.1.0.jar

#copy hello world to docker image from builder image

COPY --from=maven_build /tmp/target/hello-world-0.1.0.jar /data/hello-world-0.1.0.jar

有了Dockerfile,就可以创建镜像了:

docker build -t="hello-world-java" .

最后,可以通过以下命令创建容器:

docker run -p 8080:8080 -it --rm hello-world-java

五、Dockers-compose编排

下面是一个Docker-compose编排的例子:

version: "3.0"

services:

hello-world:

build:

context: ./

dockerfile: Dockerfile

ports:

- 8080:8080

六、小结

本文介绍了Dockerfile的背景和组成,以及最常用的一些Dockerfile命令,最后介绍了一个综合使用了Dockefile指令的一个案例来说明Dockerfile的应用。

相关推荐

oracle数据导入导出_oracle数据导入导出工具

关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...

继续学习Python中的while true/break语句

上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个...

python continue和break的区别_python中break语句和continue语句的区别

python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...

简单学Python——关键字6——break和continue

Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...

2-1,0基础学Python之 break退出循环、 continue继续循环 多重循

用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...

Python 中 break 和 continue 傻傻分不清

大家好啊,我是大田。...

python中的流程控制语句:continue、break 和 return使用方法

Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...

L017:continue和break - 教程文案

continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...

作为前端开发者,你都经历过怎样的面试?

已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...

面试被问 const 是否不可变?这样回答才显功底

作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...

2023金九银十必看前端面试题!2w字精品!

导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。...

前端面试总结_前端面试题整理

记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...

由浅入深,66条JavaScript面试知识点(七)

作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录...

2024前端面试真题之—VUE篇_前端面试题vue2020及答案

添加图片注释,不超过140字(可选)...

今年最常见的前端面试题,你会做几道?

在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...