目录
一、概念
二、Dockerfile的常用指令
三、构建镜像
四、CMD和ENTRYPOINT命令的区别
五、EXPOSE指令详解
引言:在上一章《容器数据卷》中,已经给大家简单的介绍了下DockerFile,那么在本章中我们将详细来讲讲DockerFile。
一、概念
DockerFile就是用来构建docker镜像的构建文件,即脚本命令。我们通过DockerFile脚本可以生成镜像。通过前面的章节我们了解到,镜像是分层的,而DockerFile脚本命令也是一个个一层层的。它包含了一系列指令,这些指令描述了镜像的构建过程,包括安装软件、设置环境变量、添加文件等。Dockerfile使得镜像的构建过程透明化,并且可以通过版本控制管理,确保镜像的一致性和可重复性。
二、Dockerfile的常用指令
常用命令详解:
常用命令通俗理解:
日常工作中镜像的构建涉及到的内容:
1. 编写一个DockerFile文件
2. docker build构建成为一个镜像
3. dokcer run 运行镜像
4. docker push 发布镜像(DockerHub、阿里云镜像仓库等)
我们通过查看Docker镜像仓库中一些官方的镜像,能够更直观地看到通过DockerFile构建镜像的全貌 :
很多官方的镜像有些是基础包或者没有我们日常工作中需要的功能,因此我们通常会根据需要构建自己的镜像。而我们所构建的镜像,是在一些现有的镜像基础上层层堆叠而成。如下图所示,可写容器这一层,便是我们要做的,Docker为我们减省了很大一部分工作量:
在编写DockerFile文件前,还有一些点需要注意:
1. DockerFile中每个保留关键字(即指令),必须是大写字母。
2. DockerFile中的命令是从上到下执行。上图所示,我们按命令的执行顺序层层叠加,构建出一个镜像的完整过程。
3. DockerFile中#表示注释
4. DockerFile中每个指令都会创建一个新的镜像层并提交。
DockerFile是面向开发人员的,我们以后要发布项目,做镜像,就需要编写DockerFile文件,而且这个文件非常的简洁。Docker镜像已经成为了企业交付的标准,是我们必须要掌握的。
三、构建镜像
构建一个自己的Centos
编写DockerFile文件
# 使用官方CentOS基础镜像,centos记得要全小写,官方要求
FROM centos
# 设置作者
MAINTAINER wangzhexiao
# 设置环境变量
ENV WZXPATH /home/wangzhexiao
# 设置工作目录
WORKDIR $WZXPATH
# 安装ifconfig命令,CentOS7默认没有ifconfig
RUN yum -y install net-tools
# 暴露端口,如果有必要
EXPOSE 80
# 容器启动时执行的命令
CMD echo "只要你相信自己,并且坚持着足够努力地去专注做一件事情,未来肯定会越来越好!"
CMD /bin/bash
docker build -f DockerFile -t wzx-centos:1.0 .
命令详解:
build 构建镜像
-f 指定DockerFile路径
-t 指定了要创建的镜像的名字和标签
. 表示当前目录,是构建上下文的路径。它是当你不在Dockerfile所在目录时告诉Dockerfile的位置
构建并成功运行新建的镜像:
通过docker history 容器id 命令,我们还可以查看Docker镜像构建的历史信息,平时我们拿到一个镜像,都可以这么查看研究它们的构建过程:
四、CMD和ENTRYPOINT命令的区别
CMD和ENTRYPOINT是Dockerfile中用于指定容器启动时执行的命令或程序的指令,它们之间存在明显的区别如下:
1. 基本用途和行为差异
ENTRYPOINT指定容器启动时的主命令,并且可以在docker run
时通过附加命令行参数来传递额外的参数给这个命令。
CMD指令也用来指定容器启动时执行的命令或程序,但它可以被docker run
命令中指定的命令覆盖。如果Dockerfile中存在多个CMD指令,只有最后一个CMD指令会生效。
2. 写法上的区别
ENTRYPOINT和CMD在Dockerfile中都支持两种格式——shell格式和exec格式。当使用exec格式时,如果同时使用了ENTRYPOINT和CMD,那么CMD中的内容会作为参数传递给ENTRYPOINT。
3. 实际使用差异
如果只使用CMD,那么在docker run
时可以通过附加的命令行参数来覆盖CMD指定的命令。
如果设置了ENTRYPOINT,则ENTRYPOINT指定的命令将作为容器的主命令执行,而CMD提供的任何内容都将作为参数传递给ENTRYPOINT。这意味着,使用ENTRYPOINT的容器更像是一个单独的应用,而CMD则提供了灵活性,允许用户在启动容器时指定额外的参数。
4. 覆盖行为
在docker run
命令中,通过指定命令行参数,可以覆盖CMD指令,但ENTRYPOINT指令定义的命令不会被覆盖,除非使用--entrypoint
选项。
结合以上描述的区别内容,我们通过以下例子来理解下:
FROM centos
CMD ["ls","-a"]
追加的-l命令会覆盖CMD的ls -a命令,而-l不是一个完整的命令,所以会报错:
FROM centos
ENTRYPOINT ["ls","-a"]
-l命令会追加到ENTRYPOINT的ls -a命令后,形成新命令ls -al
五、EXPOSE指令详解
我们要清楚地知道,EXPOSE指令只生效于运行时而非构建时,EXPOSE指令并不会自动将容器内部的端口映射到我们的宿主机(Linux服务器)上,它的作用是向Docker守护进程声明容器运行时需要监听的网络端口,并向用户以及后续的Dockerfile指令传达这个信息,它可以帮助开发及运维清楚地知道应用程序在容器内部所侦听的端口号,从而高效地配置和管理容器。因此如果要进行端口映射,我们还是需要使用Docker的端口映射命令。即在运行容器时候,使用Docker的-p选项将容器的端口映射到宿主机指定的端口上:
docker run -p 主机端口:容器端口 镜像名
案例:将Tomcat容器的8080端口映射到宿主机的3380端口,则可以执行以下命令:
docker run -p 3380:8080 tomcat