How to customize and release docker images for your app
In daily work we may have used many kinds of docker images. For me I pretty like the jupyter images which are well maintained.
$ docker run -p 8888:8888 jupyter/scipy-notebook
Here "jupyter/scipy-notebook" is the image name. How can I customize and release an image for my own app? I will show you the guide step by step.
First, we create a project dir whose name is "docker-proj". There are two important stuff in it.
- Dockerfile
- App files
App file is anything you just want to run in docker. For instance, mine in this case is a perl script. This script uses a module from CPAN, Gmail::Mailbox::Validate, which checks if the given username has a valid mailbox on gmail.
The demo code for this app are,
use Gmail::Mailbox::Validate;
use strict;
my $username = shift || die "$0 username\n";
my $v = Gmail::Mailbox::Validate->new();
print $username,
$v->validate($username) ? " exists\n" : " not exists\n";
Save the code in script "gmbox.pl", and run it you will see the output as follows.
$ perl gmbox.pl
gmbox.pl username
$ perl gmbox.pl lisaleung
lisaleung exists
Put the script into dir "docker-proj". And, create Dockerfile in the same dir with the following content.
FROM perl:5.34
RUN cpanm Gmail::Mailbox::Validate && mkdir -p /usr/src/app
COPY gmbox.pl /usr/src/app
WORKDIR /usr/src/app
ENTRYPOINT [ "perl", "./gmbox.pl" ]
Some comments on above configuration,
- FROM - we are using image perl 5.34 as base image
- RUN - run the commands to install modules from CPAN and create a work dir
- COPY - copy app files from local to docker image
- WORKDIR - step into work dir
- ENTRYPOINT - the command should be run when docker instance starts up
In current dir where the subdir "docker-proj" is located, run the following command to build an image.
$ docker build -t gmbox docker-proj/
Here "gmbox" is the image name, which you can check by this command.
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
gmbox latest 38fca2257430 2 minutes ago 894MB
Now please go to dockerhub.com creating an account. You will use this account ID to build the official image.
For instance, my account name is "geekml", then the official name for my image is "geekml/gmbox".
Let's tag the image we just made in local,
$ docker tag gmbox geekml/gmbox:latest
Log into dockerhub in terminal,
$ docker login
Input the account name and password you have created in dockerhub.com to login.
The last step is to push the tagged image to dockerhub.
$ docker push geekml/gmbox:latest
The push refers to repository [docker.io/geekml/gmbox]
b4c22e3253a2: Pushed
...
latest: digest: sha256:9fdead1956eeb93735f8301cbd34440f9383969d9729336d0d29f567c027a41a size: 2212
So you can run this docker image from everywhere. For instance, in another host just pull the image,
$ docker pull geekml/gmbox
Using default tag: latest
latest: Pulling from geekml/gmbox
...
18f60cd0e987: Pull complete
Digest: sha256:9fdead1956eeb93735f8301cbd34440f9383969d9729336d0d29f567c027a41a
Status: Downloaded newer image for geekml/gmbox:latest
docker.io/geekml/gmbox:latest
And run the image as a container,
$ docker run geekml/gmbox johnlee
johnlee exists
Check the image you have pulled down,
$ docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
geekml/gmbox latest 38fca2257430 17 minutes ago 894MB
All jobs done well now.