Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Statically linked Haskell program in Docker

Tags:

docker

haskell

I'm trying to build 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'm using a hello world program:

main = print "Hello world"

The test.cabal file is the default generated by cabal init, except that I added

ghc-options: -static -optc-static -optl-static -optl-threaded

To build I run

$ docker run -it -v $(pwd):/src haskell:7.10 /bin/bash
# cd src
# cabal build

The build gives the following error:

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 I have the correct version of glibc in order to be able to execute the binary. Executing the binary works fine in the same container:

# ./dist/build/test/test
"Hello world"

It's also statically linked as expected:

# ldd ./dist/build/test/test
not a dynamic executable

To create my minimal image, I create a Dockerfile (the libc.so.6 file is copied from the haskell:7.10 image):

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 build and run it

$ docker build -t test .
$ docker run -it test
test: out of memory (requested 1048576 bytes)

I tried the same thing starting from a busybox image (without adding libc.so.6) but this did not work either. Adding it to a ubuntu:14.04 did work (this is probably because haskell:7.10 is based on this image).

I tried running strace on the command, but was not able to make much sense of it. The strace output is here: http://pastebin.com/SNHT14Z9

Can I make this work from scratch? Or is this impossible due to the 'dlopen' issue?

like image 601
sgillis Avatar asked Jul 13 '15 10:07

sgillis


1 Answers

You encountered a feature of GHC runtime system. Even the application is static, it needs some auxiliary files, locale files are one of them.

See https://ghc.haskell.org/trac/ghc/ticket/7695 and https://ghc.haskell.org/trac/ghc/ticket/10298

As you can see, that will be fixed in 7.10.2 (which at the moment is right behind the corner).

https://github.com/snoyberg/haskell-scratch image lists hopefully all files you need in the minimal container.

like image 105
phadej Avatar answered Oct 22 '22 04:10

phadej