1

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
Jia
  • 2,417
  • 1
  • 15
  • 25
  • I would suggest using go mod as its by now more or less the standard to develop go programs. – The Fool Jun 04 '22 at 14:27
  • @TheFool could you be more specific, which part of my Dockerfile or anything I need to change to use 'go mod' ? I am very new to Go - a beginner. – Jia Jun 04 '22 at 14:29
  • `go mod init` to generate a starter `go.mod` & try again – colm.anseo Jun 04 '22 at 14:29
  • next to `go mod init`, running `go mod tidy` is probably also required. – The Fool Jun 04 '22 at 14:33
  • @TheFool I tried it , previous 'go.mod' error disappeared but seems like a new error occur , "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' – Jia Jun 04 '22 at 14:42
  • @colm.anseo do you mind take a look at my 'Edit' session in the last part of my post based on your comments ? I still go error , but a new error "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" – Jia Jun 04 '22 at 14:44
  • thats because you copy from build which is your stage or intermidate image. But you are currently in that stage. The error tells you that this image doesnt exist which is correct. You need another from instruction as your second stage, if you intend to use multi staging. I would also create the go.mod locally, not in your dockerfile. Its like a package.json when using javascript, for example. Like copy your local go.mod and go.sum into the build stage on build. – The Fool Jun 04 '22 at 14:46
  • @TheFool the Dockerfile is copied from the web and I modify it , so I can just remove multi-stage thing , right ? Posted below FROM golang:1.17 WORKDIR / COPY . . RUN go mod init feedme RUN go mod tidy RUN go build -gcflags="all=-N -l" -o /feedme EXPOSE 8000 2345 COPY /go/bin/dlv /dlv CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"] – Jia Jun 04 '22 at 14:56
  • 1
    you can but for go programs, multi staging makes alot of sense. You can go through this post once, https://docs.docker.com/language/golang/build-images/ – The Fool Jun 04 '22 at 15:20
  • @TheFool I have a working container which use multi staging build , many thanks for the doc ! It helps me to understand many basic concepts which I didn't – Jia Jun 05 '22 at 04:38

1 Answers1

3

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"]
Jia
  • 2,417
  • 1
  • 15
  • 25
  • 1
    well, done. Should should generate the go.mod and go.sum locally though. Its helps you version pinning. Otherwise you might get bad suprises one day. – The Fool Jun 05 '22 at 09:52
  • @TheFool hello , I updated my Dockerfile in 'Edit' session , just copy my local go,mod to my docker image , please let me know if anything missed . Again , appreciate your suggestion and help :) – Jia Jun 08 '22 at 01:29