An Introduction to Basic Docker Commands

This entry is part 2 of 2 of 3 in the series Containers

Author: Chad Vizino, Software Engineer

In my last article I wrote about Linux containers and how they provide a nimble alternative to setting up a Linux environment using a virtual machine. I also introduced Docker, a container management system that has become very popular due to its ease of use. In this article I’ll present an introduction to some of the basic Docker commands. I’ll conclude with a use case that you can try on your own system to help you discover how you might be able to benefit from Docker for your own work.
First, let’s get Docker installed and start a simple session. I’ll be using a Linux CentOS 7 host system for this example session. Note that you will need to have root privileges on your system to perform these steps. If you’d prefer to try this under Windows or Mac OS, follow these instructions to install a Docker environment and then skip to step 4 below.

https://docs.docker.com/installation/windows/
https://docs.docker.com/installation/mac/

# Step 1. Install docker on your system.
yum install docker

# Step 2. Edit /etc/sysconfig/docker
# Add the following to the OPTIONS value:
#   –storage-opt dm.no_warn_on_loop_devices=true

# Step 3. Start the docker daemon.
systemctl start docker

# Step 4. Show container images on your system.
# Note that there are none since none have been loaded yet.
docker images

# Step 5. Start an interactive bash shell under an Ubuntu 14.04 container.
# Note that the first time you run this, an Ubuntu 14.04 container
# image will be downloaded from the Docker Hub and may
# take a minute or two depending on your network connection.
docker run -i -t ubuntu:14.04 /bin/bash

# Step 6. Confirm your environment within the container.
cat /etc/os-release

# Step 7. Exit the container.
exit

# Step 8. Show container images locally cached your system.
docker images

That’s it. You’ve just run your first container! You can repeat steps 4-7 as many times as you like. Note that subsequent “docker run” invocations will start quicker since Docker caches images locally (as shown in Step 8).

Now let’s look at a use case. Suppose that you want to set up a development environment so that you can build and run a program.

# Start a shell in Ubuntu.
docker run -i -t ubuntu:14.04 /bin/bash
# Install gcc C compiler
# and exit container.
apt-get update
apt-get install gcc
exit

We’ve exited the container and so it would seem that we’ve lost the changes. However, previous containers are saved until they are deleted. You can examine the id of the last container:

# List id of last container
docker ps -lq

Let’s save the last container to a named image that you can instantiate later when you want.

# Save previous container to a named image, ubuntu_1404_dev
docker commit `docker ps -lq` ubuntu_1404_dev

Your last container has been saved with a meaningful name and you can observe it by:

# Show images on your system.
# Note the REPOSITORY column.
docker images

Now anytime you want to run your Ubuntu development container. You can run it from the image you created:

# Start your saved container.
docker run -i -t ubuntu_1404_dev /bin/bash

You can confirm that the gcc C compiler is already installed:

# Check for gcc.
which gcc

You can now write C programs if you like. If you prefer another compiler or additional packages in your environment, install them in the container before you run “docker commit”. If you work with the container for awhile and realize that you’d like to have other packages installed, install them in the container, exit the container and run another “docker commit” with a meaningful name.

One final, and very useful docker run option to introduce is “–volume”. Using this option you can mount a host file system within the container when you run it. This gives you access within your container to any file you’d like from the host system.

Let’s say your project is in /usr/local/myproject on your host system and you’d like to have access to it from the Ubuntu development container you created earlier. In this example you’ll mount /usr/local/myproject using the same path in the container:

# Start development container with /usr/local/myproject mounted.
docker run -i -t –volume=/usr/local/myproject:/usr/local/myproject ubuntu_1404_dev /bin/bash

You can now change directory to /usr/local/myproject and use the files from this directory. Note that you’ll be running as user root within the container and any new files created in this directory will be owned by root.

Finally, if you wish to clean up any old images you no longer want, you can run “docker rmi” to delete them. For example:

# Remove image.
# Note that the “-f” option forces removal.
docker rmi -f ubuntu_1404_dev

That’s it. In this brief tutorial, I covered installing Docker and then using “docker run” to run a container of your choice, saving changes made within the container by using “docker commit”, and removing images by using “docker rmi”. Hopefully, you’ll be able to put this knowledge to use on your system. However, there are still some issues that may concern you such as running as root in the container and how to share images. I’ll cover these topics in a future article.

Series Navigation<< Introduction to Linux Containers – Part 1Simplifying Batch Jobs with Moab Container Support >>