Docker(三):DockerFile

一、DockerFile介绍

1、DockerFile 介绍

DockerFile 是一种能够被Docker 程序解释的文件(一般为了方便理解称之为"剧本")。

DockerFile 由一条一条的指令组成,并且有自己的书写格式和支持的命令。当我们需要在容器

镜像中指定自己额外的需求时,只需要在 DockerFile 上添加或修改指令,然后通过

docker build 生成我们自定义的镜像(imahe)。如下图所示:

2、DockerFile 文件基本构成

1)基础镜像信息

2)维护者信息

3)镜像操作指令

4)镜像容器启动时执行指令

二、DockerFile 指令介绍

1、DockerFile 指令分类

DockerFile 的指令主要分为 构建类指令 和 设置类指令;

构建类指令主要用来构建镜像image,其指令的操作不会在image的容器上执行,如:FROM

、MAINTAINER、RUN、ENV、ADD、COPY 都是构建类指令。

设置类指令主要用于设置镜像image的属性信息,其指令的操作将在image的容器上执行,

如:CMD、ENTRYPOINT、USER、EXPOSE、VOLUME、WORKDIR、ONBUILD 都是

设置类指令。

2、DockerFile 指令说明

2.1、指令说明

指令 说明
FROM 基础镜像,当前新镜像是基于哪个镜像的,有继承的意味
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露的端口
WORKDIR 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点
ENV 用来在构建镜像过程中设置环境变量
ADD 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY 类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 COPY src dest COPY ["src","dest"]
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT 指定一个容器启动时要运行的命令 ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发

2.2、指令详细介绍

通过 man docker file 命令可以查看到DockerFile指令的详细说明,这里简单介绍下常用

的指令。

2.2.1、FROM

FROM 指令 用于指定其后构建 新镜像 是所使用的基础镜像。

FROM 指令 必须是 DockerFile 文件中的收条命令。

FROM 指令 所指定的基础镜像image可以是远程官方仓库中的也可以是本地仓库中的(一

般是Linux或CentOS),优先本地仓库中的镜像。

FROM 指令使用格式:

FROM <image镜像>:<tag版本标签>

如:FROM centos:latest

2.2.2、RUN

RUN 指令用于设置在构建镜像过程中执行的命令,有以下2种格式:

1)shell格式

命令格式:RUN <命令>

例如:RUN echo 'kubemsb' > /var/www/html/index.htm

2)exec 格式

命令格式:RUN ["可执行文件","参数1","参数2"]

例如:RUN ["/bin/bash","-c","echo kubemsb > /var/www/html/index.htm"]

注意:

按优化的角度来讲:当有多条需要执行的run命令时,不要使用多条RUN、尽量使用

'&&' 或 '\' 符号连接成一行。因为多条RUN命令会让镜像建立多层(镜像变臃肿了),

如下图所示:

2.2.3、CMD

CMD命令不同于 RUN 命令,CMD命令用于在容器启动时所要执行的命令,而RUN 用于

指定镜像构建时所要执行的命令、

CMD 命令格式有3种,如下所示:

CMD ["executable","param1","param2"]

CMD ["param1","param2"]

CMD command param1 param2

注意:

1)每个DockerFile只能有一条CMD命令。如果指定了多条CMD命令,只有最后一条

CMD命令会被执行

2)如果容器启动时指定了运行命令,则会覆盖CMD指定的命令。

3)什么是容器启动时指定的运行命令?

启动容器时指定的运行命令,如:docker run -d 镜像名 运行命令

2.2.4、EXPOSE

EXPOSE命令用于指定容器在运行时监听的端口,可以一次监听多个端口

命令格式:EXPOSE <port> [<port>...]

例如:EXPOSE 80 3306 8080

注意:

EXPOSE 监听的端口,在容器启动时需要通过参数 -p 映射到宿主机上后外部才能访问

2.2.5、ADD

ADD 命令用于将宿主机上的文件拷贝到构建的自定义镜像image 中

格式:ADD <src> <dest>

src:可以是一个本地文件或压缩文件,也可以是一个url,如果src是一个url,那么ADD 就

相当于wget 命令

dest:dest 路径的填写可以是容器内的绝对路径,也可以是相对工作目录的相对路径

2.2.6、ENV

ENV 命令用于指定一个环境变量

格式:ENV <key> <value> 或者

ENV <key>=<value>

例如:ENV JAVA_HOME /usr/local/jdk/jdk-XX

2.2.7、COPY

COPY命令与 ADD 命令功能一样,都是将宿主机上的文件拷贝到构建的自定义镜像

image 中,不同的是COPY的源文件src只能是本地文件

格式:COPY <src> <dest>

2.2.8、ENTRYPOINT

ENTRYPOINT 与 CMD 非常相似,都是用于指定在容器启动时需要实行的命令。

ENTRYPOINT 与 CMD 相同点:

I)一个DockerFile 只能写一条,如果写了多条,那么只有最后一条才生效;

II)都是在容器启动时执行;

ENTRYPOINT 与 CMD 不同点:

I)如果用户启动容器时指定了运行命令,ENTRYPOINT不会被运行命令覆盖,而 CMD

