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"]