-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Use Docker to build Linux binaries statically #13822
Comments
For @zackw branch on this attempt: https://github.com/zackw/phantomjs/tree/docker |
Another reference is from @bprodoehl: https://github.com/bprodoehl/phantomjs/commits/master |
This is a fantastic idea. Glad to see it embraced here! |
For an alternative approach that I've been using extensively for many projects of mine, see my previous blog post: http://ariya.ofilabs.com/2014/12/docker-and-phoenix-how-to-make-your-continuous-integration-more-awesome.html. Instead of a Here's my attempt at producing the said customized base image: https://bitbucket.org/ariya/erik (it's named after Erik, the phantom character in Phantom of the Opera). I registered this as an automated build at Docker Hub (see https://hub.docker.com/r/ariya/erik) and hence this can be pulled by the usual Docker command, e.g.
(To be continued) |
FYI, the Docker scripts in my branch do indeed construct a customized base image which could be reused for many builds. They also have a custom entry point that runs the build, which may or may not be a good idea; I'm not super familiar with Docker. I'm not going to be working on this any more until after Jan 10, because I'll be traveling and won't have the use of my Linux desktop. |
@zackw The difference in the variant that I proposed above is that the customized base image is created once (even better, by Docker Hub so we don't need to waste our own CPU cycles and such) and it will be reused by any numbers of Linux static binary builds. Given that we may only need to update the system dependencies once a while, I believe we don't need to incur that time building all those libraries statically. |
On the subject of the customized base image, I agree with the sentiment from @zackw that downloading source packages without a follow-up of package verification is rather risky (especially via http). An alternative that we can consider is using Debian's original source package. We can use The drawback of using this My pragmatic view on this subject leans towards Debian source package. What do you think @zackw? |
Here's my progress so far. I have the following file SOURCE_PATH=/src
BUILD_PATH=$HOME/build
echo "Recreating build directory $BUILD_PATH"
rm -rf $BUILD_PATH && mkdir -p $BUILD_PATH
echo
echo "Transferring the source: $SOURCE_PATH -> $BUILD_PATH"
cd $BUILD_PATH && cp -rp $SOURCE_PATH . && cd src
echo
echo "Executing make..."
python build.py --confirm --git-clean-qtbase --git-clean-qtwebkit
echo And then I run docker run -v $PWD:/src ariya/erik sh -c "/src/deploy/docker-build.sh" That So far I got Qt Base built, however I stumbled upon the following error:
It seems that some configuration script could not discover the ICU libraries on the system. I need to dig deeper but if you have an idea @bprodoehl or @zackw, let me know. |
In principle I prefer this - it's faster, it's signed, and it leverages a bunch of their infrastructure - but it does have two drawbacks: we have less control over exactly which version of each library we get, and it may be harder to persuade qmake to link the right set of things statically. Maybe let's try to do it using Debian source packages (and a baseline of Debian 'stable'/'squeeze') and see how that goes?
I hit the same problem. The issue is fundamentally that if you link ICU statically, you have to add |
It turns out that the failing ICU detection is due to the use of pkg-config. Since the customized base image has its own built libicu, it should be detected directly instead of via pkg-config. The fix is rather easy, one line in that
Now, on to building QtWebKit... |
Now that I got QtBase, QtWebKit, and PhantomJS all built properly, the linker fails rather miserably:
I am suspicious of the interplay between Fontconfig 2.11.1 and libxml2 2.9.3. Will keep digging. |
Without custom built Fontconfig, I finally got PhantomJS compiled and linked!
|
File size information:
|
Quick test on CentOS indicates that this can run only on CentOS >= 7. CentOS 6:
CentOS 7
|
Quick test on Debian gives a similar result, the executable is only usable for Debian >= 8. jessie:
wheezy:
|
It may not be so bad. So far I have luck building everything using e.g. ICU 4.8.1.1, available as the source package for wheezy, instead of using the latest ICU 56.1. The problem with qmake might be overtaken by event, as the whole build process eventually completed and I got a usable executable. |
BTW, another bonus of using |
I finally got something that works in most distribution! So far I've tested it on Fedora >= 22, CentOS 6.7 and 7.2, Debian 7 (wheezy) and 8 (jessie), as well as Ubuntu 12.04 LTS and 14.04 LTS. The workflow is still similar, take a look at docker run -v $PWD:/src debian:wheezy /src/deploy/docker-build.sh The trick here is to base it off wheezy and only to custom compile only OpenSSL and ICU (both using the earlier proposed I think it does make sense anyway to limit the rebuilt libraries. PhantomJS 1.x already requires Fontconfig (and thereby also FreeType) hence making it the same requirement in 2.1 should not cause a lot of grief. I can't imagine a usable basic system without zlib, libxml2, and friends. Meanwhile, the graphics system libraries (libpng, libjpeg, libwebp) are not being utilized since we configure Qt to use its own copy. Originally, I even tried to skip OpenSSL but the resulting executable has a problem on Fedora-based systems (likely due to build configuration differences). That leaves us with OpenSSL and ICU, but that seems to work quite well! |
I just realize that this is so far only for producing 64-bit executable. I will give it a try with a 32-bit Docker image to see if the same workflow would work. |
Awesome progress! |
We don't really handle that npm module, please propose a concrete step that I could do. Otherwise, be patient and bear with us as I'm focusing on this task. |
Ok, found this:
So, the solution is to apt-get remove shared versions of those libraries. |
That is not necessary at all. Pay attention to my |
@ariya And here are results: Resulting phantomjs binary is linked to shared ssl and icu. |
Unfortunately, uninstalling openssl isn't possible, since a whole lot of packages depend on that. I think openssl is somehow not installed in that debian docker image, so it builds against static version. |
Ok, I removed openssl-dev package and it now links to a static version that is built in
Still having glibc problem:
@ariya could you remind what was a fix for this? |
The linker takes precedence on the dynamic libraries, to force to use the
|
Yeah, I know that, but I don't want to modify phantomjs sources since I'm not sure if @ariya would be fine with that approach. |
Maybe there's already an option to generate an static build, or you could send a pull-request with it. |
Ok, I did a little research. It seems like there's no way to install libc6 2.13 on Ubuntu 14.04. So using other distributions (or Docker images) is the only option to provide binaries for corresponding distributions. |
I'm going to commit the Docker-based solution to master and then we will close this issue as largely the issue is resolved. @Vanuan We need to continue your problem in a new spawn issue, otherwise it's just creating some additional confusion. |
Move away from Vagrant-based solution and use Docker. This works well for a 64-bit executable. For the 32-bit version, a minor tweak is necessary although it's not guaranteed to always work (Docker does not officially support 32-bit system). #13822
This is resolved now. For 32-bit build improvement, we track it at #13849. |
Congrats, great way to start the new year, been waiting for a ready to go PhantomJS linux binary for a long time. |
@diwu1989 there's no linux binary yet. |
@Vanuan @ariya what blockers are left for there to be a Linux binary? I know medium has been waiting on a Linux binary to update their node-phantomjs to 2.0, which unblocks karma and a whole slew of test runners to be able to use 2.0, which kills the ES5 shim for a lot of folks who carry it around solely for its function.prototype.bind shim... |
@mikesherov there are no blockers. You can build 64-bit Linux binary from master yourself. But that still wouldn't be "official". Unfortunately, there's no build machine to produce statically linked binaries for each commit. So that's it. We're just waiting for smb to provide CPU power for free. |
32-bit build is still problematic, see #13849. This issue should be resolved already, i.e. we have identified the optimal Docker workflow to build a static binary. If it's still necessary, please continue the discussion on a different place (e.g. one the above two issue), let's keep this issue to focus on the Docker methodology itself and other tangential topics. |
Hi, Can someone help me how to run a phantomJS tests in docker...? |
ERROR: 'phantomjs' executable needs to be in PATH. Though the path is set in syetem env variable |
Move away from Vagrant-based solution and use Docker. This works well for a 64-bit executable. For the 32-bit version, a minor tweak is necessary although it's not guaranteed to always work (Docker does not officially support 32-bit system). ariya#13822
To ensure a consistent build for the static binaries for Linux, we shall use Docker and build PhantomJS inside the container.
The text was updated successfully, but these errors were encountered: