使用“gcloud build”时,Dockerfile COPY 命令缺少单个文件
Dockerfile COPY command is missing a single file when using `gcloud build`
我 运行 遇到了一个令人难以置信的令人沮丧的问题,我的 Docker 文件中的 COPY 命令成功复制了我的所有应用程序文件,只有一个除外。我没有 .dockerignore 文件,所以我知道该文件不会以这种方式从构建中排除。
注意:我确实有一个 .gitignore
,它不包括我不想版本化的 file2.json
。但是正如您将在下面看到的,我是从我的本地文件夹构建的,而不是从 clone/checkout 远程构建的,所以我不明白为什么 .gitignore
在这种情况下会影响 docker 构建。
下面是我的目录:
$ tree -a -I .git app
app
├── app
│ ├── data
│ │ ├── file1.txt
│ │ ├── file2.json
│ │ ├── file3.txt
│ │ └── file4.yml
│ ├── somefile2.py
│ └── somefile.py
├── Dockerfile
├── .gitignore
├── requirements.txt
└── setup.py
这就是我的 Docker 文件中的内容
FROM ubuntu:18.04
FROM python:3.7
COPY . /app
RUN cp app/app/data/file2.json ~/.somenewhiddendirectory
RUN pip install app/.
ENTRYPOINT ["python", "app/app/somefile.py"]
出于某种原因,file2.json
在 COPY . /app
调用期间未被复制,当我尝试在其他地方 cp
时出现错误。我做了一个像 RUN ls app/app/data/
这样的调用,除了 file2.json
之外的所有文件都在那里。我检查了文件权限并确保它们与所有其他文件相同。我试过直接 COPY
那个文件,结果出错,因为 Docker 说那个文件不存在。
在我的系统上,该文件存在,我可以使用 ls
查看它,并且我可以 cat
它的内容。我一直在努力确保图像中的上下文完全位于我的应用程序的根目录中,就像我说的那样,除了 json 文件外,所有文件都已正确复制。我一辈子都想不通为什么 Docker 讨厌这个文件。
对于一些添加的上下文,我正在使用 Google 的云构建来构建图像,yaml 配置如下所示:
steps:
- name: gcr.io/cloud-builders/docker
id: base-image-build
waitFor: [-]
args:
- build
- .
- -t
- us.gcr.io/${PROJECT_ID}/base/${BRANCH_NAME}:${SHORT_SHA}
images:
- us.gcr.io/${PROJECT_ID}/base/${BRANCH_NAME}:${SHORT_SHA}
我正在执行的命令如下所示:
gcloud builds submit --config=cloudbuild.yaml . \
--substitutions=SHORT_SHA="$(git rev-parse --short HEAD)",BRANCH_NAME="$(git rev-parse --abbrev-ref HEAD)"
免责声明:我从未使用过Google的云构建,所以我的回答仅基于阅读理论。
I don't see why .gitignore
would influence the docker build in this case
的确,docker build
本身并不关心你的.gitignore
文件。但是您正在通过 Google 的云构建进行构建,这是一个完全不同的故事。
在 gcloud build
命令中引用 documentation 作为源规范:
[SOURCE]
The location of the source to build. The location can be a directory on a local disk or a gzipped archive file (.tar.gz) in Google Cloud Storage. If the source is a local directory, this command skips the files specified in the --ignore-file
. If --ignore-file
is not specified, use .gcloudignore
file. If a .gcloudignore
file is absent and a .gitignore
file is present in the local source directory, gcloud will use a generated Git-compatible .gcloudignore
file that respects your .gitignore
files. The global .gitignore
is not respected. For more information on .gcloudignore
, see gcloud topic gcloudignore
所以在你给定的情况下,即使从你的本地目录构建,你的文件也会被忽略。此时我看到 2 个解决此问题的选项:
- 删除
.gitignore
中的文件条目,这样默认的 gcloud 机制就不会在构建过程中忽略它
- 提供
--ignore-file
或默认值 .gcloudignore
实际上 re-includes 版本控制忽略的本地文件。
我个人会选择第二个选项,使用一些超级简单的东西,比如下面的 .gcloudignore
文件(根据 relevant documentation 制作)
.git
.gcloudignore
.gitignore
我 运行 遇到了一个令人难以置信的令人沮丧的问题,我的 Docker 文件中的 COPY 命令成功复制了我的所有应用程序文件,只有一个除外。我没有 .dockerignore 文件,所以我知道该文件不会以这种方式从构建中排除。
注意:我确实有一个 .gitignore
,它不包括我不想版本化的 file2.json
。但是正如您将在下面看到的,我是从我的本地文件夹构建的,而不是从 clone/checkout 远程构建的,所以我不明白为什么 .gitignore
在这种情况下会影响 docker 构建。
下面是我的目录:
$ tree -a -I .git app
app
├── app
│ ├── data
│ │ ├── file1.txt
│ │ ├── file2.json
│ │ ├── file3.txt
│ │ └── file4.yml
│ ├── somefile2.py
│ └── somefile.py
├── Dockerfile
├── .gitignore
├── requirements.txt
└── setup.py
这就是我的 Docker 文件中的内容
FROM ubuntu:18.04
FROM python:3.7
COPY . /app
RUN cp app/app/data/file2.json ~/.somenewhiddendirectory
RUN pip install app/.
ENTRYPOINT ["python", "app/app/somefile.py"]
出于某种原因,file2.json
在 COPY . /app
调用期间未被复制,当我尝试在其他地方 cp
时出现错误。我做了一个像 RUN ls app/app/data/
这样的调用,除了 file2.json
之外的所有文件都在那里。我检查了文件权限并确保它们与所有其他文件相同。我试过直接 COPY
那个文件,结果出错,因为 Docker 说那个文件不存在。
在我的系统上,该文件存在,我可以使用 ls
查看它,并且我可以 cat
它的内容。我一直在努力确保图像中的上下文完全位于我的应用程序的根目录中,就像我说的那样,除了 json 文件外,所有文件都已正确复制。我一辈子都想不通为什么 Docker 讨厌这个文件。
对于一些添加的上下文,我正在使用 Google 的云构建来构建图像,yaml 配置如下所示:
steps:
- name: gcr.io/cloud-builders/docker
id: base-image-build
waitFor: [-]
args:
- build
- .
- -t
- us.gcr.io/${PROJECT_ID}/base/${BRANCH_NAME}:${SHORT_SHA}
images:
- us.gcr.io/${PROJECT_ID}/base/${BRANCH_NAME}:${SHORT_SHA}
我正在执行的命令如下所示:
gcloud builds submit --config=cloudbuild.yaml . \
--substitutions=SHORT_SHA="$(git rev-parse --short HEAD)",BRANCH_NAME="$(git rev-parse --abbrev-ref HEAD)"
免责声明:我从未使用过Google的云构建,所以我的回答仅基于阅读理论。
I don't see why
.gitignore
would influence the docker build in this case
的确,docker build
本身并不关心你的.gitignore
文件。但是您正在通过 Google 的云构建进行构建,这是一个完全不同的故事。
在 gcloud build
命令中引用 documentation 作为源规范:
[SOURCE]
The location of the source to build. The location can be a directory on a local disk or a gzipped archive file (.tar.gz) in Google Cloud Storage. If the source is a local directory, this command skips the files specified in the--ignore-file
. If--ignore-file
is not specified, use.gcloudignore
file. If a.gcloudignore
file is absent and a.gitignore
file is present in the local source directory, gcloud will use a generated Git-compatible.gcloudignore
file that respects your.gitignore
files. The global.gitignore
is not respected. For more information on.gcloudignore
, seegcloud topic gcloudignore
所以在你给定的情况下,即使从你的本地目录构建,你的文件也会被忽略。此时我看到 2 个解决此问题的选项:
- 删除
.gitignore
中的文件条目,这样默认的 gcloud 机制就不会在构建过程中忽略它 - 提供
--ignore-file
或默认值.gcloudignore
实际上 re-includes 版本控制忽略的本地文件。
我个人会选择第二个选项,使用一些超级简单的东西,比如下面的 .gcloudignore
文件(根据 relevant documentation 制作)
.git
.gcloudignore
.gitignore