16
votes

I have a monorepo that has holds various Go services and libraries. It has a structure of

monorepo
 services 
  service-a 
   - Dockerfile
go.mod
go.sum

My go.mod resides in the root of the monorepo and the services use the dependencies stated in the go.mod file.

I build the Docker image with

docker build -t some:tag ./services/service-a/

When I try to build my Docker image from the root of the monorepo with the above docker command I get the following error.

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

Below is my Dockerfile

FROM golang:1.14.1-alpine3.11

RUN apk add --no-cache ca-certificates git

# Enable Go Modules
ENV GO111MODULE=on

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go mod and sum files
COPY ../../go.mod go.sum ./

RUN go mod download

COPY . .

RUN CGO_ENABLED=0 go build -o service-a

ENTRYPOINT ["/app/service-a"]

Is there something I have to do to be able to add files into my Docker image that aren't in the current directory without having to have a separate go.mod and go.sum in each service within the monorepo?

2

2 Answers

24
votes

Docker only allows adding files to the image from the context, which is by default the directory containing the Dockerfile. You can specify a different context when you build, but again, it won't let you include files outside that context:

docker build -f ./services/service-a/Dockerfile .

This should use the current directory as the context.

Alternatively, you can create a temp directory, copy all the artifacts there and use that as the build context. This can be automated by a makefile or build script.

0
votes

You can build and manage your docker containers using docker-compose, then this problem can be solved with the help context directive, for example:

project_folder  
├─── src  
│    └── folder1
│        └── folder2
│            └── Dockerfile
├── docker-compose.yaml   
└── copied_file.ext 

docker-compose.yaml

version: '3'
services:

    your_service_name:
        build:
            context: ./ #project_folder for this case
            dockerfile: ./src/folder1/folder2/Dockefile

Dockerfile

FROM xxx
COPY copied_file.ext /target_folder/

build or rebuild services:

docker-compose build

run a one-off command on a service:

docker-compose run your_service_name <command> [arguments]