会被运行命令覆盖

格式有2种:

I)ENTRYPOINT ["executable","param1","param2"]

II)ENTRYPOINT command param1 param2

2.2.9、VOLUME

VOLUME 命令用于把宿主机的目录与容器中的目录映射。

使用时只指定挂载点,docker容器中的目录为自动生成的。

格式:VOLUME ["<mountpoint>"]

2.2.10、USER

USER 命令用于设置启动容器的用户(如:Oracle需要Oracle用户操作),可以是

用户名或UID。

例如:USER daemon 或 USER 1001

注意:

如果容器设置了以 daemon 用户去运行,那么 RUN,CMD 和 ENTRYPOINT都会

以这个用户去运行;镜像构建完成后,通过docker run 运行容器时,可以通过参数

-u 来覆盖锁指定的用户

2.2.11、WORKDIR

WORKDIR 命令用于设置工作目录,类似于cd 命令。

不建议使用RUN cd /root,建议使用 WORKDIR,如:WORKDIR /root

三、DockerFile 执行流程及生成镜像的一般步骤

3.1、DockerFile 生成镜像的基本步骤

使用 DockerFile 生成对应镜像一般需要以下步骤:

1)在指令目录创建一个文件夹(目标)

2)在该文件夹中编写 DockerFile 文件

3)使用 "docker build" 命令构建镜像

4)docker run 使用构建的镜像启动容器

如下图所示:

3.2、DockerFile文件中的指令需要满足以下规则

3.3、DockerFile 执行流程

docker 执行一个 DockerFile 脚本的流程大致如下:

1)docker从基础镜像运行一个容器

2)执行一条指令并对容器作出修改

3)执行类似docker commit的操作提交一个新的镜像层

4)docker再基于刚提交的镜像运行一个新的容器

5)执行dockerfile中的下一条指令直到所有指令都执行完成

3.4、DockerFile、Docker镜像和Docker容器之间的关系

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不

同阶段,即:

I)Dockerfile是软件的原材料

II)Docker镜像是软件的交付品

III)Docker容器则可以认为是软件的运行态

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺

一不可,合力充当Docker体系的基石,如下图所示:

1)Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。

Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、

动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务

和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等

2)Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,

当运行 Docker镜像时,会真正开始提供服务

3)Docker容器,容器是直接提供服务的

四、Dockerfile 使用案例

1、以构建Tomcat 为例来看下 DockerFile 的使用步骤

1.1、在指定目录下创建一个目录,如:tomcatdir

1.2、在目录 tomcatdir 中上传 jdk 和 tomcat 的安装包,

1.3、在目录 tomcatdir 中创建DockerFile 文件,DockerFile内容如下:

cs 复制代码
FROM         centos:centos7
MAINTAINER    bobo<[email protected]>
#把宿主机当前上下文的hello.txt拷贝到容器/usr/local/路径下
COPY hello.txt /usr/local/hello.txt
#把java与tomcat添加到容器中
ADD jdk-8u73-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.71.tar.gz /usr/local/
#安装vim编辑器
#RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_73
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.71
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.71
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE  8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-8.0.47/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-8.0.47/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-8.5.71/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.0.47/bin/logs/catalina.out

1.4、构建tomcat 镜像

执行命令 docker build -f Dockerfile -t image-tomcat . 来构建镜像,

其中 image-tomcat 是镜像名称,-f 指定DockerFile 文件

1.5、启动容器

1)执行下面命令来启动容器:

docker run -it -p 9080:8080 --name docker-tomcat -v /root/DockerFile/tomcatdir/test:/usr/local/apache-tomcat-8.5.71/webapps/test -v /root/DockerFile/tomcatdir/tomcatlogs/:/usr/local/apache-tomcat-8.5.71/logs -d image-tomcat

2)测试

在浏览器中输入 Apache Tomcat/8.5.71 访问tomcat ,看容器是否运行成功,

如下图所示:

相关推荐
杨不易呀1 小时前
互联网大厂Java面试:从Java SE到微服务的全栈挑战
java·spring boot·spring cloud·微服务·面试·技术栈·内容社区
alden_ygq2 小时前
K8S node ARP 表爆满 如何优化
容器·kubernetes·php
Silence4Allen2 小时前
Ubuntu 24.04 完整Docker安装指南:从零配置到实战命令大全
linux·ubuntu·docker
Gavinjou大笨象7 小时前
『Kubernetes(K8S) 入门进阶实战』资源管理
容器·贪心算法·kubernetes
阿湯哥12 小时前
Kubernetes 与 Service Mesh 的集成
容器·kubernetes·service_mesh
SoulruiA15 小时前
关于Docker拉取镜像超时/无法访问镜像仓库解决方案
docker·容器·eureka
PerCheung15 小时前
Docker与WSL2如何清理
运维·docker·容器
AllenLeungX17 小时前
firewall docker 冲突问题解决(亲测有效)
运维·docker·容器
来一杯龙舌兰18 小时前
【Dockerfile】Dockerfile打包Tomcat及TongWeb应用镜像(工作实践踩坑教学)
docker·中间件·tomcat·国产化·dockerfile·tongweb·容器化部署