使用“gcloud build”时 Dockerfile COPY 命令缺少单个文件

Wil*_*Evo 4 python docker google-cloud-build

我遇到了一个令人难以置信的令人沮丧的问题,Dockerfile 中的 COPY 命令成功复制了除一个之外的所有应用程序文件。我没有 .dockerignore 文件,所以我知道该文件不会以这种方式从构建中排除。

\n

注意:我确实有一个.gitignore排除file2.json我不想版本的情况。但正如您将在下面看到的,我是从本地文件夹构建的,而不是从克隆/签出远程构建的,所以我不明白为什么.gitignore在这种情况下会影响 docker 构建。

\n

下面是我的目录的样子:

\n
$ tree -a -I .git app\napp\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 data\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file1.txt\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file2.json\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file3.txt\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 file4.yml\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 somefile2.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 somefile.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Dockerfile\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .gitignore\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 requirements.txt\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 setup.py\n
Run Code Online (Sandbox Code Playgroud)\n

这就是我的 Dockerfile 中的内容

\n
FROM ubuntu:18.04\nFROM python:3.7\n  \nCOPY . /app\n  \nRUN cp app/app/data/file2.json ~/.somenewhiddendirectory\n   \nRUN pip install app/.\n   \nENTRYPOINT ["python", "app/app/somefile.py"]\n
Run Code Online (Sandbox Code Playgroud)\n

由于某种原因,在通话file2.json过程中没有被复制,当我尝试在其他地方复制COPY . /app时,我收到错误。cp我已经完成了类似的调用RUN ls app/app/data/,除此之外的所有文件都file2.json在那里。我检查了文件权限并确保它们与所有其他文件相同。我尝试直接执行COPY该文件,但这会导致错误,因为 Docker 说该文件不存在。

\n

在我的系统上,该文件存在,我可以使用 来查看它ls,并且可以查看cat其内容。我已经尝试过确保图像中的上下文完全位于我的应用程序的根目录中,并且正如我所说,除了 json 文件之外,所有文件都已正确复制。我怎么也想不通为什么 Docker 讨厌这个文件。

\n

对于一些添加的上下文,我使用 Google 的云构建来构建图像,yaml 配置如下所示:

\n
steps:\n  - name: gcr.io/cloud-builders/docker\n    id: base-image-build\n    waitFor: [-]\n    args:\n      - build\n      - .\n      - -t\n      - us.gcr.io/${PROJECT_ID}/base/${BRANCH_NAME}:${SHORT_SHA}\n        \nimages:\n  - us.gcr.io/${PROJECT_ID}/base/${BRANCH_NAME}:${SHORT_SHA}\n
Run Code Online (Sandbox Code Playgroud)\n

我正在执行的命令如下所示:

\n
gcloud builds submit --config=cloudbuild.yaml . \\\n  --substitutions=SHORT_SHA="$(git rev-parse --short HEAD)",BRANCH_NAME="$(git rev-parse --abbrev-ref HEAD)"\n
Run Code Online (Sandbox Code Playgroud)\n

Zei*_*tor 5

免责声明:我从未使用过谷歌的云构建,所以我的答案仅基于阅读理论。


我不明白为什么.gitignore在这种情况下会影响 docker 构建

确实,docker build它本身并不关心你的.gitignore文件。但你是通过谷歌的云构建进行构建,这是一个完全不同的故事。

引用命令中源规范的文档gcloud build

[SOURCE]
要构建的源的位置。该位置可以是本地磁盘上的目录或 Google Cloud Storage 中的 gzip 压缩存档文件 (.tar.gz)。如果源是本地目录,此命令会跳过--ignore-file. 如果--ignore-file未指定,则使用.gcloudignore文件。如果.gcloudignore文件不存在,但.gitignore本地源目录中存在文件,gcloud 将使用生成的与.gcloudignore您的文件兼容的 Git 兼容文件.gitignore。全局.gitignore不被尊重。有关 的更多信息.gcloudignore,请参阅gcloud topic gcloudignore

因此,在您给定的情况下,即使是从本地目录构建,您的文件也将被忽略。此时我看到有两个选项可以解决此问题:

  1. 删除文件中的条目,.gitignore以便默认 gcloud 机制在构建过程中不会忽略它
  2. 提供一个--ignore-file或一个默认值.gcloudignore,它实际上重新包含版本控制时忽略的本地文件。

我个人会选择第二个选项,使用一些超级简单的文件,例如以下文件(根据相关文档.gcloudignore制作)

.git
.gcloudignore
.gitignore
Run Code Online (Sandbox Code Playgroud)