Closed kraih closed 3 years ago
Comment moved to https://github.com/graphql-perl/graphql-perl/issues/29.
@mohawk2 I strongly disagree, getting it "right" (for whatever definition) from the start is not important at all. All we have to do is give our users a minimal starting point for their first experiments with containerization. Any complexity with multiple dockerfiles would be counter productive. More complex generators can be shipped as 3rd party modules on CPAN.
(Putting my docker-perl hat on...)
Yep, probably simplest is a ./script/myapp generate dockerfile
that produces:
FROM perl:5.32
ADD . /app
WORKDIR /app
RUN cpanm Mojolicious && cpanm --installdeps .
EXPOSE 3000
CMD ["./script/myapp","prefork"]
There are a few assumptions like whether there's a cpanfile
or Makefile.PL
already around, what ports to use, etc. but I suppose these can be parameterized/templated (or just document calling script/myapp generate makefile
prior.) Also probably worth noting (but not too important) is the base perl
image to use; the regular variant is heavy but good for general development, but for documenting deployments it might be worth using a :slim
variant...
The default port 3000 should be fine, no need to make everything configurable. I trust our users do edit a dockerfile if they have to. 😉 The generator should probably output a warning though if a Makefile.PL
or cpanfile
is missing. Caring about a :slim
variant doesn't seem that important, maybe as a side note in the cookbook recipe.
Given it's generating in the context of a my_app
/ myapp.pl
, do you think it makes sense to do things like WORKDIR /opt/my_app
(instead of the generic /app
) and/or pin cpanm Mojolicious
to the particular version being currently used (like the makefile generator does)?
I would imagine if folks have a cpanfile
or Makefile.PL
that it already lists Mojolicious
, so we probably should do one or the other of cpanm Mojolicious
and cpanm --installdeps
(not both) right?
FROM perl:5.32
RUN cpanm Mojolicious@8.64
WORKDIR /opt/my_app
COPY . .
EXPOSE 3000
CMD ["./script/my_app", "prefork"]
or:
FROM perl:5.32
WORKDIR /opt/my_app
COPY . .
RUN cpanm --installdeps .
EXPOSE 3000
CMD ["./script/my_app", "prefork"]
For the cookbook (to get folks thinking about how to improve their cacheability, etc), I would probably go slightly more complex with something like this, which would dovetail nicely with the makefile generator's output:
FROM perl:5.32
WORKDIR /opt/my_app
COPY Makefile.PL .
RUN cpanm --installdeps .
COPY . .
EXPOSE 3000
CMD ["./script/my_app", "prefork"]
(This makes sure the cpanm
only reinstalls deps when Makefile.PL
changes, although doesn't work in more complex cases like sourcing VERSION
from another module, so isn't a sane default for the generator.)
@tianon The VERSION
is hardcoded in the Makefile.PL
created by ./myapp generate makefile
though.
Right, so my thought is that this should either use cpanm Mojolicious@8.64
(matching the makefile generator) or should assume users use that makefile generator and instead use just cpanm --installdeps .
Do you think it makes sense to change the output depending on whether a Makefile.PL
exists, or should we just assume that one does and/or throw a warning if it is missing?
What about for a Lite app - should the result copy just the single script or should it still be basically the same?
(Edit: I've pushed the very absolute basics to https://github.com/mojolicious/mojo/compare/master...tianon:dockerfile, shamelessly copying from makefile.pm
-- happy to make a PR or do more on it with some guidance but don't want to pester :smile: IMO it definitely needs to get clever with ->app
to at least get the right app name in there :innocent:)
If you're creating a dockerfile for a lite app i think we should assume that there's more stuff to be copied in the directory (like templates and static files at least).
Edit: Yes, it should detect the right script to put into the dockerfile.
I've updated https://github.com/mojolicious/mojo/compare/master...tianon:dockerfile with a bit more - I'd love some feedback (I'm admittedly a little bit over my own head, but trying to work it out :sweat_smile: :heart:).
One thing I'm not a huge fan of is that my $exe
detection currently will turn mojo generate dockerfile
into something like ../../../bin/mojo
(for a system installed mojo
binary), so I'm thinking it might make sense to add some detection there and convert anything that starts with ../
into script/$name
instead?
I'm happy to adjust or even let someone else take over if I'm completely on the wrong track, but I'm also enjoying my attempt. :smile:
@tianon That might just be the best we can do for script detection. Personally, i don't care too much about the mojo generate dockerfile
case (it could just as well use ... if $self->app->isa('Mojo::HelloWorld')
to set some static default). Or we could use $ENV{MOJO_EXE} || ('script/' . $self->app->moniker)
. There is no need to overthink it.
Totally fair, and makes sense -- folks who've renamed their script
ought to know what they're getting into already. :smile:
I've pushed the updated version to https://github.com/mojolicious/mojo/compare/master...tianon:dockerfile -- do you think it's ready for a PR, or is there more I ought to put into this first?
Sure, there will be style change requests, but it seems enough to get the review process started.
I want to be able to do
and
to get a minimal but working
Dockerfile
for a Mojolicious app. It should probably start with an official perl container from Docker Hub, runcpanm --installdeps
to install dependencies, and finally start the app in prefork mode. Nothing fancy, just enough to get started.And of course there should be a new recipe in the Deployment section of the cookbook. Describing how to declare dependencies and also showing a minimal
Dockerfile
to build a container for a Mojolicious app.