4.1. Docker

4.1.1. Building images from scratch

To create a docker container, you can write a recipe file (comparable to a singularity recipe file) named by convention Dockerfile.

An example of Dockerfile:

# base image: Ubuntu
FROM ubuntu:16.04
RUN apt-get update --fix-missing \
&& apt-get install -y git make g++ zlib1g-dev \
&& cd /usr/local/ \
&& git clone https://github.com/OpenGene/fastp.git \
&& cd fastp \
&& make \
&& make install \
&& cd /usr/local \
&& rm -rf fastp \
&& apt-get remove -y git make g++ zlib1g-dev \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/local/bin/fastp"]

This builds and installs fastp on a blank ubuntu. Here, all commands are executed on only one RUN instruction, but each command may be run in a separate RUN instruction. In that case, changing one line of the Dockerfile will affect only following instructions at build stage. See also Best practices for writing Dockerfiles.

We can build the image with:

docker build . -t fastp:0.21.0

This will create an image called fastp version 0.21.0 and will execute all the instructions listed in the Dockerfile (the -t option is to add name and tag to your image).

We can list locally installed Docker images with:

docker images

4.1.2. Reusing already available images

We can also pull already built images from public repositories (such as DockerHub):

docker pull hello-world

You can verify that this new image is now installed locally:

docker images

4.1.3. Running containers

Now, let's run a command in a container based on our fastp image:

docker run -v $PWD:$PWD --entrypoint bash -i -t fastp:0.21.0

It will:

  1. Run a fastp container

  2. Execute bash in this container

  3. Link your current directory to a directory with the same absolute path in the container.

The main command options you might need:

  • -v: bind local folders to container folders

  • -i: Interactive (Keep STDIN open)

  • -t: Allocates a pseudo TTY

  • --entrypoint bash: Changes the default entrypoint, with default entrypoint, just like calling fastp locally

  • -p: Redirects local ports to container ports (useful for web services)

Let's verify if the version of fastp we downloaded and dockerized is 0.21.0:

docker run fastp:0.21.0 -v

4.1.4. Sharing your images

One way to share your Docker images with the community is to upload them to DockerHub. To be able to push your image to DockerHub, you will first need to create a DockerHub account.

We can rebuild our previous image with:

docker build . -t YOUR_DOCKERHUB_USERNAME/fastp:0.21.0

This will create the same fastp image than before but now it will linked your dockerhub account.

We can list again locally installed Docker images with:

docker images

To push locally created images to DockerHub:

docker login
docker push YOUR_DOCKERHUB_USERNAME/fastp:0.21.0

4.1.5. Managing containers/images

We can list all containers (not only the ones running):

docker container ls -a

And do some cleaning, removing containers by ID:

docker rm -vf <ID>

To list all available images:The same can be done for images, Then list and remove images:

docker images

And remove image by ID:

docker rmi <ID>

You can remove also images by their repository:tag, for example let's remove our first image, which is a duplicate:

docker rmi fastp:0.21.0

4.1.6. Exercises

You can practice creating/obtaining Docker images for different bioinformatic tools:

These tools will allow us to map, call variants and define clades using SARS-CoV-2 sequencing data.

You can first organize in groups and coordinate who will create which image.

To help you write Dockerfiles,

  1. Start writing it from our fastp example

  2. Write RUN commands to get the executable (for example bwa) and put it on the PATH (/usr/local/bin for example)

  3. Build the image

  4. Run help command for the chosen executable via Docker : --help

  5. Remove the container and the image (you can anyway rebuild it from the Dockerfile)