简体   繁体   中英

Build Docker with Go app: cannot find package

I have my Dockerfile in the root of directory with src/myapp folder, myapp contains myapp.go with main package.

Dockerfile looks like following:

FROM golang:1.9.2

ADD . /
RUN go build myapp;

ENTRYPOINT ["/go/bin/myapp"]

I get following error:

can't load package: package myapp: cannot find package "myapp" in any of:
    /usr/local/go/src/myapp (from $GOROOT)
    /go/src/myapp (from $GOPATH)

What am I doing wrong? Can I log ls command after docker has done ADD ?

After experiments I've come to this way of building Golang apps.

This way has several advantages:

  • dependencies are installed on build stage

  • if you need you may uncomment test options

  • build first fully-functional image about 800 MB

  • copies your program to an fresh empty image and produces very small image about 10 MB

Dockerfile :

# Two-stage build:
#    first  FROM prepares a binary file in full environment ~780MB
#    second FROM takes only binary file ~10MB

FROM golang:1.9 AS builder

RUN go version

COPY . "/go/src/github.com/your-login/your-project"
WORKDIR "/go/src/github.com/your-login/your-project"

#RUN go get -v -t  .
RUN set -x && \
    #go get github.com/2tvenom/go-test-teamcity && \  
    go get github.com/golang/dep/cmd/dep && \
    dep ensure -v

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build  -o /your-app

CMD ["/your-app"]

EXPOSE 8000



#########
# second stage to obtain a very small image
FROM scratch

COPY --from=builder /your-app .

EXPOSE 8000

CMD ["/your-app"]

You are copying all the files to Image root directory, Didn't installed any dependencies, Trying to Build it and then run the binary from /go/bin/app . The binary doesn't exists in that directory and it's generating errors.

I would recommend using a Dockerfile like this,

FROM golang:1.9.2 
ADD . /go/src/myapp
WORKDIR /go/src/myapp
RUN go get myapp
RUN go install
ENTRYPOINT ["/go/bin/myapp"]

This'll do the following.

  1. Copy project files to /go/src/myapp .
  2. Set Working directory to /go/src/myapp .
  3. Install dependencies, I used go get but replace it with which ever dependency management tool you are using.
  4. Install/build the binary.
  5. Set entry point.

You can run ls or any other command using docker exec .

Example:

docker exec <image name/hash> ls

You can also enter the shell in the generated image to understand it well using

docker run --rm -it <image hash/name> /bin/sh

For go 1.11 , you can use go module, the following is example

FROM alpine AS base
RUN apk add --no-cache curl wget

FROM golang:1.11 AS go-builder
WORKDIR /go/app
COPY . /go/app
RUN GO111MODULE=on  CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /go/app/main /go/app/cmd/myapp/main.go

FROM base
COPY --from=go-builder /go/app/main /main
CMD ["/main"]

myapp needs to be in /go/src/myapp as suggested, or in /usr/local/go/src/myapp . You can add it in ADD section.

If the objective is to create a container that simply runs your binary, I would take different approach.

First build the binary for linux:

GOOS=linux CGO_ENABLED=0 go build -a -installsuffix cgo

Then build a lightweight docker image from scratch:

FROM scratch
COPY myApp 
CMD ["/myApp"]

The official docs suggests the following Dockerfile:

FROM golang:1.8

WORKDIR /go/src/app
COPY . .

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["app"]

Please, visit https://hub.docker.com/_/golang for more info

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM