- 在 Docker-Dockerfile入门 - 1 中我们提到了build中
.
的作用,当时说的是代表当前目录其实说的并不准确具体,我们今天来说一下这个问题,如果理解不对请指正 -
之前提到了Docker context ,那么这到底是个什么东西,有什么作用,在 <>中大致意思是这样解释的:
表面在本机执行docker build,但是其实是有一个docker daemon在运行的,所以你所执行的命令与产生的结果都是与docker服务交互后的结果,这是一种C/S架构的东西,所以构建其实并非是在本地执行,而是在服务端完成的
- 所以我们指定了
.
这个上下文路径后,docker会根据这个上下文路径来去构建镜像,我们来测试一下 -
首先最简单的构建操作如下
[qidai@qidai-pc cc]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 881bd08c0b08 9 days ago 109MB ubuntu latest 47b19964fb50 5 weeks ago 88.1MB centos latest 1e1148e4cc2c 3 months ago 202MB [qidai@qidai-pc cc]$ tree . . └── file 0 directories, 1 file [qidai@qidai-pc cc]$ docker build -t x:x -f file . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM nginx ---> 881bd08c0b08 Step 2/2 : RUN touch succ / ---> Running in a57757a928f2 Removing intermediate container a57757a928f2 ---> 8ce68f7c4572 Successfully built 8ce68f7c4572 Successfully tagged x:x
-
tree
:linux命令,列出当前目录结构 - 同时我们也知道了用来构建的文件不一定是叫Dockerfile,Dockerfile只是docker的默认文件名而已
-
- 刚才为docker指定了上下文,为
.
,这时候docker知道这个路径后, docker会将这个目录下的所有东西打包上传到服务端,然后进行解析构建 - 现在我们全部用错误的构建来说明docker的context路径问题,
-
先说一下
-f
参数的问题-
构建如下
[qidai@qidai-pc cc]$ cd .. [qidai@qidai-pc test]$ tree . . └── cc └── file 1 directory, 1 file [qidai@qidai-pc test]$ docker build -t s:s -f cc/file . Sending build context to Docker daemon 2.56kB Step 1/2 : FROM nginx ---> 881bd08c0b08 Step 2/2 : RUN touch succ / ---> Running in ef1fa8e3bb07 Removing intermediate container ef1fa8e3bb07 ---> 416623a1c3f7 Successfully built 416623a1c3f7 Successfully tagged s:s
-
更改构建路径
[qidai@qidai-pc test]$ docker build -f s:s -f cc/nofile . unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /run/media/qidai/_yingpan/test/cc/nofile: no such file or directory [qidai@qidai-pc test]$ docker build -t s:s -f cc . Sending build context to Docker daemon 2.56kB Error response from daemon: unexpected error reading Dockerfile: read /var/lib/docker/tmp/docker-builder684771877/cc: is a directory
- 如上我们就很清楚了,首先
-f
参数指定的Dockerfile的具体路径在本地是必须存在的,这个无可质疑,如果本地都不存在那么本地的机器就会跟你爆出不存在的错误,其次那就是本地存在,而且本地不报错了,这就通过过了第一步的本地审查,所以就打包上传到docker服务器,在服务器中解析,发现cc并不是具体的构建文件的路径,所以会给你再次报错,我们从两次的报错中的路径也可以看出来,/run/media
是本地检查,而/var/lib/tmp/...
是docker的检查
-
-
然后我们在说一下后面的
.
的问题-
构建如下
[qidai@qidai-pc cc]$ cd .. [qidai@qidai-pc test]$ tree . . └── cc └── file 1 directory, 1 file [qidai@qidai-pc test]$ docker build -t s:s -f cc/file . Sending build context to Docker daemon 2.56kB Step 1/2 : FROM nginx ---> 881bd08c0b08 Step 2/2 : RUN touch succ / ---> Running in ef1fa8e3bb07 Removing intermediate container ef1fa8e3bb07 ---> 416623a1c3f7 Successfully built 416623a1c3f7 Successfully tagged s:s
-
更改构建路径
[qidai@qidai-pc test]$ docker build -t s:s -f cc/file cc Sending build context to Docker daemon 2.048kB Step 1/2 : FROM nginx ---> 881bd08c0b08 Step 2/2 : RUN touch succ / ---> Using cache ---> 416623a1c3f7 Successfully built 416623a1c3f7 Successfully tagged s:s [qidai@qidai-pc test]$ docker build -t s:s -f cc/ cc Sending build context to Docker daemon 2.048kB Error response from daemon: unexpected error reading Dockerfile: read /var/lib/docker/tmp/docker-builder657763113: is a directory
- 如上,我们给出的context路径其实是上传后的服务器的相对路径,当给出的context为
cc
的时候,那么docker就会在context_path/cc/
下去找构建文件,这时候会根据-f
参数去找构建文件,然后开始构建, 而上面第二次构建就不行了,依旧传入的context为cc
,然后根据-f
找构建文件,但是-f
并没有具体指定文件,所以构建失败 -
当然也可以指定本机的绝对路径为docker的context路径,如下
[qidai@qidai-pc test]$ docker build -t s:s -f cc/file . Sending build context to Docker daemon 2.56kB Step 1/1 : FROM nginx ---> 881bd08c0b08 Successfully built 881bd08c0b08 Successfully tagged s:s [qidai@qidai-pc test]$ pwd /run/media/qidai/_yingpan/test [qidai@qidai-pc test]$ docker build -t s:s -f cc/file /run/media/qidai/_yingpan/test Sending build context to Docker daemon 2.56kB Step 1/1 : FROM nginx ---> 881bd08c0b08 Successfully built 881bd08c0b08 Successfully tagged s:s
-
-
知道了路径问题后,我们再来看一下Dockerfile中的文件问题,拿
COPY
指令来说-
构建文件内容如下
FROM nginx COPY cc/file /file.bak
-
构建过程
[qidai@qidai-pc test]$ tree . . └── cc └── file 1 directory, 1 file [qidai@qidai-pc test]$ docker build -t a:a -f cc/file . Sending build context to Docker daemon 2.56kB Step 1/2 : FROM nginx ---> 881bd08c0b08 Step 2/2 : COPY cc/file /file.bak ---> 9b5b8bcc0246 Successfully built 9b5b8bcc0246 Successfully tagged a:a
-
如果我们将
COPY
的源目的地址改一下呢 ?,如下[qidai@qidai-pc test]$ touch /home/qidai/tempFile #本机新建一个文件 [qidai@qidai-pc test]$ cat cc/file FROM nginx COPY /home/qidai/tempFile /file.bak #想法是将本机内的指定文件复制到容器 [qidai@qidai-pc test]$ docker build -t s:s -f cc/file . Sending build context to Docker daemon 2.56kB Step 1/2 : FROM nginx ---> 881bd08c0b08 Step 2/2 : COPY /home/qidai/tempFile /file.bak COPY failed: stat /var/lib/docker/tmp/docker-builder527470065/home/qidai/tempFile: no such file or directory
- 如上我们就可以看到了,构建文件中也是应用的是context的相对路径,所以想将我们的文件复制到容器内只能是将文件放入我们指定的context目录下(
COPY
和ADD
命令不能拷贝上下文之外的本地文件)
-
- 下面是我自己画的一张图,更直观的展示了Docker命令和目录路径之间的关联,如果有异议请评论指出,谢谢