I am trying to build a Dockerfile of my Golang application which includes delve debugger - I want to debug my Golang application in Docker container.
When I try to build my Docker I consistently go error below:
Step 5/9 : RUN go build -gcflags "all=-N -l" -o ./feedme
---> Running in a0579ec8a85c
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
The command go build runs well on my local folder(refer tree commands below)
go build -gcflags "all=-N -l" -o ./feedme
Here are my folder structure and files:
tree
.
├── Dockerfile
├── Makefile
├── docker-compose.yml
└── parsedata-xml-fp.go
0 directories, 4 files
Single application file parsedata-xml-fp.go (I will dismiss it , since I think the error has nothing to do with it)
My Dockerfile :
FROM golang:1.17 AS build
WORKDIR /
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -gcflags "all=-N -l" -o ./feedme
EXPOSE 8000 2345
COPY --from=build /go/bin/dlv /dlv
COPY --from=build /feedme /feedme
CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"]
Any idea why this error occur and how can I fix it ? I searched for it and tried to set some env variable:
1) RUN GO111MODULE=off/on
2) RUN CGO_ENABLED=0
Seems like none of them works
Edit: I modified my Dockerfile added 'go mod init feedme' and I got some new error:
New Dockerfile
FROM golang:1.17 AS build
WORKDIR /
COPY . .
RUN go mod init feedme
RUN go mod tidy
RUN GO111MODULE=auto
RUN go build -gcflags="all=-N -l" -o /feedme
EXPOSE 8000 2345
COPY --from=build /go/bin/dlv /dlv
COPY --from=build /feedme /feedme
CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"]
Error message is :invalid from flag value build: pull access denied for build, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
docker build --network=host -f Dockerfile -t fdebug .
Sending build context to Docker daemon 7.056MB
Step 1/10 : FROM golang:1.17 AS build
---> 57ac3b44728a
Step 2/10 : WORKDIR /
---> Using cache
---> 59325512e59b
Step 3/10 : COPY . .
---> Using cache
---> 8e744ca7fb7f
Step 4/10 : RUN go mod init feedme
---> Using cache
---> c9a5fd57769c
Step 5/10 : RUN go mod tidy
---> Using cache
---> cbc9d9ca142b
Step 6/10 : RUN go build -gcflags="all=-N -l" -o /feedme
---> Using cache
---> 38e79d1b85c9
Step 7/10 : EXPOSE 8000 2345
---> Using cache
---> fd4950bcf8c9
Step 8/10 : COPY --from=build /go/bin/dlv /dlv
invalid from flag value build: pull access denied for build, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
The credit goes to @TheFool, thank you for the documents and guidance. I read official Docker documents : docs.docker.com/language/golang/ and also multi staging build blog
Here is the solution I came up with and I can boot my Go application container locally
Dockerfile of mine:
FROM golang:1.17 AS build
WORKDIR /
COPY . .
RUN go mod init feedme
RUN go mod tidy
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -gcflags="all=-N -l" -o /feedme
RUN echo $(ls /go/bin)
FROM gcr.io/distroless/base-debian10
WORKDIR /
EXPOSE 2345
COPY --from=build /go/bin/dlv /dlv
COPY --from=build /feedme ~/feedme
#ENTRYPOINT [ "/dlv" ]
CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "~/feedme"]
I boot my container using :
docker run -p 2345:2345 <docker image ID>
Then I tried to curl to it , it does have response:
curl http://localhost:2345
[Edit] Per suggestion from TheFool, I used my local copy of go.mod and go.sum directly in my container. COPY it from my local workspace to container,(rather than generate go.mod in the container) to avoid any unexpected surprise in the future:
Here is the improved version of Dockerfile
FROM golang:1.17 AS build
WORKDIR /
COPY go/app/parsedata-xml-fp.go .
COPY go.mod . # just copy local go.mod
COPY go.sum .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -gcflags="all=-N -l" -o /feedme
RUN echo $(ls /go/bin)
FROM gcr.io/distroless/base-debian10
WORKDIR /
EXPOSE 2345
COPY --from=build /go/bin/dlv /dlv
COPY --from=build /feedme ~/feedme
#ENTRYPOINT [ "/dlv" ]
CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "~/feedme"]