1

I would like for this very simple Go package to run in a Docker container using Scratch (or minimal) image.

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    cmd := "host"
    args := []string{"-t", "ns", "google.com"}
    output, err := exec.Command(cmd, args...).Output()
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(output))
}

My original Dockerfile is as follows:

FROM scratch
ADD gohost /
CMD ["/gohost"]

This results in exit code 0: exec: "host": executable file not found in $PATH

I figure this means I need to ADD the /usr/bin/host and set ENV on the added host.. but all the random combinations I've tried of this failed..

I've also tried to simply change cmd := "host" to point to the host binary I added (cmd := "/host"), but seems that isn't a possibility either.

Also, I'm not sure if it's relevant, but it's important the Go binary is built with env GOOS=linux GOARCH=arm64 go build.

2
  • move host executable into docker's path namespace. Commented Oct 4, 2018 at 10:45
  • @nilsocket could you clarify? I've tried ADD /usr/bin/host /bin and /usr/bin but that didn't work, and when I changed the Go code to point to the binary, e.g. cmd := "/host" then I made sure that the binary was located in that path, e.g. ADD /usr/bin/host / Commented Oct 4, 2018 at 11:01

1 Answer 1

1

If you're depending on calling external binaries, either you also need to make sure they're statically-compiled and included in your Dockerfile, or you can't use a FROM scratch image. A merely very small base image might work better.

In many cases there is a Go-native library to do what you need, and you might see if you can change your code to not need an external process. For instance, instead of calling host as an external process, you might call net.LookupHost instead.

Some common tools are available in busybox (image), including an nslookup but not a host or a dig, but usually these are the sorts of things where an in-process library call will do better. Otherwise you need a lightweight base Linux distribution like alpine where you can add software; your Dockerfile would be

FROM alpine
RUN apk add bind-tools
COPY gohost /bin
CMD ["gohost"]

The Alpine base image advertises itself as being only 5 MB, so your image will be bigger than a FROM scratch image but still not huge.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked, thanks a lot! The reason I wanted to use host is because I believed it would be much more performant, but I had been testing up against a Go package (github.com/miekg/dns) and not net.LookupHost.. the dns package felt a bit slow, but net.LookupHost seems just as fast as /usr/bin/host (play.golang.org/p/J2_TWGMCfog)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.