In the
previous post I gave an overview of Docker and explained what it takes to run a
simple container. In this post I will be demonstrating Docker images which
provides the basis for running containers. I will go into a bit more detail
about what exactly a Docker image is, how to manage your images and also
demonstrate how to build an image from scratch and have it store locally on
your host.
What is a Docker image?
For those
of us with familiarity in the virtualization space this might come a bit easier
of a concept. A Docker image can be thought of as a template or as source code
for all your containers. Docker images provide the building blocks of
containers and allow us to define characteristics of
containers such as the OS, application and processes running inside the
container. Images are what you use to build and launch your containers and
is what makes Docker so lightweight and portable. Docker images are what
we store in registries that provide us with a git-like functionality of
sharing, updating, deploying and storing. There are a few ways of creating
images such as by pulling already created images from a repo, creating them
from a container or from Dockerfiles.
Managing your Docker images
After
learning a bit more about images its easy to see how important it is to manage
your images. Docker uses public and private registries to help us easily manage
our images. We will just be using the local repo on our host for simplicity
reasons of this post.
Search for
an image:
#
sudo docker search <image_name>
# sudo docker search centos
Pull down
an image locally from repo:
#
sudo docker pull <image_name>
# sudo docker pull centos
Push an
image to the repo:
#
sudo docker push <image_name>
# sudo docker push centos
Remove an image:
# sudo docker rmi <image_name>
# sudo docker rmi centos
Building a Docker image
This
post will demonstrate how to create a custom base image for nginx that you can
use to create and run new containers from. This is a way of ensuring that your
containers are being created the same and customized to fit your environment
and liking. There are a couple of ways doing this. My preferred method is to
use Dockerfiles (which will cover in the next tutorial) but for this demo I
will be using a custom script written from the Docker Github page (Thanks all
you lovely people at Docker!) to build a base image. Another way of course would be to use the
"docker pull" command above. Ill demonstrate how to pull down
a Centos image, customize it, and then use it to deploy my containers from. Ill
be demonstrating using a Centos 6 host and creating a Centos 6 image for
running nginx.
1. Go to the Docker Github
page and grab the mkimage-yum.sh file . Please be sure to check out the other
scripts Docker has provided for other Host OS and other image distributions.
# wget -O ~/mkimage-yum.sh https://raw.githubusercontent.com/docker/docker/master/contrib/mkimage-yum.sh
--2015-03-31 14:30:03-- https://raw.githubusercontent.com/docker/docker/master/contrib/mkimage-yum.sh
Resolving raw.githubusercontent.com... 199.27.78.133
Connecting to raw.githubusercontent.com|199.27.78.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2708 (2.6K) [text/plain]
Saving to: “/root/mkimage-yum.sh”
100%[===================================================================>]
2,708 --.-K/s in 0s
2015-03-31 14:30:03 (229 MB/s) - “/root/mkimage-yum.sh” saved
[2708/2708]
Please note that the
mkimage-yum.sh script will actually automatically run a container from the
image as well. If you don’t want this just comment out line 106 in the script
above:
#docker run -i -t $name:$version echo success
2. Run the script like below. It
will take a minute or two to complete.
# ./mkimage-yum.sh <desire_name_of_image>
# ./mkimage-yum.sh centos6-new
# validate new image is created and imported
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos6-new 6.6 61faa3d658e3 22 seconds ago 237.5 MB
3. Once it completes we can create
a container from that newly created image. We will be attaching to the
container, running the customization stuff and then committing the
container into an image that we can use later.
# docker run -it --name centos6-nginx centos6-new:6.6 /bin/bash
6. Now we can "commit" that container into an image. We will then be able to use that image to create all of our "new nginx" servers.
7. To test out the new image, lets
run a new container from the image on port 8080 of the host and see if we
get a valid website.
4. The above command will attach you to the running container. So just treat this as you would to install and configure nginx on a normal linux server. I used the following steps to complete customizing my nginx environment. NOTE: This is where you would be customizing to fit your environment. GO NUTZ!
[root@dba3856e6c99 ~]# ###created the following directories
[root@dba3856e6c99 ~]# mkdir -p /var/www/website/public_html /var/www/website/log /etc/nginx/sites-available
[root@dba3856e6c99 ~]# ###install nginx
[root@dba3856e6c99 ~]# yum install -y nginx
[root@dba3856e6c99 ~]# ###add the following line to nginx.cong file
[root@dba3856e6c99 ~]# vi /etc/nginx/nginx.conf
[root@dba3856e6c99 ~]# tail -2 /etc/nginx/nginx.conf
include /etc/nginx/sites-available/*;
}
[root@dba3856e6c99 ~]# ###create the virtual host for the website and paste the following text
[root@dba3856e6c99 ~]# vi /etc/nginx/sites-available/website
[root@dba3856e6c99 ~]# cat /etc/nginx/sites-available/website
server {
server_name website;
access_log /var/www/website/log/access.log;
error_log /var/www/website/log/error.log;
root /var/www/website/public_html;
location / {
index index.php;
}
# Disable favicon.ico logging
location = /favicon.ico {
log_not_found off;
access_log off;
}
# Allow robots and disable logging
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
}
[root@dba3856e6c99 ~]# ###start and chkconfig the nginx service
[root@dba3856e6c99 ~]# service nginx status
nginx is stopped
[root@dba3856e6c99 /]# echo "service nginx start" >> ~/.bashrc
5. Logout of the container and check to make sure its exited and no longer running.
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dba3856e6c99 centos6-new:6.6 "/bin/bash" 21 minutes ago Exited (0) 2 seconds ago centos6-nginx
6. Now we can "commit" that container into an image. We will then be able to use that image to create all of our "new nginx" servers.
# docker commit <container_id> <repo>/<image_name>:<tag> ###NOTE: you can also use -m to document the image and -a to document the author
# docker commit dba3856e6c99 centos6/nginx:6.6
d88af477ead3fd48196fd6e4b65c85990965d30df4732e4c8cd7f07d54de8be6
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos6/nginx 6.6 d88af477ead3 8 seconds ago 407.3 MB
centos6-new 6.6 61faa3d658e3 About an hour ago 237.5 MB
# docker run -it -d --name <new-container-name> -p 8080:80
<repo>/<image_name>:<tag> <some_command> ### -d runs in
daemon mode (non attached)
# docker run -it -d --name new-nginx -p 8080:80 centos6/nginx:6.6
/bin/bash
Go
the host IP address on port 8080 in our web browser to validate you get a
screen that looks like the one below.
http://your-ip-address:8080
If
you can see it then you have made it!
Hopefully this has
given a good overview of Docker images as it is one of the most important
aspects of Docker. In the next tutorial Ill demonstrate how to create an image
but using a Dockerfile which is my preferred method.