Standard Go Project Layout with Docker causes build context problem

  docker, go, google-cloud-build

I’m following two guides which appear to conflict

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

Go’s Standard Go Project Layout recommends a /build directory, the use of which is described as

Packaging and Continuous Integration.

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

Following Google Cloud Endpoints Sample for Go using gRPC, I have a Dockerfile which copies application source code and installs any dependencies with 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"]

Following Standard Go Project Layout I place the aforementioned Dockerfile in /build.

Since the Dockerfile is now in the /build directory, I modified the COPY command to copy the parent directory to find the application source code (COPY ../ /go/src/github.com/username/repository).

The Docker build command is not run directly, rather the build is started with Google Cloud Build

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

The cloudbuild.yaml file is really simple and just kicks off the Docker build. The --file flag points to build/Dockerfile since the Cloud Build command is started from the project root and not from /build)

# /build/cloudbuild.yaml

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

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

As expected, this fails

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

How to include files outside of Docker’s build context? suggests using the --file flag, however, this assumes the build is started from the root context. When using Google’s Cloud Build, the build is started from a cloudbuild.yaml, which also located in /build for obvious reasons.

I could just place the Docker file in the root of my go module, but I would like to follow best practices where possible.

What is the correct way to achieve this while following the Standard Go Project Layout?

Source: Docker Questions

LEAVE A COMMENT