--- title: Perl 6 nightly Docker images layout: post tags: Perl6 Docker Raku description: > An overview of my work on nightly Perl 6 Docker images, and a few examples on how I'm using them. --- {% markdown %} 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](https://github.com/rakudo/rakudo/issues/1501), and [another branch with some possible fixes](https://github.com/MoarVM/MoarVM/pull/1072), 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. {% endmarkdown %} {% markdown %} These nightlies are now up and running, available on [Docker Hub](https://hub.docker.com/r/tyil/perl6) for anyone to use! You can also find [the Dockerfiles I'm using on git.tyil.nl](https://git.tyil.nl/docker/perl6), in case you're interested or have suggestions to further improve the process. {% endmarkdown %} {% markdown %} 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](https://p6weekly.wordpress.com/2019/03/25/2019-12-cool-truck/). 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. {% endmarkdown %} {% markdown %} 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. {% endmarkdown %} {% markdown %} 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. {% endmarkdown %} {% markdown %} 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. {% endmarkdown %} {% markdown %} 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](https://git.tyil.nl/perl6/app-cpan-uploadannouncer-irc) is using these nightly images in its [`Dockerfile`](https://git.tyil.nl/perl6/app-cpan-uploadannouncer-irc/src/branch/master/Dockerfile). {% endmarkdown %} {% highlight 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 . {% endhighlight %} {% markdown %} 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. {% endmarkdown %} {% highlight dockerfile %} 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" ] {% endhighlight %} {% markdown %} 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. {% endmarkdown %} {% markdown %} 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. {% endmarkdown %} {% markdown %} 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. {% endmarkdown %} {% markdown %} 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. {% endmarkdown %}