【问题标题】:Dockerfile COPY command is missing a single file when using `gcloud build`使用“gcloud build”时,Dockerfile COPY 命令缺少单个文件
【发布时间】:2022-01-21 21:57:30
【问题描述】:

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

注意:我确实有一个.gitignore,它不包括我不想版本化的file2.json。但正如您将在下面看到的那样,我是从本地文件夹构建的,而不是从克隆/签出远程构建,所以我不明白为什么 .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

这就是我的 Dockerfile 中的样子

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.jsonCOPY . /app 调用期间没有被复制,当我尝试在其他地方cp 时出现错误。我打了一个像RUN ls app/app/data/ 这样的电话,除了file2.json 之外的所有文件都在那里。我检查了文件权限并确保它们与所有其他文件相同。我尝试直接对该文件执行COPY,这会导致错误,因为 Docker 说该文件不存在。

在我的系统上,该文件存在,我可以用ls 看到它,我可以cat 它的内容。我一直在尝试确保图像中的上下文完全位于我的应用程序的根目录中,就像我说的那样,除了那个 json 文件之外,所有文件都被正确复制。我一辈子都想不通为什么 Docker 讨厌这个文件。

对于一些附加的上下文,我使用谷歌的云构建来构建图像,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)"

【问题讨论】:

  • 你检查file2.json的权限没有区别吗?什么给出了命令ls -l
  • 顺便说一句,你的 Dockerfile 的第一个 FROM 命令是无关紧要的(拇指规则:一个 Dockerfile 应该只包含 一个 FROM,除非你依赖于multi-stage builds(这不是你的情况))
  • 是的,我做到了。该文件的权限是-rw-rw-r--,就像同一目录中的其他文件一样
  • 您是否尝试将app/app/data/file2.json 替换为/app/app/data/file2.json。以防万一你在错误的目录中。
  • @FrankYellin 是的,但ls 再次显示除该文件之外的所有其他文件,因此我认为该文件一开始就没有被复制,并且由于ls 命令有效,我确定我指的是正确的地方。

标签: python docker google-cloud-build


【解决方案1】:

免责声明:我从未使用过 Google 的云构建,因此我的回答仅基于阅读理论。


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

确实,docker build 本身并不关心您的.gitignore 文件。但您是通过 Google 的云构建构建的,这是完全不同的故事。

gcloud build 命令中引用documentation 作为源规范:

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

因此,在您给定的情况下,即使是从本地目录构建,您的文件也会被忽略。在这一点上,我看到了解决此问题的 2 个选项:

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

我个人会选择第二个选项,使用超级简单的东西,例如以下 .gcloudignore 文件(由 relevant documentation 制作)

.git
.gcloudignore
.gitignore

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 2019-07-23
    • 2019-12-10
    • 2021-07-17
    • 2018-12-25
    • 2021-01-01
    • 2020-09-20
    • 1970-01-01
    相关资源
    最近更新 更多