Earlier we saw how to get started with Perl on Docker.

This time we'll have a simple script and distribute it using Docker.

If the simple script only uses standard Perl modules, then we might not need this extra work, but in this example we'll have a script that uses Image::Magick.

The script

This is the script I'd like to distribute:

examples/perl-script/bin/script.pl

use 5.010;
use strict;
use warnings;

use Getopt::Long qw(GetOptions);
use Image::Magick;

my $server = 'localhost';
my $verbose;

GetOptions(
    'server:s' => \$server,
    'verbose'  => \$verbose,
) or die;

say "running on $]...";

if ($verbose) {
    say $server;
}

It loads the Image::Magick library though it does not actually uses it. I did not want the script to be complex.

It also loads the Getopt::Long module to demonstrate how we can pass parameters to the script.

There is really nothing fancy here.

The Dockerfile

examples/perl-script/Dockerfile

FROM ubuntu:18.04
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y libimage-magick-perl

# install modules that are needed

WORKDIR /opt
COPY bin/script.pl /opt/script.pl

ENTRYPOINT ["perl", "script.pl"]

In this example we rely on Ubuntu 18.04, but you can use any other image.

In this case I opted to use the system Perl and to install the necessary Perl modules using apt-get. Alternatively you could download and compile your own version of Perl and then install modules using cpanm. Which approach to use depends on your needs.

Using the RUN command we update and upgrade all the packages that came with the Docker image and then we install the Perl module we need. (Note the -y parameters that will tell apt-get to say yes to its own questions.

Here you could install any other package distributed by Ubuntu.

Then we create a working directory and COPY the script from the directory on the host machine to the /opt directory of the Docker image we are creating.

Unlike in the get started case when we wanted to have the script on the host machine to make it easy to edit it, this time we would like it to be part of the Docker image so we can distributed it easily.

Finally we use the ENTRYPOINT directive in the Dockerfile to tell docker what to execute when the container starts to run.

Directory layout

Jut to be clear the directory layout for this project is:

project-root/
    Dockerfile
    bin/
        script.pl

Building the Docker image

I assume you have already installed Docker and the daemon is running.

This command executed in the project-root directory where the Dockerfile can be found. Th name "mydocker" is arbitrary. You can use anything there.

$ docker build -t mydocker .

Running the script in the Docker image

The --rm option is needed so the container will be removed after the execution is finished. The name we chose above when we build the image is needed here again.

After that we can pass the parameters we would want to pass to the script.

$ docker run --rm mydocker
running on 5.026001...

$ docker run --rm mydocker --verbose
running on 5.026001...
localhost

$ docker run --rm mydocker --verbose --server hello
running on 5.026001...
hello

Distributing Private Docker Image

Once we created a Docker image we can distribute it privately to anyone.

Use the save command to create a tar file of the image. You can give any name to the tar file. Then zip it to make it smaller.

docker save mydocker -o my.tar
gzip my.tar

Copy the resulting "my.tar.gz" file to the target machine.

Then on the target machine, where you also have Docker installed and running, unzip the zip file and load the image:

gunzip my.tar.gz
docker load my.tar

After that we can run the image as we did earlier.