summaryrefslogtreecommitdiff
path: root/_posts/2019-04-11-perl6-nightly-docker-images.html
blob: 78c868e4946625045737417b703f3285a650f4e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
---
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 %}