带有Docker的标准Go项目布局导致生成上下文问题

带有Docker的标准Go项目布局导致生成上下文问题,docker,go,google-cloud-build,Docker,Go,Google Cloud Build,我遵循两个似乎有冲突的指南 Go推荐一个/build目录,其使用如下 包装和持续集成 将您的云(AMI)、容器(Docker)、操作系统(deb、rpm、pkg)打包 /build/package目录中的配置和脚本 接下来,我有一个Dockerfile,它复制应用程序源代码,并使用go-get安装任何依赖项 #/build/Dockerfile 来自戈兰:阿尔卑斯山脉 #Alpine Linux包管理 运行apk更新 运行apk添加git 复制..//go/src/github.com/us

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

  • Go推荐一个
    /build
    目录,其使用如下

    包装和持续集成

    将您的云(AMI)、容器(Docker)、操作系统(deb、rpm、pkg)打包 /build/package目录中的配置和脚本

    接下来,我有一个Dockerfile,它复制应用程序源代码,并使用
    go-get
    安装任何依赖项

    #/build/Dockerfile
    来自戈兰:阿尔卑斯山脉
    #Alpine Linux包管理
    运行apk更新
    运行apk添加git
    复制..//go/src/github.com/username/repository
    #下载由导入路径命名的包及其名称
    #依赖关系。然后安装命名的软件包,如“go install”。
    #****不要在生产中这样做!使用自动售货机代替****
    运行go-get-v github.com/username/repository/foo-module
    #编译并安装由导入路径命名的包。
    运行go install github.com/username/repository/foo-module
    入口点[“/go/bin/foo模块”]
    
    接下来,我将上述Dockerfile放在
    /build

    由于Dockerfile现在位于
    /build
    目录中,因此我修改了
    COPY
    命令来复制父目录以查找应用程序源代码(
    COPY..//go/src/github.com/username/repository

    Docker
    build
    命令不是直接运行的,而是以

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

    #/build/cloudbuild.yaml
    步骤:
    -id:构建
    名称:“gcr.io/cloud builders/docker”
    目录:${u SOURCE}
    args:
    [
    “建造”,
    “--文件生成/Dockerfile”,
    ".",
    ]
    
    正如所料,这是失败的

    COPY failed: Forbidden path outside the build context: ../ ()
    
    建议使用
    --file
    标志,但是,这假定构建是从根上下文启动的。当使用谷歌的云构建时,构建从
    cloudbuild.yaml
    开始,它也位于
    /Build

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


    在遵循以下步骤的同时,实现这一点的正确方法是什么?

    这是一个相当长的问题,因此让我们集中精力解决遇到的问题:

    导致

    您不包括上下文之外的文件,docker不允许这样做。而是更改上下文以包含构建图像所需的文件,并在复制/添加命令中创建与该上下文相关的路径。请确保重新阅读,这些路径与Dockerfile位置无关

    因此,使用
    docker构建
    ,如果您有
    build/Dockerfile
    ,您将从父目录中构建:

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

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

    COPY . /go/src/github.com/username/repository
    
    如果由于某种原因,由于工具的原因,您无法从该父目录进行构建,则将上下文设置为具有相对路径的父文件夹:

    docker build -f Dockerfile ..
    

    非常感谢。这是有意义的,当应用到云构建时,意味着我只需添加
    。“
    作为运行
    gcr.io/Cloud builders/docker
    from
    cloudbuild.yaml
    时的最终
    arg
    。但是,此错误
    错误检查上下文:“/proc/6/fd/5”)未被.dockrignore”
    找到或排除,因此有些地方不正确。我的
    。dockerignore
    不会忽略任何生成files@Jack我猜你不想要
    在该生成器中,只需修复Dockerfile中的复制行,使其具有
    ,并坚持你在问题中提出的yaml。没有
    。“
    作为最后的
    参数
    ,Docker的上下文将限制为
    /build
    COPY../
    失败,原因是
    复制失败:生成上下文之外的禁止路径:
    。我想我误解了你的答案。@jack重新阅读了粗体部分,并将Dockerfile中的复制行修改为
    ,而不是
    。如果你告诉它使用
    build/Dockerfile
    你不是从
    build
    内部构建的,那么你所做的假设是不正确的。这很有效(谢谢)。我认为这与云构建有更多的关系,当从项目的根运行时,后面的
    意味着构建是在根目录的上下文中运行的:
    Cloud Build local--config=Build/cloudbuild.yaml--dryrun=false。
    。因此,当Docker
    build
    运行时(通过
    build/cloudbuild.yaml
    ),无需将Docker构建上下文指定为父级(
    ),在Docker
    build
    进入场景时,Cloud build已经完成了这项工作。
    COPY . /go/src/github.com/username/repository
    
    docker build -f Dockerfile ..