Vinícius Krolow

Let's hurt the code!

Wed, Jan 11, 2017

Go compile binary not running in alpine and busybox

I was working in a proxy pac project to serve TLD for local development. I have decided to use golang, because the code would be quite simple and get a binary as output would help in use a small docker image and just copy the binary.

Once the code was finish, I have started the creation of the docker file that was quite simple, just a copy of binary file to inside the docker image.

Unfortunately it was not that simple, in the first tries I got this error:

panic: standard_init_linux.go:175: exec user process caused "no such file or directory" [recovered]
        panic: standard_init_linux.go:175: exec user process caused "no such file or directory"

goroutine 1 [running, locked to thread]:
panic(0x7ea980, 0xc820143420)
        /usr/local/go/src/runtime/panic.go:481 +0x3e6
        /go/src/ +0x38e
panic(0x7ea980, 0xc820143420)
        /usr/local/go/src/runtime/panic.go:443 +0x4e9*LinuxFactory).StartInitialization.func1(0xc82011abf8, 0xc82001e090, 0xc82011ad08)
        /go/src/ +0x136*LinuxFactory).StartInitialization(0xc82005c820, 0x7f53b3b86470, 0xc820143420)
        /go/src/ +0x5b1
main.glob.func8(0xc82007a780, 0x0, 0x0)
        /go/src/ +0x68, 0x900b08, 0x13, 0x846ea8, 0x4, 0xc82011b268, 0x1, 0x1, 0x0, 0x0, ...)
        /usr/local/go/src/reflect/value.go:435 +0x120d
reflect.Value.Call(0x74f180, 0x900b08, 0x13, 0xc82011b268, 0x1, 0x1, 0x0, 0x0, 0x0)
        /usr/local/go/src/reflect/value.go:303 +0xb1, 0x900b08, 0xc82007a780, 0x0, 0x0)
        /go/src/ +0x2ee, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8dfe00, 0x51, 0x0, ...)
        /go/src/ +0xfec*App).Run(0xc820001980, 0xc82000a100, 0x2, 0x2, 0x0, 0x0)
        /go/src/ +0xaa4
        /go/src/ +0xe24

After some google about the error, I was thinking it might be related with the docker version, I have tried to upgrade and downgrade and keep with no lucky.

So I found this stackoverflow by the description it seems that error was quite similar to mine.

I have decided to give it a try, and it works! Basically the issue is that golang net library when normally build a package it creates dynamic links to some .so libs, in my case these were the links:

 -> ldd builds/1.0.0/linux_amd64/tld-proxy-pac =>
        (0x00007ffd9a087000) => /lib/x86_64-linux-gnu/ (0x00007f6470502000) => /lib/x86_64-linux-gnu/ (0x00007f6470139000)
        /lib64/ (0x00005589babab000)ldd builds/1.0.0/linux_amd64/tld-proxy-pac =>  (0x00007ffd9a087000) => /lib/x86_64-linux-gnu/ (0x00007f6470502000) => /lib/x86_64-linux-gnu/ (0x00007f6470139000)
        /lib64/ (0x00005589babab000)

So what I have to do is build netgo by forcing static links CGO_ENABLED=0 go build -tags netgo -a -v and build my code using CGO_ENABLED=0 as well CGO_ENABLED=0 goxc.

By checking the links in the new binary output, I could ensure the non existence of dynamic links:

-> ldd builds/1.0.0/linux_amd64/tld-proxy-pac
        not a dynamic executable

Hey, have you find a typo or english smell? help me improve my english, i'll be glad to receive an improvement here.