一、镜像的创建
1、基于已有镜像创建
基于已有容器构建镜像主要是通过
docker commit
命令来构建新的镜像。
dockercommit构建进行主要有三步:
- 创建和运行容器
- 修改容器
- 将容器保存为新的镜像
比如在 ubuntu 镜像中安装vim编辑器并存为新的镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="mrhelloworld" -m="jdk11 and tomcat9" centos7 mycentos:7
-a
:提交的镜像作者;
-c
:使用 Dockerfile 指令来创建镜像;
-m
:提交时的说明文字;
-p
:在 commit 时,将容器暂停。
1、首先本地要有镜像或者需要从Docker Hub上下载所需的基础镜像:
docker pull ubuntu:18.04
2、创建并运行容器:
# 根据 unbuntu 镜像创建一个容器,容器名docker 默认给
docker run -it ubuntu
# 根据 unbuntu 镜像创建一个容器,容器名为 test
docker run -it --name test ubuntu
3、进入该容器,并且确认没有 vim 编辑器。
# 在 docker 容器中,有的需要先安装 pip 工具才能使用 pip 安装库
docker exec -it container_name /bin/bash # 进入docker
apt-get update && apt-get install -y python3-pip
# 安装 vim 工具
apt-get install vim
4、使用commit, 将修改后的容器存为新的镜像
docker commit 容器id/容器名 新镜像名
然后就可以使用新的镜像进行容器的创建
2、基于 Dockefile 创建镜像
Pytorch Docker镜像构建教程(不同系统、CUDA、Python版本)
Pytorch Docker镜像构建教程(不同系统、CUDA、Python版本) - 知乎 (zhihu.com)
2.0、dockerfile 创建镜像命令
示例:
docker build -t nginx:test .
#基于dockerfile文件构建镜像命令
完整的写法: docker build -f dockerfile -t nginx:new .
docker build : 基于dockerfile 构建镜像
-f :指定dockerfile 文件(默认不写的话指的是当前目录)
-t :(tag) 打标签 ——》nginx:new
. :专业说法:指的是构建镜像时的上下文环境,简单理解:指的当前目录环境中的文件
2.1、镜像加载原理介绍
联合文件系统:
- UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS。
- Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
- 特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
- 我们下载的时候看到的一层层的就是联合文件系统。
镜像加载原理
- Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。
- bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。
- 在Docker镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
- rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,
这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;
接着再安装一个apache,又会在images上面再叠加一层image。
最后它们看起来就像一个文件系统即容器的rootfs。在Docker的体系里把这些rootfs叫做Docker的镜像。
但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。
当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。
Dockerfile 是什么
- Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
- 镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
- Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成 image 即可, 省去了敲命令的麻烦。
- 除了手动生成Docker镜像之外,可以使用Dockerfile自动生成镜像。Dockerfile是由多条的指令组成的文件,其中每条指令对应 Linux 中的一条命令,Docker 程序将读取Dockerfile 中的指令生成指定镜像。
驱动程序overlay2
Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#“号开头的注释。
Docker 镜像结构的分层
镜像不是一个单一的文件,而是有多层构成。
容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。 如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。
Docker使用存储驱动管理镜像每层内容及可读写层的容器层。
- Dockerfile中的每一个指令都会创建一个新的镜像层(是一个临时的容器,执行完成后将不再存在,再往后进行重新的创建于操作)
- 镜像层将被缓存和复用(后续的镜像曾将基于前面的每一层,每一层都会由下几层的缓存)
- 当Dockerfile的指令被修改了,复制的文件变化了,或构建镜像时指定的变量不同了,那么对应的镜像层缓存就会失效(因为后续的操作必然更改前面的镜像层)
- 某一层的镜像缓存失效了之后,它之后的镜像层就会失效(第一层不成功,那么第二层也会失效)
- 容器的修改并不会影响镜像,如果在某一层中添加一个文件,在下一层中删除它,镜像中依然会包含该文件
2.2、指令详解
Dockerfile 指令说明FROM
指定基础镜像,用于后续的指令构建。
MAINTAINER指定Dockerfile的作者/维护者。(已弃用,推荐使用LABEL指令)LABEL添加镜像的元数据,使用键值对的形式。RUN在构建过程中在镜像中执行命令。在所基于的镜像上执行命令,并提交到新的镜像中CMD指定容器创建时的默认命令。(可以被覆盖)ENTRYPOINT设置容器创建时的主要命令。(不可被覆盖)EXPOSE声明容器运行时监听的特定网络端口。ENV在容器内部设置环境变量。ADD将文件、目录或远程URL复制到镜像中。COPY将文件或目录复制到镜像中。VOLUME为容器创建挂载点或声明卷。WORKDIR设置后续指令的工作目录。USER指定后续指令的用户上下文。ARG定义在构建过程中传递给构建器的变量,可使用 "docker build" 命令设置。ONBUILD当该镜像被用作另一个构建过程的基础时,添加触发器。STOPSIGNAL设置发送给容器以退出的系统调用信号。HEALTHCHECK定义周期性检查容器健康状态的命令。SHELL覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令。
2.2.1、FROM
指定新镜像所基于的镜像,第一条指令必须为FROM指令每创建一个镜像就需要一条FROM指令。且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令。
语法格式如下:
FROM <image>
# 指定基础image为该image的最后修改的版本
FROM <image>:<tag>
# 指定基础image为该image的一个tag版本
其中
<tag>
是可选项,如果没有选择,那么默认值为
latest
。
如果不以任何镜像为基础,那么写法为:
FROM scratch
但是ARG可以放在FROM之前,例如
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
2.2.2、RUN
用于执行后面跟着的命令行命令。这些命令可以是安装软件包、创建文件、设置环境变量等,用于定制镜像的功能。
有以下俩种格式:
# shell格式:就像在命令行中输入的Shell脚本命令一样。
RUN <command>
# exec格式:就像是函数调用的格式。
RUN ["executable", "param1", "param2"]
# 例如:
RUN ["./test.php", "dev", "offline"] # 等价于 RUN ./test.php dev offline
注意:Dockerfile 的每条RUN指令,都会在当前镜像基础上执行指定命令,并提交为新的镜像层。所以过多无意义的层,会造成镜像膨胀过大。因此,为了减少镜像大小和层数,建议将多个相关的命令合并到一条RUN指令中,并使用&&来连接它们。这样做可以减少镜像的构建时间和存储空间。
例如:
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
RUN指令在Dockerfile中非常常用,它使得我们可以在构建镜像的过程中自动化执行一系列命令,从而实现自定义和配置化的镜像构建过程。通过合理使用RUN指令,我们可以构建出功能完善、安全可靠且高效的Docker镜像。
使用示例
RUN apt-get update
RUN apt-get install -y curl
2.2.3、CMD
设置container启动时执行的操作
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行, CMD指令用于指定一个容器启动时所运行的命令
- RUN 是在 docker build 构建时要运行的命令
作用:为启动的容器指定默认要运行的程序,即容器默认的启动命令,程序运行结束,容器也就结束。
需要注意的是,一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用。CMD会被docker run之后的参数替换,如果我们在Dockerfile中指定了CMD指令,通过在docker run命令行中也指定了要运行的命令,命令行中的指令会覆盖Dockerfile中的CMD指令。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
#第一种
CMD <shell 命令>
# 第二种
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
#第三种
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
2.2.4、ENTRYPOINT
设置container启动时执行的操作
ENTRYPOINT 指令用于设置在启动容器时始终运行的可执行文件。类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
Docker ENTRYPOINT 指令支持 shell 和 exec 两种模式的写法:
- Exec 模式:
ENTRYPOINT ["executable", "parameter1", "parameter2"]
- Shell 模式:
ENTRYPOINT command parameter1 parameter2
该指令的使用分为两种情况,一种是独自使用,另一种和CMD指令配合使用。
当独自使用时,如果你还使用了CMD命令且CMD是一个完整的可执行的命令,那么CMD指令和ENTRYPOINT会互相覆盖只有最后一个CMD或者ENTRYPOINT有效。
比如:
# CMD指令将不会被执行,只有ENTRYPOINT指令被执行
CMD echo “Hello, World!”
ENTRYPOINT ls -l
另一种用法和CMD指令配合使用来指定ENTRYPOINT的默认参数,这时CMD指令不是一个完整的可执行命令,仅仅是参数部分。ENTRYPOINT指令只能使用JSON方式指定执行命令,而不能指定参数。
FROM centos7
CMD ["-l"]
ENTRYPOINT ["/usr/bin/ls"]
参考: 使用exec模式与shell模式,执行ENTRYPOINT和CMD的区别 - 知乎 (zhihu.com)
2.2.5、ENV
设置环境变量,会被后面的RUN使用。定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。container启动后,可以通过
docker inspect
查看这个环境变量,也可以通过在
docker run --env key=value
实时设置或修改环境变量。
格式:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
2.2.6 、ARG
LABEL <key>=<value> <key>=<value> <key>=<value> ...
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
格式:
ARG <参数名>[=<默认值>]
2.2.7、LABEL
LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
比如我们可以添加镜像的作者:
LABEL org.opencontainers.image.authors="runoob"
2.2.8、VOLUME
指定挂载点。设置指令,使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用,也可以共享给其他容器使用。我们指定容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后所有的更改都会丢失。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。
作用:
- 避免重要的数据,因容器重启而丢失,这是非常致命的。
- 避免容器不断变大。
格式:
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
例如:
VOLUME /data
VOLUME /data1 /data2
使用VOLUME指令后,Docker会在容器中创建一个或多个匿名卷(anonymous volume),这些匿名卷将持久化存储容器中的数据。当容器删除时,这些匿名卷不会被自动删除,您需要手动删除它们。
需要注意的是,VOLUME指令只能在Dockerfile中使用,不能在容器运行时使用。如果您需要在容器运行时创建挂载点,可以使用
docker run
命令的
-v
选项。同时在启动容器 docker run 的时候,我们也可以通过 -v 参数修改挂载点。将宿主机的目录或文件挂载到容器的挂载点上,实现宿主机与容器之间的数据共享。
RUN mkdir /myvol
RUN echo "hello wolrd" > /myvol/greeting
VOLUME ["/myvol"]
运行通过该Dockerfile生成image的容器,/myvol 目录中的数据在容器关闭后,里面的数据还存在。
该指令会创建匿名数据卷,可以通过
docker volume ls
指令查看目录位置
[root@localhost data]# docker volume ls
DRIVER VOLUME NAME
local 5a89f86a6926edb5cac07e7b11fdde89f0dfa7284ca6add8bf09274bc1afea62
[root@localhost data]#
然后再通过
docker volume inspect
查看具体路径
[root@localhost data]# docker volume inspect 5a89f86a6926edb5cac07e7b11fdde89f0dfa7284ca6add8bf09274bc1afea62
[
{
"CreatedAt": "2024-01-04T04:36:33-05:00",
"Driver": "local",
"Labels": {
"com.docker.volume.anonymous": ""
},
"Mountpoint": "/var/lib/docker/volumes/5a89f86a6926edb5cac07e7b11fdde89f0dfa7284ca6add8bf09274bc1afea62/_data",
"Name": "5a89f86a6926edb5cac07e7b11fdde89f0dfa7284ca6add8bf09274bc1afea62",
"Options": null,
"Scope": "local"
}
]
2.2.9、EXPOSE
指定新镜像加载到Docker时要开启的端口,仅仅只是声明监听的端口,在监听是可以指定是TCP还是UDP协议,默认值为TCP
作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
格式:
EXPOSE <端口号>
# 默认情况下一般如果我们未指定协议的话,那么都是使用TCP协议,
# 当然也可以指定具体的协议,也可以同时指定TCP和UDP协议。
EXPOSE 80/tcp
EXPOSE 80/udp
2.2.10、WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
WORKDIR <工作目录路径>
可以多次切换(相当于cd命令)这种用法比较少,对RUN ,CMD,ENTRYPOINT生效。
格式:
WORKDIR /path/to/workdir
下面的用法比较少
# 在 /p1/p2 下执行 vim a.txt
WORKDIR /p1 WORKDIR p2 RUN vim a.txt
2.2.11、USER
设置指令,设置启动容器的用户,默认是root用户
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
2.2.12、HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
2.2.13、ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
ONBUILD <其它指令>
2.2.14、ADD
ADD指令是指将宿主机的文件或目录复制到镜像文件系统中指定的路径,源文件复制到镜像中,源文件要与 Dockerfile 位于相同目录中,或者是一个 URL 。
注意:如果源文件是个归档文件(压缩文件),则docker会自动帮解压。但是URL下载和解压特性不能一起使用。任何压缩文件通过URL拷贝,都不会自动解压。
其语法格式有两种:
ADD <src>... <dest>
以下是
ADD
指令的一些关键点和行为:
- 源文件/目录与目标路径:- 如果源路径是一个文件,并且目标路径以
/
结尾,那么Docker会将目标路径视为一个目录,并将源文件拷贝到该目录下。如果目标路径不存在,Docker会自动创建它。- 如果源路径是一个文件,并且目标路径不是以/
结尾,那么Docker会将目标路径视为一个文件。如果目标路径不存在,Docker会创建一个新文件,其内容来自源文件。如果目标路径是一个已存在的文件,那么Docker会用源文件的内容覆盖它(仅覆盖内容,文件名保持不变)。- 如果目标路径实际上是一个已存在的目录,那么源文件会被拷贝到该目录下(这可能会导致混淆,所以最好显式地以/
结尾目标路径)。 - URL文件:除了本地文件或目录,
ADD
指令还支持从URL添加文件。但是,这种功能并不常见,因为它可能导致构建过程的不确定性和不可重复性(例如,如果URL内容发生变化)。 - 自动解压:
ADD
指令有一个独特的功能,就是可以自动解压识别的压缩格式(如tar)。如果源文件是一个可识别的压缩格式,并且目标路径是一个目录,那么Docker会自动解压文件到目标目录中。 - 权限和所有权:添加到镜像中的文件和目录将继承Dockerfile中
USER
和WORKDIR
指令所指定的权限和所有权。 - 与COPY指令的区别:
ADD
指令和COPY
指令在功能上非常相似,都是用于将文件或目录从构建上下文拷贝到镜像中。然而,ADD
指令提供了额外的功能,比如自动解压和URL支持,而这些功能在COPY
指令中不可用。通常建议,如果不需要ADD
的额外功能,最好使用COPY
指令,因为它的语义更清晰。 - 构建缓存:每次使用
ADD
指令时,Docker都会为该指令创建一个新的镜像层,并缓存该层。如果源文件没有发生变化,Docker将重用之前的缓存层,这可以加速构建过程。
ADD
命令可以使用以下选项:
-from
:指定要复制的文件或目录的镜像。-chown
:指定要复制的文件或目录的所有者和组。-chmod
:指定要复制的文件或目录的权限。
以下是
ADD
命令的一些示例:
# 将当前上下文中的test.txt文件添加到镜像的/app目录中
ADD test.txt /app/
# 从URL添加一个文件(尽管这不太常见)
ADD https://example.com/remote-file.txt /app/remote-file.txt
ADD src/ /app
ADD src/index.html /app/index.html
ADD src/ /app/ -from my-image
ADD src/ /app/ -chown root:root
ADD src/ /app/ -chmod 755
请注意,由于
ADD
指令的某些行为可能会导致混淆,尤其是当目标路径是文件还是目录时,因此在撰写Dockerfile时务必小心。同时,考虑到构建的可重复性和清晰度,很多Docker开发者更倾向于使用
COPY
指令而不是
ADD
指令,除非确实需要
ADD
提供的特殊功能。
2.2.15、COPY
COPY 命令用于将本地文件或目录复制到容器中。COPY 只是复制,不会进行解压。COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中
语法如下:
COPY <src> <dest>
其中,
src
是本地文件或目录的路径,
dest
是容器中文件或目录的路径。
如果
src
是目录,则
dest
可以是目录或文件。如果
dest
是目录,则
src
中的所有文件和子目录都会被复制到
dest
中。如果
dest
是文件,则
src
中的所有文件都会被复制到
dest
中,并重命名为
dest
的文件名。
如果
src
是文件,则
dest
必须是文件。如果
dest
是目录,则
src
中的文件会被复制到
dest
中,并重命名为
dest
的文件名。
COPY 命令可以使用以下选项:
-from
:指定要复制的文件或目录的镜像。-chown
:指定要复制的文件或目录的所有者和组。-chmod
:指定要复制的文件或目录的权限。
COPY 命令是 Dockerfile 中非常常用的命令,它可以用于将应用程序的源代码、配置文件、数据库文件等复制到容器中。
2.2.17、ARG DEBIAN_FRONTEND=noninteractive作用说明
在Dockerfile中使用ARG指令定义变量并为其指定一个默认值。ARG指令用于在构建过程中传递变量的值。
对于DEBIAN_FRONTEND=noninteractive,它定义了一个名为DEBIAN_FRONTEND的变量,并将其默认值设置为noninteractive。在这个上下文中,noninteractive用于禁用任何交互式提示。
作用:
在这个Dockerfile中,设置DEBIAN_FRONTEND=noninteractive是为了避免在安装过程中出现交互式提示。
默认情况下会在终端上显示交互式提示,例如要求用户确认安装某个软件包、选择配置选项等。但在Docker容器中构建镜像时,没有终端可以显示这些提示,因此需要禁用交互提示。
通过将DEBIAN_FRONTEND设置为noninteractive,在安装过程中使用默认选项而不提示用户。
这样可以确保在构建Docker镜像时,整个过程是自动化的,不需要人工干预。
2.3、完整Dockerfile参考
# pull base image
#FROM 127.0.0.1:5000/centos6.7:latest
FROM hub.c.163.com/public/centos:6.7
# maintainer
MAINTAINER wlddhj "[email protected]"
# update source
# pass
# install req pkgs
#RUN yum update -y
RUN yum install -y bzip2
# deploy jdk1.7.0_80
RUN mkdir -p /data/tmp
WORKDIR /data/tmp
RUN wget http://7mnldi.com1.z0.glb.clouddn.com/jdk-7u80-linux-x64.rpm\
&& yum install -y jdk-7u80-linux-x64.rpm
# set jdk env
ENV JAVA_HOME=/usr/java/jdk1.7.0_80
ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$PATH:$JAVA_HOME/lib
# deploy tomcat 7.0.33.0
RUN useradd tomcat\
&& mkdir -p /data/product/deploy
#RUN mkdir /opt/apache-tomcat
WORKDIR /data/tmp
#RUN wget http://7mnldi.com1.z0.glb.clouddn.com/apache-tomcat_7.0.33.0.tar.bz2
RUN wget http://7mnldi.com1.z0.glb.clouddn.com/apache-tomcat-7.0.72.tar.gz\
&& cd /data/tmp\
&& tar -xf apache-tomcat-7.0.72.tar.gz\
&& mv apache-tomcat-7.0.72 /opt/apache-tomcat\
&& chown -R tomcat.tomcat /opt/apache-tomcat
# add tomcat's startup script
ADD ./tomcat /etc/init.d/tomcat
RUN chmod 755 /etc/init.d/tomcat
# dir mapping
# pass
# set tomcat env
# pass
# deploy zabbix agent
# pass
# clean yum cache
RUN yum clean all
# clean wget cache
RUN rm -rf /data/tmp
# expose ports
EXPOSE 8080
# start tomcat
#ENTRYPOINT service tomcat start && tail -f /opt/apache-tomcat/logs/catalina.`date +'%Y-%m-%d'`.out
ENTRYPOINT service tomcat start && tail -f /opt/apache-tomcat/logs/catalina.out
#ENTRYPOINT service tomcat start
二、导入导出镜像、导入导出容器
通过导入和导出镜像文件的方式可以将镜像从一个Docker宿主机迁移到另一个Docker宿主机。首先,在源Docker宿主机上使用以下命令导出镜像文件:
1、导出镜像(docker save)与导入镜像(docker load)
这是一对操作,用于处理 Docker 镜像。这个操作会将所有的镜像层以及元数据打包到一个 tar 文件中。然后,你可以使用 docker load 命令将这个 tar 文件导入到任何 Docker 环境中。例如:
导出:docker save -o <保存路径>/myimage.tar myimage:latest
导入:docker load -i <路径>/myimage.tar
这种方式主要用于分享或迁移整个镜像,包括所有版本、标签和历史。
-o 参数表示输出的文件路径和名称,后面紧跟着要保存的镜像名称。例如,docker save -o /pathtosave/myimage.tar myimage:tag
-i 参数表示输入的文件路径和名称。例如,docker load -i /pathtoload/myimage.tar
适用场景
假设你在你的开发环境中创建了一个新的 Docker 镜像,这个镜像包含了你的应用和所有依赖项,你已经测试了这个镜像,并且打了一个标签,称其为 “myapp:1.0”。现在你想要将这个镜像移到生产环境。这个场景中,你应该使用 docker save 和 docker load 命令。具体操作如下:
在开发环境中,你运行 docker save -o myapp_1.0.tar myapp:1.0。这将创建一个名为 “myapp_1.0.tar” 的 tar 文件,其中包含了 “myapp:1.0” 镜像的所有层和元数据。
你可以将这个 tar 文件复制到你的生产环境,然后在那里运行 docker load -i myapp_1.0.tar。这将导入 “myapp:1.0” 镜像,你可以立即在生产环境中使用它。
2、导出容器(docker export)与导入容器(docker import)
这也是一对操作,用于处理 Docker 容器。docker export 命令可以将运行中的容器的文件系统导出为一个 tar 文件。然后,你可以使用 docker import 命令将这个 tar 文件作为一个新的镜像导入。例如:
导出:docker export <容器ID> > mycontainer.tar
导入:docker import mycontainer.tar
这种方式主要用于分享或迁移容器的当前状态。这不包括容器的历史或元数据,如环境变量,所以它常常用于对容器进行快照。
docker export 命令后直接跟容器的 ID 或名称
docker import 的参数包括输入的文件路径和名称,以及新镜像的名称和标签。例如docker import /path/to/import/mycontainer.tar newimage:tag
**
总的来说,如果你想要保存整个镜像,包括它的所有历史和标签,那么你应该使用 docker save 和 docker load命令。而如果你只是想要保存一个容器的当前状态,那么你应该使用 docker export 和 docker import 命令。
**
版权归原作者 ytusdc 所有, 如有侵权,请联系我们删除。