Docker Crash Course Part 2: Running and Building Containers
Overview
Teaching: 20 min
Exercises: 0 minQuestions
How can I customize docker images and run them as containers on my machine?
How do I give a running docker container access to files and directories on my machine?
Objectives
Understand how containers help you encapsulate your environment
Practice creating and running docker containers
Running containers
To use a Docker image as a particular instance on a host machine you run it as a container. You can run in either a detached or foreground (interactive) mode.
Run the image we pulled as an interactive container
docker run -it matthewfeickert/intro-to-docker:latest /bin/bash
You are now inside the container in an interactive bash session. Check the file directory
pwd
/home/docker/data
and check the host to see that you are not in your local host system
hostname
Monitoring Containers
Open up a new terminal tab on the host machine and list the containers that are currently running
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
<generated id> <image:tag> "/bin/bash" n minutes ago Up n minutes <generated name>
Volume Mounting
You can make files and directories accessible to the container by mounting them as volumes to the
container with the -v
flag.
This allows for direct access to the host file system inside of the container and for
container processes to write directly to the host file system.
docker run -v <path on host>:<path in container> <image>
For example, to mount your current working directory on your local machine to the data
directory in the example container
docker run --rm -it -v $PWD:/home/docker/data matthewfeickert/intro-to-docker
From inside the container you can ls
to see the contents of your directory on your local
machine
ls
and yet you are still inside the container
pwd
/home/docker/data
You can also see that any files created in this path in the container persist upon exit
touch created_inside.txt
exit
ls *.txt
created_inside.txt
This I/O allows for Docker images to be used for specific tasks that may be difficult to do with the tools or software installed on only the local host machine. For example, debugging problems with software that arise on cross-platform software, or even just having a specific version of software perform a task (e.g., using Python 2 when you don’t want it on your machine, or using a specific release of TeX Live when you aren’t ready to update your system release).
CMD Dockerfile Instruction
If you’re super observant, you may have noticed that the startup command
/bin/bash
was used to start the container in a bash shell when we first ran thematthewfeickert/intro-to-docker:latest
, but the second time we ran the container (when we added the-v $PWD:/home/docker/data
), we didn’t specify a startup command. How did the container still know to start in a bash shell?No, docker doesn’t have mind-reading functionality (yet…). Rather, this behaviour comes from the fact that the Dockerfile used to create this image includes an instruction
CMD ["/bin/bash"]
at the end, where theCMD
command specifies that the container should start up in the bash shell by default if no other startup command is specified in thedocker run
command. If another startup command is specified, likedocker run -it matthewfeickert/intro-to-docker:latest python
then this will override the default set by the
CMD
option, so the container will in this case start up with a python command-line prompt instead (try it out!).
Writing Dockerfiles to Build Images
Docker images are built through the Docker engine by reading the instructions from a
Dockerfile
.
These text based documents provide the instructions though an API similar to the Linux
operating system commands to execute commands during the build.
The Dockerfile
for the example image being used is an example of
some simple extensions of the official Python 3.6.8 Docker image.
As a very simple of extending the example image into a new image create a Dockerfile
on your local machine
touch Dockerfile
and then write in it the Docker engine instructions to add cowsay
and
scikit-learn
to the environment
# Dockerfile
FROM matthewfeickert/intro-to-docker:latest
USER root
RUN apt-get -qq -y install cowsay && \
ln -s /usr/games/cowsay /usr/bin/cowsay
RUN pip install --no-cache-dir -q scikit-learn
USER docker
Dockerfile layers
Each
RUN
command in a Dockerfile creates a new layer to the Docker image. In general, each layer should try to do one job and the fewer layers in an image the easier it is compress. When trying to upload and download images on demand the smaller the size the better.
Don’t run as
root
By default Docker containers will run as
root
. This is a bad idea and a security concern. Instead, setup a default user (likedocker
in the example) and if needed give the user greater privileges.
Then build
an image from the Dockerfile
and tag it with a human
readable name
docker build -f Dockerfile -t extend-example:latest .
You can now run the image as a container and verify for yourself that your additions exist
docker run --rm -it extend-example:latest /bin/bash
which cowsay
cowsay "Hello from Docker"
pip list | grep scikit
python3 -c "import sklearn as sk; print(sk)"
/usr/bin/cowsay
___________________
< Hello from Docker >
-------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
scikit-learn 0.21.3
<module 'sklearn' from '/usr/local/lib/python3.6/site-packages/sklearn/__init__.py'>
Key Points
Dockerfiles let you to customize a base docker image to get the exact environment you want
Volume-mounting lets you specify the exact files and directories on your machine that you want a running container to have access to