最近被 Docker 的当前目录位置整得有些混乱,特地在此整理一下。
执行docker build命令的时候,需要传入一个 positional 参数,这个参数就是 context。举个例子,假如当前 shell 的目录是/root,我们执行以下命令:
docker build -f dockerfiles/a.Dockerfile dockerfiles
那么,构建过程中 Dockerfile 的 context 就是/root/dockerfiles。Context 的值会有以下三个影响:
.所代表的目录。COPY命令只能访问到 context 下的文件。这里有一个坑点:假如我们将 context 设置成/root,那么在 Dockerfile 中访问../tmp/a.txt的时候不会立刻报错,而是会访问/root/tmp/a.txt。foo.Dockerfile,那么对应的.dockerignore 文件名就是foo.Dockerfile.dockerignore,但是这种.dockerignore 是在 Dockerfile 文件所在的目录下查找,而非 context 目录。举例来说,假如 Dockerfile 是/root/dockerfiles/a.Dockerfile,context 设置为/root,那么生效的.dockerignore 路径就是/root/.dockerignore以及/root/dockerfiles/a.Dockerfile.dockerignore。Docker Compose 的当前目录是docker-compose.yml配置文件所在的目录,而不是执行docker compose命令时 shell 的当前目录,并且没有选项可以更改它。
但是这里又有一个坑点:在 Docker Compose 的配置文件中可以指定从本地的 Dockerfile 构建镜像,例如:
services:
service-0:
build:
context: ..
dockerfile: docker/Dockerfile
这里面的context选项是相对于docker-compose.yml所在目录的,但是dockerfile选项却是相对于context的。也就是说,假如上面的配置文件位于/foo/docker-compose.yml,那么context就是/,而 Dockerfile 应该位于/docker/Dockerfile。