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

标签 docker go google-cloud-build

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

  • Standard Go Project Layout
  • Google Cloud Endpoints Sample for Go using gRPC

  • 围棋Standard Go Project Layout推荐 /build目录,使用的是described作为

    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 ,我有一个 Dockerfile,它复制应用程序源代码并使用 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我将前面提到的 Dockerfile 放在 /build .
    由于 Dockerfile 现在位于 /build目录,我修改了COPY命令复制 家长 目录以查找应用程序源代码 (COPY ../ /go/src/github.com/username/repository)。
    docker build命令是 不直接运行 ,而是从 Google Cloud Build 开始构建
    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 引擎以执行构建。它不会直接在客户端访问文件,这就是为什么你不能包含来自上下文之外的文件(另外你不希望恶意 Dockerfiles 从构建服务器中提取数据)。
    然后在 Dockerfile 中,您将定义相对于该上下文的路径:
    COPY . /go/src/github.com/username/repository
    
    如果由于某种原因由于工具的原因您无法从该父目录构建,则将上下文设为具有相对路径的父文件夹:
    docker build -f Dockerfile ..
    

    关于docker - 使用 Docker 的标准 Go 项目布局导致构建上下文问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63970047/

    相关文章:

    docker - 如何在 Cloud Run 中以特权方式运行 docker 容器

    java - 如何修复MAVEN中的 "Either artifact or artifactItems is required"错误

    google-cloud-build - 从失败的构建中存储工件

    c# - 找不到应用程序依赖项 list 中指定的程序集 :

    image - Golang io.Reader 问题与 jpeg.Decode 返回 EOF

    go - 从 time.Now() 开始接收字符串的简单方法

    golang Gin : router like django?

    macos - 在 macOS 上意外使用了端口 80,结果为 "It works"

    Docker 删除 <none> 标记图像

    linux - docker 能否解决 C 共享库不匹配的问题?