1

In docker container I have a perl script and I need to be able to parse json I tried to have CPAN JSON installed for perl in my Dockerfile.

So I am doing the following in my Dockerfile

FROM centos:7.9.2009
RUN yum install -y cpanm \
      perl \
      perl-App-cpanminus \
      perl-Config-Tiny \
      sudo \
      &&  yum clean all \
      && sudo cpanm install JSON;

But when I do a docker build I get:

#0 41.76 Configuring Test-Simple-1.302195 ... OK
#0 41.95 Building and testing Test-Simple-1.302195 ... OK
#0 68.48 Successfully installed Test-Simple-1.302195
#0 68.59 Building and testing JSON-4.10 ... OK
#0 126.9 Successfully installed JSON-4.10
#0 127.0 2 distributions installed
------
ERROR: failed to solve: executor failed running [/bin/sh -c yum install -y cpanm     perl     perl-App-cpanminus     perl-Config-Tiny     sudo     &&  yum clean all     && sudo cpanm install JSON;]: exit code: 1

What is the problem here?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Jim
  • 3,845
  • 3
  • 22
  • 47
  • 2
    Note that `cpanm install JSON` will install `JSON` but also install a module called `install`! You probably just wanted `cpanm JSON`. – tobyink Aug 15 '23 at 16:17
  • 1
    Tip: Installing JSON::XS will make JSON *much* faster (since JSON uses pure-Perl JSON::PP by default). That said, I recommend Cpan::JSON::XS over both of those. – ikegami Aug 16 '23 at 19:12

3 Answers3

3

There are two issues you should fix.

  1. The package cpanm is not available for installation in the 1st place. Run docker run -it centos:7.9.2009 /bin/bash and in the container do yum install -y cpanm. I got:

No package cpanm available.
Error: Nothing to do

When I ran yum install -y cpanm perl sudo perl-App-cpanminus and then echo $? the return was 0 as it did install the other packages. This means that this stage isn't what broke your build. That is because the package you need in order to install packages from cpanm is perl-App-cpanminus. To fix this, just remove cpanm from the list of modules to install (since you're already installing perl-App-cpanminus). As this didn't break the build it is not strictly necessary just highly recommended.

  1. After that running the command cpanm install JSON returned:
[root@aabe6178c007 /]# cpanm install JSON
--> Working on install
Fetching http://www.cpan.org/authors/id/D/DA/DAGOLDEN/install-0.01.tar.gz ... OK
Configuring install-0.01 ... OK
Building and testing install-0.01 ... FAIL
! Installing install failed. See /root/.cpanm/work/1692109504.103/build.log for details. Retry with --force to force install it.
--> Working on JSON
Fetching http://www.cpan.org/authors/id/I/IS/ISHIGAKI/JSON-4.10.tar.gz ... OK
Configuring JSON-4.10 ... OK
==> Found dependencies: Test::More
--> Working on Test::More
Fetching http://www.cpan.org/authors/id/E/EX/EXODIST/Test-Simple-1.302195.tar.gz ... OK
Configuring Test-Simple-1.302195 ... OK
Building and testing Test-Simple-1.302195 ... OK
Successfully installed Test-Simple-1.302195
Building and testing JSON-4.10 ... OK
Successfully installed JSON-4.10
2 distributions installed
[root@aabe6178c007 /]#

So as you can see you do not need the word install there. Running echo $? the return code was 1, so this is the step that broke your build.

Side notes

  • If you are running the container without changing your user inside it (we didn't see the Dockerfile so I can't tell) the package sudo is redundant.
  • As you are still root while installing the packages using sudo in the command && sudo cpanm install JSON; is certainly redundant.
  • Apparently there's a dummy package called install in cpanm just for such an occasion.
ikegami
  • 367,544
  • 15
  • 269
  • 518
Uberhumus
  • 921
  • 1
  • 13
  • 24
3

This doesn't answer your question, but I recently had to debug a cpanm situation by figuring out how to find the cpanm errors (although setting --verbose can work too). I wanted to grab the build log for a failed build.

First, find the container ID of whatever the build left behind. This is likely the most recent container, but also the command will have the start of the PERL_CARTON_MIRROR environment variable:

$ docker ps -a
CONTAINER ID   IMAGE                    COMMAND     ...
2eae7f9e757a   9e2398121731             "cpanm …"   ...

Commit that container to an image by using the container ID (the first column):

$ docker commit 2eae7f9e757a
sha256:6887b59a7ed957c3ff38d0652929847a1ef200461e8f117c6a2746f066206b3f

Now grab the cpanm build log:

$ docker cp -L 6887b59a7ed9:/root/.cpanm/build.log build.log
brian d foy
  • 129,424
  • 31
  • 207
  • 592
1

Firstly cpanm is not a package in CentOS. I would recommend breaking the install steps into separate RUN commands just for the sake of maintaining the image (and seeing errors).

FROM centos:7.9.2009
RUN yum install -y perl sudo perl-App-cpanminus
RUN yum clean all
RUN cpanm install --notest JSON Config::Tiny

Secondly, there is no need to sudo cpanm. If you install cpanm I don't see why you'd want to install Config::Tiny via yum, so instead I would install it with cpanm.

Breaking these commands up reveal the actual error, being cpanm is not a package you can install on CentOS. It is: perl-App-cpanminus instead.

Rawley Fowler
  • 1,366
  • 7
  • 15