standard_init_linux.go:190:exec用户进程使用go basic Web应用程序导致“无此文件或目录” Docker

The very basic web app is created in Go

package main

import(
   "fmt"
   "net/http"
   "os"
)

func hostHandler(w http.ResponseWriter, r *http.Request){
    name, err :=os.Hostname()

    if err != nil {
           panic(err)
        }

        fmt.Fprintf(w, "<h1>HOSTNAME: %s</h1><br>",name)
        fmt.Fprintf(w, "<h1>ENVIRONMENT VARS: </h1><br>")
        fmt.Fprintf(w, "<ul>")

        for _, evar := range os.Environ(){
            fmt.Fprintf(w, "<li>%s</li>",evar)
        }
        fmt.Fprintf(w, "</ul>")

}

func rootHandler(w http.ResponseWriter, r *http.Request){

    fmt.Fprintf(w, "<h1>Awesome site in Go!</h1><br>")
    fmt.Fprintf(w, "<a href='/host/'>Host info</a><br>")

}

func main() {

        http.HandleFunc("/", rootHandler)
        http.HandleFunc("/host/", hostHandler)
        http.ListenAndServe(":8080", nil)


}

Docker File for it

FROM scratch
WORKDIR /home/ubuntu/go
COPY webapp /
EXPOSE 8080
CMD ["/webapp"]

The image is built successfully

ubuntu@ip-172-31-32-125:~/go/src/hello$ docker build -t "webapp" .
Sending build context to Docker daemon  6.152MB
Step 1/5 : FROM scratch
 --->
Step 2/5 : WORKDIR /home/ubuntu/go
 ---> Using cache
 ---> 8810a06c58c7
Step 3/5 : COPY webapp /
 ---> Using cache
 ---> d75222363d3a
Step 4/5 : EXPOSE 8080
 ---> Using cache
 ---> 45de0853de8e
Step 5/5 : CMD ["/webapp"]
 ---> Using cache
 ---> e9f9031f3632
Successfully built e9f9031f3632
Successfully tagged webapp:latest

But when i run the docker its show error.

ubuntu@ip-172-31-32-125:~/go/src/hello$ docker run webapp
standard_init_linux.go:190: exec user process caused "no such file or directory"

Please guide what is the issue, I am new to docker and go.

Environment-related information

ubuntu@ip-172-31-32-125:~/go/src/hello$ ls
Dockerfile  webapp
ubuntu@ip-172-31-32-125:~/go/src/hello$ echo $GOPATH
/home/ubuntu/go

Code was compiled with go build webapp.go command

File not found can mean the file is missing, a script missing the interpreter, or an executable missing a library. In this case, the net import brings in libc by default, as a dynamic linked binary. You should be able to see that with ldd on your binary.

To fix it, you'll need to pass some extra flags:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -ldflags '-w' -o mybin *.go

The above is from: https://medium.com/@diogok/on-golang-static-binaries-cross-compiling-and-plugins-1aed33499671

Try change line in your Dockerfile

COPY webapp /webapp

I used this and it works

env GOARCH=386 GOOS=linux go build webapp.go

In my case CGO_ENABLED=0 was the key to fix this problem.

Cgo allows to use inline C code in Go sources, see more: https://golang.org/cmd/cgo/

I reckon by default Cgo links your application dynamically to libc, even if you don't use any inline C.
And libc is missing when you package your application to Docker image FROM scratch

Here is my working Dockerfile:

FROM golang:1.9.2-alpine AS builder
WORKDIR /go/src/app
COPY . .
RUN CGO_ENABLED=0 go install


FROM scratch
WORKDIR /opt
COPY --from=builder /go/bin/app .
ENTRYPOINT ["/opt/app"]