Once you’ve installed Docker, there a few basic features to know. In this post you’ll learn about running containers. If you haven’t gotten started with Docker yet, checkout this quick start guide.
You can run Docker containers with a command that takes the following form:
docker run [options] <image name> [command]
The only required element is the image name. So for example, to run
minimal-notebook image in a container, use the image name
docker run jupyter/minimal-notebook
This runs the default command in the image and streams logs to stdout
(you can quit by pressing
ctrl+c), which can sometimes be useful. But
in this case, the default command is starting a Jupyter notebook server,
which is not useful if we don’t have access to port 8888 on the
Fortunately, we can expose this port using the
-p flag (p is for
docker run -p 8888:8888 jupyter/minimal-notebook
Now we’ve done something useful. The notebook command prints out a URL in the logs with a token parameter. If you visit that link, you will be in a Jupyter notebook hosted on the container.
If we were already using port 8888 on our local machine or in another container, we could pick a different port to map to 8888 on the container.
docker run -p 8889:8888 jupyter/minimal-notebook
Now we will need to modify the URL printed to stdout, by substituting
8889 for 8888. This means you’ll need to navigate to a URL like
http://localhost:8889?token=<some token> even though the container
Overriding the default command
It’s a pain to have to get the URL from the logs before we can use it.
minimal-notebook container is running an executable script called
start-notebook.sh (see the script
This will take arguments and pass them to the
command. This gives us the opportunity to disable token-based
docker run -p 8888:8888 jupyter/minimal-notebook start-notebook.sh --NotebookApp.token=''
Now we can visit the notebook server by simply navigating to
localhost:8888. But we still have a problem. Any work we do in a
notebook will not be saved after we exit the container. This is probably not what you want.
The best way to save code you write in a container is to mount a data
volume from your host machine. For this, you use the
-v flag (v is for
“volume”). The working directory in the container is
/home/jovyan/work, which is where the notebook will be launched. A
good bet is to give the host access to this directory. I like keeping
code in my
~/code directory so I’ll create a folder called
~/code/minimal-notebook-scratch. Feel free to make a folder wherever you
want and substitute it in your run command.
docker run -v ~/code/minimal-notebook-scratch:/home/jovyan/work -p 8888:8888 jupyter/minimal-notebook start-notebook.sh --NotebookApp.token=''
Now if you start a notebook and write some code, the notebook will live
~/code/minimal-notebook-scratch when you quit the container. In
fact, anything you change in the
/home/jovyan/work directory within
the container will also change in the
folder on your machine. Pretty handy.
Running the container in different modes
There’s one more irritating thing about this setup to take care of. The
container will die if we close the Terminal tab, or if we accidentally
ctrl+c. When you’re running something like a server in a container, it’s usually nice to run it in detached mode. This is done with the
-d flag (d is for
docker run -d -v ~/code/minimal-notebook-scratch:/home/jovyan/work -p 8888:8888 jupyter/minimal-notebook start-notebook.sh --NotebookApp.token=''
This time, you will see a container ID on the screen but no logs from the container. That’s because the container is running in the background. You can watch the logs of a detached container with
docker logs -f <container ID> and you can kill and delete a container with
docker rm -f <container ID>. If you forget the container ID, just run
docker ps to see the IDs of all the running containers.
If you’re debugging an image, you can run the container in interactive
mode using the
-t flags together:
-it (i is for
“interactive”, but I’m not really sure about the t).
docker run -it -v ~/code/minimal-notebook-scratch:/home/jovyan/work -p 8888:8888 jupyter/minimal-notebook start-notebook.sh --NotebookApp.token=''
You now know enough about
docker run to be dangerous. Go forth and containerize all the things.