所谓的容器实际上是在父镜像的基础上创建了一个可读写的文件层级,所有的修改操作都在这个文件层级上进行,而父镜像并未受影响,如果读者需要根据这种修改创建一个新的本地镜像,有两种不同的方式,第一种方式:commit。
创建容器
首先,根据本地镜像运行一个容器,如下:
首先执行 docker images 命令,查看本地镜像。
根据本地镜像中的 nginx 镜像,创建一个名为 nginx 的容器,并启动。
将宿主机中一个名为 index.html 的文件拷贝到容器中。
访问容器,发现改变已经生效。
接下来再重新创建一个容器,名为 nginx2.
访问 nginx2 ,发现 nginx2 中默认的页面还是 nginx 的默认页面,并未发生改变。
commint 创建本地镜像
接下来,根据刚刚创建的第一个容器,创建一个本地镜像,如下:
参数 -m 是对创建的该镜像的一个简单描述。
–author 表示该镜像的作者。
ce1fe32739402 表示创建镜像所依据的容器的 id。
ss/nginx 则表示仓库名,ss 是名称空间,nginx 是镜像名。
v1 表示仓库的 tag。
创建完成后,通过 docker images 命令就可以查看到刚刚创建的镜像。
通过刚刚创建的镜像运行一个容器,访问该容器,发现 nginx 默认的首页已经发生改变。
这是我们通过 commint 方式创建本地镜像的方式,但是 commit 方式存在一些问题,比如不够透明化,无法重复,体积较大,为了解决这些问题,可以考虑使用 Dockerfile ,实际上,主流方案也是 Dockerfile。
Dockerfile
Dockerfile 就是一个普通的文本文件,其内包含了一条条的指令,每一条指令都会构建一层。先来看一个简单的例子。
首先在一个空白目录下创建一个名为 Dockerfile 的文件,内容如下:
FROM nginx 表示该镜像的构建,以已有的 nginx 镜像为基础,在该镜像的基础上构建。
MAINTAINER 指令用来声明创建镜像的作者信息以及邮箱信息,这个命令不是必须的。
RUN 指令用来修改镜像,算是使用比较频繁的一个指令了,该指令可以用来安装程序、安装库以及配置应用程序等,一个 RUN 指令执行会在当前镜像的基础上创建一个新的镜像层,接下来的指令将在这个新的镜像层上执行,RUN 语句有两种不同的形式:shell 格式和 exec 格式。本案例采用的 shell 格式,shell 格式就像 linux 命令一样,exec 格式则是一个 JSON 数组,将命令放到数组中即可。在使用 RUN 命令时,适当的时候可以将多个 RUN 命令合并成一个,这样可以避免在创建镜像时创建过多的层。
COPY 语句则是将当前目录下的 hello.html 文件拷贝到镜像中
文件创建完成后,执行如下命令进行构建:
-t 参数用来指定镜像的命名空间,仓库名以及 TAG 等信息。
最后面的 . 是指镜像构建上下文。
注意:Docker 采用了 C/S 架构,分为 Docker 客户端(Docker 可执行程序)与 Docker 守护进程,Docker 客户端通过命令行和 API 的形式与 Docker 守护进程进行通信,Docker 守护进程则提供 Docker 服务。因此,我们操作的各种 docker 命令实际上都是由 docker 客户端发送到 docker 守护进程上去执行。我们在构建一个镜像时,不可避免的需要将一些本地文件拷贝到镜像中,例如上文提到的 COPY 命令,用户在构建镜像时,需要指定构建镜像的上下文路径(即前文的 . ), docker build 在获得这个路径之后,会将路径下的所有内容打包,然后上传给 Docker 引擎。
然后根据这个镜像创建容器并启动,就可以看到之前的内容了。