How to get started with Docker
01 Dec 2018Running a Docker image
Docker is way to run a specific application without
having to install it, or compile it and deal with all the dependencies. In
Ubuntu, it was very easy to install the docker software from the command line.
On Mac, you can look at that post. Once this is done,
you need to identify the image you want to run. A Docker image is a container a
certain set of applications. To run that image, you can type in the command line
docker run <image>
If you have never run that image before, the first
time you execute that command, docker will download the image and all other
stuff it needs. If you want to download the image without running it, you can
instead do docker pull <image>
.
A few options make the whole Docker experience a lot more useful. In
particular, you typically want that image to be opened in an interactive shell.
For that, you need the options -it
. Another useful feature is to be able
to access some folders of your local hard drive from within the image; this can
be done with the option -v LOCAL_FOLDER:DOCKER_FOLDER
.
For example, when running the Fenics Docker image, I would do
docker run -t -i -v /home/ben/Work/fenicstools:/home/fenics/fenicstools -v /home/ben/Work/hippylib:/home/fenics/hippylib fenics20171
to have access to my local fenicstools
and hippylib
folders.
In another example, to run a tensorflow Docker image, I did
docker run -t -i -v
/home/ben/Work/Programmation/Python/mlds/tensorflow/:/home/tf/
tensorflow/tensorflow bash
The bash was required here as by default the
tensorflow image starts a notebook.
Actually you start in the /notebook
folder, and need to navigate to the
folder you defined cd ../home/tf
. But once you figure this out, everything
works great.
Running a jupyter notebook using a Docker image
I found the solution in this StackOverflow post. First you need to publish a port of the container to the host (your laptop),
docker run <...> -p 8888:8888 <your_image> bash
Inside your Docker image, you can start the jupyter notebook,
jupyter-notebook --ip 0.0.0.0 --no-browser --allow-root
Now on your local machine, from your browser, navigate to localhost:8888/tree
.
You will be prompted with a menu asking for a token. After starting the jupyter notebook,
you’ll get a http adress which contains the sequence :8888/?token=<...>
.
Your token is made of all the alphanumeric characters following the equal sign.
Creating a Docker image
You can save all the characteristics of the image you want to create in a Dockerfile, then build the corresponding image by doing, if you’re in the same directory as the Dockerfile,
docker build -t <name>:<tag> .
For instance docker build -t local/ben:latest .
.
You can also specify the modules you want installed in a Pipfile that you load as part of your Docker file, then install with pipenv
. In that case, you need to first generate the lock file, then install all the modules. For instance,
# Python dependencies
RUN pip install pipenv==2018.11.26
ADD ./Pipfile ./
RUN pipenv lock
RUN pipenv install --system
Another way to build the image which may be more flexible is to use a docker-compose.yml
file
(see here) and execute it through
docker-compose up <name_specified_in_yml>
The up
, by default will start the container after building and creating it. To prevent this from happening, you can pass the option --no-start
.
Note: I had a lot of trouble with docker-compose
.
Dockerfile and absolute path
Sometimes you want to create a docker image with files that are in a different
directory. However, you can’t do that with docker. When you define an absolute
path inside your Dockerfile, this refers to the absolute path in the build
context. A work-around is to create your docker image from a place where you can
access (in relative path) all the files you need. And if you want your
Dockerfile to be somewhere else, you can use the -f
option,
docker build -f /home/Dockerfile -t mytag .
Pruning Docker
Docker have a very conservative approach to garbage collection, it seems, and keep everything unless you asked it to delete it. The problem is that if you’re not careful, you can end up filling up all your available memory, and you can’t build/pull any images. The solution is to either (1) increase the amount of memory Docker can use, or (2) prune all the images/containers/… that you don’t need anymore. To prune everything at one, just do
docker system prune --volumes
docker
linux
notebook
]