I am trying to create a statically linked binary from Haskell source code and copy this binary to a minimal Docker image so that my production image is as small as possible.
As a test case, I use the global hello program:
main = print "Hello world"
The default test.cabal file was created by cabal init , except that I added
ghc-options: -static -optc-static -optl-static -optl-threaded
For assembly, I run
$ docker run -it -v $(pwd):/src haskell:7.10 /bin/bash
The following error appears in the assembly:
opt/ghc/7.10.1/lib/ghc-7.10.1/rts/libHSrts.a(Linker.o): In function `internal_dlopen': (.text+0x727): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
From what I understood, this means that I need to make sure that I have the correct version of glibc in order to be able to execute binary code. Executing binary files works fine in one container:
# ./dist/build/test/test "Hello world"
It is also statically linked as expected:
# ldd ./dist/build/test/test not a dynamic executable
To create my minimal image, I create a Docker file (the libc.so.6 file libc.so.6 copied from the haskell:7.10 image haskell:7.10 ):
FROM scratch ADD dist/build/test/test /test ADD libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 CMD ["/test"]
This does not work when I try to create and run it.
$ docker build -t test . $ docker run -it test test: out of memory (requested 1048576 bytes)
I tried the same thing starting with a busybox image (without adding libc.so.6 ), but that didn't work either. Adding it to ubuntu:14.04 really worked (this is probably due to the fact that haskell:7.10 based on this image).
I tried running strace on a command, but couldn't figure it out. The strace output is here: http://pastebin.com/SNHT14Z9
Can I do this job with scratch ? Or is this not possible due to the dlopen problem?