godockerfilego-modulesgo-get

go build fails to find local dependencies on docker


I'm trying to create a dockerfile for my go server but it keeps failing as it does not recognize some local dependencies (they are modules on the code itself, not external dependencies).

example:

import (
    "<private-repo-url>/src/cmd/http-api/bootstrap" // this a local module that's part of the server
    "go.uber.org/fx"
)

func main() {
    fx.New(bootstrap.Module).Run()
}

Here's the error:

 => ERROR [7/7] RUN go build -a -o ./server                                                                                                                                                                        0.3s
------
 > [7/7] RUN go build -a -o ./server:
#10 0.295 server.go:4:2: no required module provides package <private-repo-url>/src/cmd/http-api/bootstrap; to add it:
#10 0.295       go get <private-repo-url>/src/cmd/http-api/bootstrap
------
executor failed running [/bin/sh -c go build -a -o ./server]: exit code: 1

Please note that this private-repo-url corresponds to this application's repository (it's not an external dependency).

Here's the Dockerfile

FROM golang:1.17

WORKDIR /balrog

# Copy dependency definitions and download them
ADD go.mod .
ADD go.sum .
RUN go mod download

# Build the binary
ADD ./src .
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
RUN go build -a -o ./server

#Run the server
CMD ["/server"]

And the mod.go file:

module <private-repo-url>

go 1.16

require (
    github.com/gin-gonic/gin v1.7.7
    github.com/google/uuid v1.3.0
    github.com/kelseyhightower/envconfig v1.4.0
    github.com/sirupsen/logrus v1.8.1
    go.uber.org/fx v1.15.0
)

I've read about GO111MODULE saying it should be on, and I also read that it's enabled by default from 1.17 (here).

Also according to the official docker image (in dockerhub) the right way is using go get and go install after copying all the files. This approach lead me to a slightly different problem which is that the docker can not access the repository (because it's private) and adding credentials to the docker is something I'd like to avoid.

I tried to play arround with the environment variable GOVCS setting it's value like:

ENV GOVCS=github.com:git,gitlab.com:off

But it still did fail with the same error.

Finally I tried with the replace, I figured that if I removed the from the local dependencies it would work, so I executed (inside the Dockerfile) this:

RUN go mod edit -replace <private-repo-url>=./

Again it did fail with:

 => ERROR [builder 10/10] RUN go build -a -o ./server                                                                                                                                                              0.3s
------                                                                                                                                                                                                                  
 > [builder 10/10] RUN go build -a -o ./server:                                                                                                                                                                         
#17 0.299 server.go:4:2: module <private-repo-url>/src provides package <private-repo-url>/src/cmd/http-api/bootstrap and is replaced but not required; to add it:
#17 0.299       go get <private-repo-url>/src
#17 0.299 server.go:5:2: no required module provides package go.uber.org/fx; to add it:
#17 0.299       go get go.uber.org/fx

Is there any way to prevent go builder/package installer to look for these files externally? As both go mod and go get + go install try to access this private repository and fail as they do not have access. But they should not try to access it on the first place as it's the application's repository... Or is that I'm doing something wrong (clearly or I wouldn't be here), missing something?


Solution

  • ADD ./src . - that copies the contents of src to the current folder, stripping away the src part.

    It should just be COPY . ./

    Also note that it's not recommended to have a src subfolder in your source tree - the folder that contains go.mod is already the source tree.