In short, I wanted a script that:
- compiles the source and produces the binary
- is possibly a one-liner
- does not litter around various libraries
- cleans up after itself
- does not have any dependencies besides Docker
Setup and cleanup
The first step is to create a new container based on Ubuntu, execute some commands and remove it. Docker and Bash have powerful support for this:
With --name, we can name a container, and then we can reference it without first having to look up the container id.
Fetching the dependencies and compiling
The next thing is to actually setting up and the compiling inside the container. I’ve started from the official build docs, just added make, git and libqt5webkit5-dev as they were needed for the base Ubuntu image. Also, the build have a confirmation prompt, but luckily that can be supplied from the CLI with --confirm. The commands are:
To make it a one-liner, simply add && between the commands:
Copying the resulting binary
Docker have several ways to copy a file from the container to the host (there is a COPY command, and the container can also mount a volume of the host), unfortunately they are not portable. Luckily there is a method that works with relative paths, and that is stream redirection. The basic idea is that we redirect all stderr streams to stdout (so there will be no stderr data), and read the binary to the stderr, and finally on the host redirect the stderr to a file. As the binary is located as bin/phantomjs, the resulting commands are:
And the redirection to file:
The only step now is to combine and compress all the above into a single line, which can be copy-pasted to any system with Docker:
The actual compilation will take quite some time, on my machine it was ~ 1 - 1.5 hours. The binary works fine, and it will make a good substitution until the official build arrive. The only thing the process leaves is an Ubuntu image, but that’s something people may generally want to have around. If you don’t need it, delete it with a simple sudo docker rmi ubuntu.
The good thing with this approach is that it will work with any other compilation too. Just figure out the exact sequence of commands, add the above tricks, and you have a fully automated build script. Remember, that you can pull out multiple files, just tar them inside the container and untar on the host.
For a reference, if you want to start a fresh new Ubuntu as a playground, use: