Reputation: 453
Within my Dockerfile, I am setting up the Perl modules that will be installed when run, like so:
RUN ["cpanm", "Carp", "Carp::Heavy", "Class::Data::Inheritable"]
However, for one module, I need a specific version of a module, not the latest one. How can I specify that version in the above line?
I've been searching online for hours, and haven't turned up anything useful yet.
Upvotes: 8
Views: 6207
Reputation: 25153
To specify target module version you can use
cpanm MIYAGAWA/Plack-0.99_05.tar.gz # full distribution path
cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz # install from URL
cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz # install from a local file
See official documentation: https://metacpan.org/dist/App-cpanminus/view/bin/cpanm
But better, to my mind, would be to use cpanfile
. See --cpanfile
option https://metacpan.org/dist/App-cpanminus/view/bin/cpanm#-cpanfile and format of this file https://metacpan.org/pod/cpanfile
But if you have many modules (like me), I recommend to use cpm
. It installs modules in parallel very fast. Also with help of docker we could cache builds, thus rebuilds will takes seconds. Here is my Dockerfile
:
## Modules
WORKDIR ${APP_ROOT}
# install modules outside of WORKDIR, so it will not interfere when we do COPY . .
RUN mkdir -p ../modules
RUN ln -s ../modules local
RUN cpanm -n -L ./local App::cpm Carton::Snapshot && rm -rf /root/.cpanm
COPY cpanfile ./
COPY cpanfile.snapshot ./
RUN \
--mount=type=cache,target=/root/.perl-cpm \
cpm install -w 16 --no-test -L ./local \
--with-develop
# regenerate cpanfile.snapshot
# https://github.com/miyagawa/Carmel#cpm
# cpm doesn't have the ability to manage cpanfile.snapshot file on its own.
RUN carton install
# You can copy snapshot from container by running:
# docker cp <container_name>:${APP_ROOT}/cpanfile.snapshot.latest ./cpanfile.snapshot
Upvotes: 0
Reputation: 453
For anyone who's searching for this same answer in the future, another option can be found here in the documentation for cpanm
:
cpanm [email protected]
If you have a long list of modules, consider feeding a cpanfile
into cpanm
rather than listing them all in the Dockerfile.
The easiest way to specify a particular version number for a module in a cpanfile
is like this:
requires 'Text::ParseWords', '==3.1';
The syntax for requesting the latest version of a module is this:
requires 'Text::ParseWords';
Requesting a minimum version: (note the lack of '==')
requires 'Text::ParseWords', '3.1';
The syntax for requesting specific versions in other ways is fairly well-documented here.
Another great write-up of the use of cpanm
and a cpanfile
can be found
in Installation of cpan modules by cpanm and cpanfile.
Upvotes: 8
Reputation: 118138
Instead of specifying a module name, specify a URL. Eg, instead of Class::Data::Inheritable
, use https://cpan.metacpan.org/authors/id/T/TM/TMTM/Class-Data-Inheritable-0.06.tar.gz
You can find the applicable URL by going to the module page on metacpan, selecting the version you want, and copying the download link.
PS: You might want to also set PERL_CPANM_OPT=--from https://cpan.metacpan.org/
in the environment so cpanm
only downloads using HTTPS
.
Upvotes: 7
Reputation: 8721
To have CPAN install a specific version of a module, you need to provide the full module distribution filename including the author. For example to install the module Set::Object
version 1.28
, at the command line type:
cpan SAMV/Set-Object-1.28.tar.gz
Same thing apply with Docker, just add
RUN cpan SAMV/Set-Object-1.28.tar.gz
Upvotes: 4