Docker 的标准 Go 项目布局导致构建上下文问题
Standard Go Project Layout with Docker causes build context problem
我正在遵循两个似乎冲突的指南
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.yaml
和 Dockerfile
保留在 /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 ..
我正在遵循两个似乎冲突的指南
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.yaml
和 Dockerfile
保留在 /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 ..