Phantomjs for npm in alpine-based docker image

Make npm phantomjs-prebuilt package compatible with alpine-based docker image.

Make npm phantomjs-prebuilt package compatible with alpine-based docker image.


Problem

musl-libc vs glibc

alpine uses musl-libc as its C library instead of glibc to shrink down the image size and improve performance 1.

However phantomjs doesn’t get compiled with musl-libc which cripples phantomjs-prebuilt node package inside the container. The cause was pinned down to the missing ld-linux-x86-64.so.2.

phantomjs error

It appears there is no fix for this even after so long.

Solution

Dockerize

One approach is to Dockerize phantomjs into linux executables inside a glibc compatible base (Debian or Ubuntu):

// download phantomjs
mkdir /tmp && cd /tmp
curl -o phantomjs.tar.bz2 \

    -L https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2

// untar and dockerize phantomjs
tar -jxvf phantomjs.tar.bz2

dockerize -n -o phantomjsDir -e /tmp/phantomjs-2.1.1-linux-x86_64  \

    -a /bin/dash /bin/sh -a /usr/share/fonts /usr/share -a /etc/ssl /etc  \ 
    -a /etc/fonts /etc \

    /tmp/phantomjs-2.1.1-linux-x86_64 /usr/bin/curl

// tar the executables but without phantomjs binaries
cd phantomjsDir
tar -zcf phantomjs.tar.gz ./lib ./lib64 ./usr/lib

Which gives us a phantomjs.tar.gz with the following structure:

│── lib
β”‚Β Β  └── x86_64-linux-gnu
β”‚Β Β      β”œβ”€β”€ libcom_err.so.2
β”‚Β Β      β”œβ”€β”€ libcrypto.so.1.0.0  
β”‚Β Β      β”œβ”€β”€ libcrypt.so.1
β”‚Β Β      β”œβ”€β”€ libc.so.6
β”‚Β Β      β”œβ”€β”€ libdl.so.2
β”‚Β Β      β”œβ”€β”€ libexpat.so.1
β”‚Β Β      β”œβ”€β”€ libgcc_s.so.1
β”‚Β Β      β”œβ”€β”€ libgcrypt.so.11
β”‚Β Β      β”œβ”€β”€ libgpg-error.so.0
β”‚Β Β      β”œβ”€β”€ libkeyutils.so.1
β”‚Β Β      β”œβ”€β”€ libm.so.6
β”‚Β Β      β”œβ”€β”€ libnss_compat.so.2
β”‚Β Β      β”œβ”€β”€ libnss_dns.so.2
β”‚Β Β      β”œβ”€β”€ libnss_files.so.2
β”‚Β Β      β”œβ”€β”€ libpng12.so.0
β”‚Β Β      β”œβ”€β”€ libpthread.so.0
β”‚Β Β      β”œβ”€β”€ libresolv.so.2
β”‚Β Β      β”œβ”€β”€ librt.so.1
β”‚Β Β      β”œβ”€β”€ libssl.so.1.0.0
β”‚Β Β      └── libz.so.1
β”œβ”€β”€ lib64
β”‚Β Β  └── ld-linux-x86-64.so.2
└── usr
β”‚   └── lib
β”‚       └── x86_64-linux-gnu
β”‚           β”œβ”€β”€ libasn1.so.8
β”‚           β”œβ”€β”€ libcurl.so.4
β”‚           β”œβ”€β”€ libffi.so.6
β”‚           β”œβ”€β”€ libfontconfig.so.1
β”‚           β”œβ”€β”€ libfreetype.so.6
β”‚           β”œβ”€β”€ libgnutls.so.26
β”‚           β”œβ”€β”€ libgssapi_krb5.so.2
β”‚           β”œβ”€β”€ libgssapi.so.3
β”‚           β”œβ”€β”€ libhcrypto.so.4
β”‚           β”œβ”€β”€ libheimbase.so.1
β”‚           β”œβ”€β”€ libheimntlm.so.0
β”‚           β”œβ”€β”€ libhx509.so.5
β”‚           β”œβ”€β”€ libidn.so.11
β”‚           β”œβ”€β”€ libk5crypto.so.3
β”‚           β”œβ”€β”€ libkrb5.so.26
β”‚           β”œβ”€β”€ libkrb5.so.3
β”‚           β”œβ”€β”€ libkrb5support.so.0
β”‚           β”œβ”€β”€ liblber-2.4.so.2
β”‚           β”œβ”€β”€ libldap_r-2.4.so.2
β”‚           β”œβ”€β”€ libp11-kit.so.0
β”‚           β”œβ”€β”€ libroken.so.18
β”‚           β”œβ”€β”€ librtmp.so.0
β”‚           β”œβ”€β”€ libsasl2.so.2
β”‚           β”œβ”€β”€ libsqlite3.so.0
β”‚           β”œβ”€β”€ libstdc++.so.6
β”‚           β”œβ”€β”€ libtasn1.so.6
β”‚           └── libwind.so.0

Then mount phantomjs.tar.gz into the alpine image we are going to build.

tar -zxf phantomjs.tar.gz /

phantomjs-prebuilt should now work fine in alpine-based docker containers.