HowToDocker

HowTo Docker

What is Docker ?

Docker is a software that allows you to create containers inside an operating system, where you can install software and run your code in without modifying the main operating system. It comes from this need to have “generalized virtual environments”, where you can also put in an environment the software you use (installed with apt-get) and not only the python modules.

docker vs vm

Before docker, the way to do that was using virtual machines. But a virtual machine is a simulated operating system, i.e. it’s very heavy. Docker on the other side is really lightweight and allows quick communication between your software and the hardware of the machine.

Why should I use Docker ?

For the same reason you should use virtual environments:

  • allows you to organize what software (and what version you need).
  • allows you to deploy quickly on other machines (e.g. computing servers)
  • prevent you from breaking other people’s code (and even yours) as everything that you change is in your container.

How can I create containers ?

In order to create a container, you need an image. The container is instantiated from an image. The image contains “the source code” and the container is the programmed launched (from the source code). With one source code, you can launch several times your program. It’s the same with the container. You can have an image containing python3 and every dependence you need (e.g. opencv, pytorch, …) and instantiate one (or more) containers that would have these programs installed.

Where do I get the image ?

There are to way to get an image:

  • get the image from the Docker Hub (containing tons of pre-made images like ubuntu, python, …)
    use docker pull: docker pull debian:jessie
  • create the image from a Dockerfile
    use docker build: docker build . from the directory where your Dockerfile is.

You can create Dockerfile yourself or find some online.

Docker workflow

How do I create a container from an image ?

To do so, you can use the command docker run image_name. This would instantiate a new container and automatically give it an ID and a name from the image.

If the image you are using to instantiate your container is not available locally, it will be downloaded and saved locally for future runs.

This is the most important command, and it has a tons of useful options. The complete command is :
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

Here as you can see, when you run a container, you actually instantiate it from the image and run a specific command. For example, if you have in your image named cvdetect a folder /myprograms/detection.py, you can use
docker run cvdetect python3 /myprograms/detection.py --camera 1. This will:

  1. Instantiate a container from an image
  2. Run your python script inside this container

As bash is a program, you can (if installed) run:
docker run -it ubuntu bash (you need the -it option here), this makes the container interactive, thus allowing you to connect to it. By default, containers run programs without being interactive and you cannot connect to it.

Useful [OPTIONS] are:

  • -it: allowing you to have an interactive container (you can run commands inside it, i.e. inside bash)
  • -v host/dir:cont/dir: allowing you to connect host directory to container directory, i.e. all data that is present in host/dir will be readable and all saved data in cont/dir will persist on the machine even if the container is removed.
  • --gpus all allows the container to use nvidia gpu(s). You need to have nvidia-container-toolkit installed for it. Please look here for more info.
  • --name container_name give a specific your container (otherwise randomly attributed)

How to manage the images and containers on my machine ?

The images

  • To list: docker images
  • To remove: docker rmi image_name
    Note that you can’t remove an image if a container using it is still instantiated on your machine

The containers

  • To list: docker ps -a
    containers are processes so use docker ps, the -a option indicating you want to see the all containers (the one that are running and the one that have been killed).
  • To remove: docker rm [container_name|container_id]

Back on creating an image

From a Dockerfile

You can use an existing Dockerfile and modify it to add your desired commands. The best way (most common) to create image. You end up with a text file with instruction on how to build an image. It’s lightweight and open (people can check what is inside).

A Dockerfile usually use these commands:

  • FROM Imagename indicating an existing image you wish to build upon.
  • RUN command to indicate what command to be run when creating the image (usually apt-get install …)
  • ENV VAR value defines an environment variable and assigns the value.
  • WORKDIR path set the working directory for the following command (e.g. run or python3 install)
  • COPY path/to/content path/in/cont to copy a file/folder into the container.
  • ADD url does the same as copy but with urls and allows you to extract a tar directly inside.

Using commit

You can also commit your changes to create an image from a container. As containers are unmutable, you can’t commit on top of an existing image but always have to create a new one (you can use docker rmi to delete the old one, see above).

To commit, use:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]],
e.g. docker commit my_container_test ubuntu_perso:latest