2015-07-13 1 views
7

Próbuję zbudować statycznie połączoną wersję binarną z kodu źródłowego Haskell i skopiuj ten plik binarny na minimalny obraz Docker, aby mój obraz produkcyjny był jak najmniejszy.Statycznie połączony program Haskell w Docker

W przypadku testu używam program Hello World:

main = print "Hello world" 

Plik test.cabal jest domyślnym generowane przez cabal init, tyle że dodałem

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

Aby zbudować biegnę

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

W budowie występuje następujący błąd:

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 

Z tego co zrozumiałem, oznacza to, że muszę mieć poprawną wersję glibc, aby móc wykonać plik binarny. Wykonywanie binarny działa dobrze w tym samym pojemniku:

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

Jest również statycznie połączonego zgodnie z oczekiwaniami:

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

utworzyć mój minimalny obraz, tworzę Dockerfile (plik libc.so.6 jest kopiowany z 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"] 

ta nie działa, gdy próbuję zbudować i uruchomić go

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

Próbowałem tego samego, zaczynając od obrazu busybox (bez dodawania libc.so.6), ale to też nie działało. Dodanie jej do pracy z ubuntu:14.04 działało (prawdopodobnie dlatego, że na tym obrazie bazuje haskell:7.10).

Próbowałem uruchomić strace na komendzie, ale nie byłem w stanie nadać temu sensu. Wyjście strace jest tutaj: http://pastebin.com/SNHT14Z9

Czy mogę wykonać tę pracę od scratch? Czy jest to niemożliwe z powodu problemu "dlopen"?

+2

Prawdopodobnie interesuje Cię [ten artykuł] (https://www.fpcomplete.com/blog/2015/05/haskell-web-server-in-5mb). – Zeta

+0

Ten artykuł jest właśnie powodem, dla którego postanowiłem spróbować swoich sił w odtwarzaniu tego samego, ale przy użyciu statycznego pliku binarnego. Próbowałem uruchomić mój statyczny kod binarny zaczynając od 'dysinger/haskell-scratch', ale to powoduje kod błędu 139. – sgillis

+0

Nie jestem tego pewien, ponieważ użyłeś 'scratch', a nie' haskell-scratch', jak wspomniano w artykule, zobacz https://github.com/snoyberg/haskell-scratch. – Zeta

Odpowiedz

4

Napotkano funkcję systemu wykonawczego GHC. Nawet aplikacja jest statyczna, potrzebuje niektórych plików pomocniczych, a pliki ustawień narodowych są jednym z nich.

Zobacz https://ghc.haskell.org/trac/ghc/ticket/7695 i https://ghc.haskell.org/trac/ghc/ticket/10298

Jak widać, które zostaną ustalone w 7.10.2 (który w tej chwili jest tuż za rogiem).

Lista obrazów zawiera wszystkie potrzebne pliki w minimalnym pojemniku.

+0

Próbowałem ponownie z obrazem 'haskell-scratch', ale tym razem z' snoyberg/haskell-scratch'. To wystarczyło. Po wyjściu 7.10.2 spróbuję jeszcze raz i zobaczę, czy naprawdę mogę zacząć od 'scratch'. Dzięki! – sgillis

+0

Jest to bardziej cecha iconv niż GHC (jedyną cechą wyróżniającą GHC jest to, że jego pakiet bazowy intensywnie używa iconv), –