The following are the basic steps for developing KBC Docker Images. There is no need to know everything about the Docker stack since this is a very limited set of Docker features. The official Windows, Mac OS X, and other Tutorials are not being replaced here. Before you start, make sure you have Docker installed.
The code discussed below is available in our sample repository.
To create your own image, create a Dockerfile. Dockerfile is a set of shell instructions leading to a configured OS environment. You can think of it as a bash shell script with some specifics. Each Dockerfile should be placed in its own folder because the folder becomes Build Context of the Docker image. Build context contains files which can be injected into the Image. There is no other way to inject arbitrary files into the image other than through the build context or download them from the Internet.
Useful Dockerfile instructions:
FROM: State the base image to start with.
RUN: Execute an arbitrary shell command.
ENTRYPOINT: Set the command which will be executed when the image is run; this is the command that will actually run inside a container. When the command finishes, the container finishes too.
ENV: Set an environment variable, use this instead of
WORKDIR: Set the current working folder.
COPY: Copy files from Build context into the image.
Note that in Dockerfile, each instruction is executed in its own shell. Therefore, the
WORKDIR instructions MUST be used to set environment variables and the current folder.
Create an empty folder, and then create a Dockerfile with the following contents inside the folder.
FROM instruction means we start with our base image
which, in turn, is based on the CentOS image.
The second instruction means that when you run the image, it will ping example.com twice and exit.
When you run
docker build .
you should see an output like this:
Sending build context to Docker daemon 3.584 kB Step 1 : FROM quay.io/keboola/base latest: Pulling from keboola/base a3ed95caeb02: Already exists 3286cdf780ef: Already exists ecfdc5e942e9: Already exists Digest: sha256:cbd64500481e64bff852f8a34ab7fdcd35befb03afabde29adb6cf33643f8e2d Status: Downloaded newer image for quay.io/keboola/base:latest ---> 4ed770742c49 Step 2 : ENTRYPOINT ping -c 2 example.com ---> Running in 2bb58014055f ---> b818507de866 Removing intermediate container 2bb58014055f Successfully built b818507de866
b818507de866 is a volatile image hash which is used to refer to the image and can be abbreviated to first three
b81 in this case).
Additionally, you can name the image by passing the
--tag option, e.g.
docker build --tag=my-image .
After an image has been built, run it using
docker run -i b81 or
docker run -i my-image .
The switch -i is important for receiving an interactive output. You should see an output like this:
docker run -i my-image PING example.com (220.127.116.11) 56(84) bytes of data. 64 bytes from 18.104.22.168: icmp_seq=1 ttl=50 time=121 ms 64 bytes from 22.214.171.124: icmp_seq=2 ttl=50 time=121 ms --- example.com ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 121.615/121.721/121.828/0.364 ms
When building your own image, the ability to run arbitrary commands in the image is very useful. Override the entrypoint using the
option (which means that your application will not execute, and you will have to run it manually). The
option opens interactive terminal:
docker run -i -t --entrypoint=/bin/bash my-image
--entrypoint overrides the
ENTRYPOINT specified in the
Dockerfile. This ensures that a
bash shell is run instead of your application. You then have to run the
ping command, previously defined in the entrypoint, manually.
It is also possible to inspect a running container. Assume you have the following
When you build it using:
docker build --tag=my-image .
Then run the image (create a new container and run the image entrypoint in it):
docker run my-image
Open a new command line window and run:
This will show you a list of running containers - something like:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dafd708d0d7e my-image "/bin/sh -c 'ping exa" 58 seconds ago Up 57 seconds jolly_rosalind
The important part is the container ID. You can then run an arbitrary command in the running container with the following command:
docker exec *container_id* *command*
docker exec -i -t daf /bin/bash
will execute interactive terminal with the bash shell in the container daf (container ID can
be shortened to first 3 letters). Verify that
ping is still running by:
which will give you something like:
PID TTY TIME CMD 1 ? 00:00:01 ping 25 ? 00:00:00 bash 41 ? 00:00:00 ps
Chances are that your application requires something special. You can install whatever you need using standard commands. You can create Dockerfile:
RUN command will install the specified
php-cli package. Build the image with:
docker build --tag=my-image .
and then run the image (and create a new container):
docker run -i my-image
You should see the following output:
Hello world from PHP
When you need to add files into your image, use the build context (which is simply
the folder in which the Dockerfile is and in which you are building the image). Create a
file in the same folder as the Dockerfile with the following contents:
Then change the Dockerfile to:
COPY command copies the entire contents of the folder with Dockerfile into the
folder inside the image. The
ENTRYPOINT command then simply executes the file when the image
is run. When you
docker build and
docker run the image, you will receive:
Hello world from PHP file
RUN export foo=barmakes no sense. Use
ENV foo=barinstruction to create environment variables.
and only once you are sure the image builds correctly and you are happy with the result, change this to:
yum clean alleverywhere.
Now that you are able to create dockerized applications, get yourself familiar with the Docker registry.