Docker 的标准 Go 项目布局导致构建上下文问题

Standard Go Project Layout with Docker causes build context problem

我正在遵循两个似乎冲突的指南

  1. Standard Go Project Layout
  2. Google Cloud Endpoints Sample for Go using gRPC

Go的Standard Go Project Layout推荐了一个/build目录,其使用描述

Packaging and Continuous Integration.

Put your cloud (AMI), container (Docker), OS (deb, rpm, pkg) package configurations and scripts in the /build/package directory.

Google Cloud Endpoints Sample for Go using gRPC 之后,我有一个 Docker 文件,它复制应用程序源代码并使用 go get 安装任何依赖项。

# /build/Dockerfile

FROM golang:alpine

# Alpine Linux package management
RUN apk update
RUN apk add git

COPY ../ /go/src/github.com/username/repository

# Downloads the packages named by the import paths, along with their
# dependencies. It then installs the named packages, like 'go install'.
# ****Don't do this in production! Use vendoring instead.****
RUN go get -v github.com/username/repository/foo-module

# Compiles and installs the packages named by the import paths.
RUN go install github.com/username/repository/foo-module

ENTRYPOINT ["/go/bin/foo-module"]

Standard Go Project Layout 之后,我将上述 Docker 文件放在 /build.

由于Docker文件现在在/build目录下,我修改COPY命令复制parent目录找到应用程序源代码 (COPY ../ /go/src/github.com/username/repository).

Docker build 命令 不是 运行 直接 ,而是从 Google Cloud Build[=41 开始构建=]

cloud-build-local --config=build/cloudbuild.yaml .

cloudbuild.yaml 文件 非常简单 并且只是 Docker 构建的开始。 --file 标志指向 build/Dockerfile,因为 Cloud Build 命令是从项目根目录启动的,而不是从 /build)

# /build/cloudbuild.yaml

steps:
    - id: Build
      name: "gcr.io/cloud-builders/docker"

      dir: ${_SOURCE}
      args:
        [
            "build",
            "--file build/Dockerfile",
            ".",
        ]

不出所料,这失败了

COPY failed: Forbidden path outside the build context: ../ ()

How to include files outside of Docker's build context? 建议使用 --file 标志,但是,这假定构建是从根上下文开始的。使用 Google 的 Cloud Build 时,构建从 cloudbuild.yaml 开始,它也位于 /build.

我可以将 Docker 文件放在我的 go 模块的根目录中,但我想尽可能遵循最佳实践并将 cloudbuild.yamlDockerfile 保留在 /build.

遵循 Standard Go Project Layout 的正确方法是什么?

这个问题比较长,所以让我们关注遇到的问题:

COPY ../ /go/src/github.com/username/repository

这导致

COPY failed: Forbidden path outside the build context: ../ ()

您不能在上下文之外包含文件,docker 不允许这样做。相反,您可以更改上下文以包含构建图像所需的文件,并使 COPY/ADD 命令中的路径相对于该上下文。请务必重新阅读,这些路径与 Dockerfile 位置无关

所以对于 docker build,如果你有 build/Dockerfile,你将从父目录构建:

docker build -f build/Dockerfile .

尾随的点是构建上下文的路径,它被发送到 docker 引擎以执行构建。它不直接在客户端访问文件,这就是为什么您不能从上下文外部包含文件(另外您不希望恶意 Dockerfile 从构建服务器提取数据)。

然后在 Dockerfile 中定义相对于该上下文的路径:

COPY . /go/src/github.com/username/repository

如果由于某种原因您无法从该父目录构建,因为工具,则使上下文成为具有相对路径的父文件夹:

docker build -f Dockerfile ..