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

Dockerfile详解 dockerfile示例

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

一、关于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的应用。

相关推荐

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

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

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入门,这部分知识点显得很庞杂,内容分支很多,大部分同学在刚刚学习时一头雾水。...