Perl 6 nightly Docker images

Due to the slow release of Rakudo Star (which actually did release a new version last month), I had set out to make Docker images for personal use based on the regular Perl 6 releases. But, as I discovered some memory related issues, and another branch with some possible fixes, I changed my mind to make them nightlies based on the master branches of all related projects instead. This way I could get fixes faster, and help testing when needed.

These nightlies are now up and running, available on Docker Hub for anyone to use! You can also find the Dockerfiles I'm using on git.tyil.nl, in case you're interested or have suggestions to further improve the process.

The timing of the (public) release of these images could have been better, though. About two weeks ago, other nightlies were released as well, by Tony O'Dell, as has been noted in the Perl 6 Weekly post. While I greatly appreciate his efforts, I was not going to just abandon all the work I've put into my images. Instead I've tried to make smaller images, and provide different bases than him. Maybe we can eventually learn from each other's images and improve Docker support for the entire community together.

The easiest thing to work on was providing different bases. For now, this means I have images with the following four base images:

  • Alpine
  • Debian
  • Ubuntu
  • Voidlinux

This way, people can have more options with regards to using the distribution tooling that they're more comfortable with. One could also opt to use a more familiar or better supported base image for development and testing out their module, and use a smaller image for production releases.

As to the size of the images, Tony's tonyodell/rakudo-nightly:latest is about 1.42GB at the time of writing this post. My images range from 43.6MB (alpine-latest) to 165MB (voidlinux-latest). Though this is not a completely fair comparison, as my images have stripped out a lot of the tooling used (and often required) to build some Perl 6 modules, making them unusable in their default shape for many projects.

To remedy this particular issue, I've also created -dev images. These images come with a number of additional packages installed to allow zef to do its work to get dependencies installed without requiring end-users to search for those packages. This should reduce complexity when using the images for end-users. If we take the dev images into account when comparing sizes, my images range from 256MB (alpine-dev-latest) to 1.27GB (voidlinux-dev-latest). That's much closer to the rakudo-nightly image.

If you're interested in trying these images out, you may be interested in the way I'm using these images myself as reference. Currently, my CPAN upload notifier bot is using these nightly images in its Dockerfile.

FROM tyil/perl6:debian-dev-latest as install

RUN apt update && apt install -y libssl-dev uuid-dev

COPY META6.json META6.json

RUN zef install --deps-only --/test .

As you can see from the Dockerfile, I start out by using a -dev image, and name that stage install. I'm still contemplating to include libssl-dev into the -dev images, as it seems to pop up a lot, but for now, it's not part of the -dev images, so I install it manually. Same goes for uuid-dev. Then I copy in the META6.json, and instruct zef to install all the dependencies required.

FROM tyil/perl6:debian-latest

ENV PERL6LIB=lib

WORKDIR /app

RUN mkdir -p /usr/share/man/man1
RUN mkdir -p /usr/share/man/man7
RUN apt update && apt install -y libssl-dev postgresql-client

COPY bin bin
COPY lib lib
COPY --from=install /usr/local /usr/local

RUN mkdir -p /var/docker/meta
RUN date "+%FT%TZ" > /var/docker/meta/build-date

CMD [ "perl6", "bin/bot" ]

Then I start a new stage. I set the $PERL6LIB environment variable so I don't have to use -Ilib at the end, and set a WORKDIR to have a clean directory to work in. Next, I set up the runtime dependencies of the application.

I then continue to copy in the bin and lib directories, containing the application itself, and copy over /usr/local from the install stage. /usr/local is where Perl 6 is installed, and zef installs all its dependencies into. This way, the -dev image can be used for building all the dependencies as needed, and only the finished dependencies end up in the final image that's going to run in production.

Lastly, I set the build date and time of the image in a file, so the application can refer to it later on. It is displayed when the IRC bot replies to a .bots command, so I can verify that the running bot is the one I just built. And finally, the CMD instruction runs the application.

I hope this displays how the images can be used for your applications, and the reasoning as to why I made them the way they are. If you have any suggestions or issues, feel free to contact me in whatever way suits you best. You can find some contact details on the homepage of my blog.