Module 16 · Docker for Bioinformatics

What is Docker & Why Bioinformaticians Need It

Understand the reproducibility crisis in bioinformatics, what containers actually are under the hood, and why Docker has become the standard for sharing computational pipelines.

🐳 Week 22 · Phase 3 — Advanced & Specialised
🐳 Docker ⚗️ Reproducibility 📖 Conceptual · Lesson 1 of 8 · ⏱ ~35 min

01 The reproducibility crisis in bioinformatics

Imagine this scenario: you spend three months building an RNA-seq pipeline to analyse your sorghum transcriptome data. It runs perfectly on your Ubuntu machine in Gießen. You send the scripts to a collaborator in Tokyo. They run the exact same code and get different results — or the pipeline crashes entirely.

This is not a hypothetical. It is one of the most documented problems in computational biology. A 2016 survey found that more than 70% of researchers had failed to reproduce another scientist's results. In bioinformatics specifically, the problem is acute because a single pipeline depends on dozens of interlocking software versions.

🔬

Why does this happen? STAR 2.7.9 and STAR 2.7.10 produce different alignment statistics on the same reads. GATK 4.2 and GATK 4.3 have changed default parameters. DESeq2 0.99 and DESeq2 1.40 produce different normalisation results. Multiply these version gaps across 15 tools in your pipeline and you have a combinatorial nightmare.

The traditional solutions each have serious problems:

Approach The problem
README with software versions Users still have to install everything manually. Dependencies conflict. "Works on my machine."
conda environments Better, but environment.yml can still behave differently across operating systems. conda can't reproduce system-level libraries.
Virtual machines (VMs) Reproducible, but enormous (10–50 GB). Slow to start. Hard to share. Not practical for HPC clusters.
Docker containers ✅ Lightweight, fast, portable, version-pinned, shareable as a single image. The current gold standard.

Docker is the answer the bioinformatics community has converged on. Journals like Nature Methods and Bioinformatics increasingly expect that published pipelines ship with a Dockerfile. Workflow frameworks like Nextflow and Snakemake have built-in Docker support. Learning Docker is not optional for a modern bioinformatician — it is foundational.

02 Virtual machines vs containers — what is the actual difference?

To understand Docker, you need to understand what it replaced and why it is fundamentally different — not just faster, but architecturally different.

Virtual machines (VMs): simulating entire hardware

A virtual machine uses a piece of software called a hypervisor (e.g. VirtualBox, VMware, KVM) to simulate a complete physical computer inside your real computer. When you run a VM, you are running a fake CPU, fake RAM, fake hard disk — all simulated. On top of that fake hardware, you install a complete operating system (the "guest OS"), and on top of that, your actual software.

🏗️ Analogy

A VM is like building a complete second house inside your house — walls, plumbing, electrical, the whole thing — just so you can use one specific piece of furniture in it. Completely isolated, completely reproducible, but enormously wasteful.

Containers: sharing the host kernel

A container takes a completely different approach. Instead of simulating hardware, it uses Linux kernel features — specifically namespaces and cgroups — to create isolated environments that share the host machine's kernel directly.

Namespaces isolate what a process can see: its own filesystem, its own network, its own process list — even though the host kernel is running everything. Cgroups limit what a process can use: CPU time, RAM, disk I/O. Together, they create the illusion of an isolated machine without actually simulating one.

🏗️ Analogy

A container is like partitioning your existing house into separate rooms with separate locks — each room has its own furniture, its own key, and cannot see into other rooms. But they all share the same roof, foundation, and plumbing. Much cheaper to build. Much faster to create and destroy.

Property Virtual Machine Docker Container
Startup time Minutes (full OS boot) Milliseconds to seconds
Size on disk 5–50 GB per VM 50 MB – 2 GB per image
Isolation level Complete hardware emulation Kernel-level namespace isolation
OS required inside Full guest OS always Minimal OS layer only (or none)
Portability Difficult — VM format varies Excellent — runs anywhere Docker runs
HPC cluster support Rarely supported Supported via Singularity/Apptainer
Performance overhead 10–30% CPU overhead < 1% CPU overhead (near-native)
Sharing mechanism Copy enormous image files Push/pull from Docker Hub (layered)
💡

Important caveat: Docker containers on Linux share the Linux kernel directly. On Windows and macOS, Docker runs a lightweight Linux VM behind the scenes (Docker Desktop), so there is a small additional layer. This is why Docker is fastest and most natural on Linux — which is exactly the environment you will use for bioinformatics work.

03 Core Docker concepts — the vocabulary you must know

Docker has a small vocabulary of terms that are used precisely and consistently everywhere. Confusing "image" with "container" is the most common beginner mistake. Here is what each term means:

📄
Dockerfile
A plain-text recipe file that describes how to build an image. It lists a base OS, software to install, files to copy in, and commands to run at startup. You write this once; Docker reads it to build the image.
🖼️
Image
A read-only snapshot of a filesystem built from a Dockerfile. Think of it as a template or a blueprint — it exists on disk but is not running. You push/pull images to/from Docker Hub. Multiple containers can run from the same image simultaneously.
📦
Container
A running instance of an image. The image is the class; the container is the object. A container has its own writable filesystem layer on top of the read-only image. You can start, stop, pause, and delete containers independently.
🗃️
Registry
A server that stores and distributes Docker images. Docker Hub (hub.docker.com) is the default public registry. Biocontainers (biocontainers.pro) is a registry specifically for bioinformatics tools — every tool in Bioconda has a corresponding Docker image there.
🔖
Tag
A label on an image that usually encodes the software version. samtools:1.18 and samtools:1.19 are the same tool, different versions. Always pin your tags in production — never use :latest for reproducible pipelines.
📂
Volume
A persistent storage mechanism that exists outside the container's writable layer. When a container is deleted, its writable layer disappears — but data in a volume persists. Critical for keeping your FASTQ files and results accessible on the host filesystem.
🏗️
Layer
Docker images are built in layers — each instruction in a Dockerfile creates a new layer. Layers are cached and reused across builds. If you change line 20 of a Dockerfile, Docker only rebuilds from line 20 onward. This is why Docker builds are fast.
🧩
Docker Daemon
The background service (dockerd) that actually manages containers and images. The docker command you type in the terminal is a client that talks to this daemon via a socket.
🔑 The most important distinction

Image ≠ Container. An image is a static file on disk — like a frozen snapshot. A container is a live, running process that was started from that snapshot. You can run 10 containers simultaneously from the same image (e.g. 10 parallel STAR alignment jobs). Deleting a container does not delete the image. Deleting an image while containers are running from it will fail.

Advertisement In-feed ad unit — AdSense / sponsor content goes here

04 How Docker is actually used in bioinformatics today

Docker is not just a theoretical tool — it is baked into the infrastructure of modern bioinformatics at every level. Here is where you will encounter it in real research workflows:

1. Biocontainers: one image per tool

The Biocontainers project (biocontainers.pro) automatically builds a Docker image for every package in Bioconda. This means that instead of installing STAR, samtools, GATK, and FastQC manually, you can run each tool from its own pre-built, version-pinned container with a single docker pull command.

bash — pulling a Biocontainers image
# Pull a specific version of STAR from Biocontainers
docker pull quay.io/biocontainers/star:2.7.11b--h43eeafb_0

# Pull samtools 1.18
docker pull quay.io/biocontainers/samtools:1.18--hd87286a_0

# Pull FastQC
docker pull quay.io/biocontainers/fastqc:0.12.1--hdfd78af_0
🧬 Why this matters for your research

When you publish your sorghum RNA-seq analysis, your reviewer can reproduce your exact results by pulling the same three images with the same tags. No "I couldn't install STAR" emails, no version drift, no missing library errors. The tag 2.7.11b--h43eeafb_0 uniquely identifies every dependency compiled into that image, down to the C compiler version.

2. Nextflow and Snakemake native Docker support

Both major workflow managers in bioinformatics support Docker natively. In Nextflow, you specify a Docker image per process and Nextflow automatically pulls it and runs each step inside the container. Your pipeline becomes entirely self-contained — collaborators just need Nextflow and Docker installed.

nextflow — using Docker per process
// nextflow.config — Docker enabled globally
docker.enabled = true

// main.nf — each process specifies its own image
process STAR_ALIGN {
    container 'quay.io/biocontainers/star:2.7.11b--h43eeafb_0'

    input:
      path reads
      path genome_index

    output:
      path "*.bam"

    script:
    """
    STAR --runThreadN 8 \
         --genomeDir ${genome_index} \
         --readFilesIn ${reads} \
         --outSAMtype BAM SortedByCoordinate
    """
}

3. HPC clusters via Singularity / Apptainer

Most HPC clusters (like those at JLU Gießen or GWDG) do not allow Docker itself because it requires root privileges. Instead, they use Singularity (now called Apptainer), which can directly convert Docker images to Singularity format. This means you build and test with Docker locally, then run the exact same image on the cluster via Singularity — no root needed.

bash — converting a Docker image to Singularity on HPC
# On the HPC cluster — convert Docker image to Singularity .sif file
singularity pull --name star.sif \
    docker://quay.io/biocontainers/star:2.7.11b--h43eeafb_0

# Run STAR inside the Singularity container
singularity exec star.sif \
    STAR --runThreadN 8 \
         --genomeDir /data/sorghum_genome/ \
         --readFilesIn sample1_R1.fastq.gz sample1_R2.fastq.gz

4. Galaxy, CWL, and cloud platforms

The Galaxy platform (usegalaxy.org) runs every tool inside a Docker container. The Common Workflow Language (CWL) standard — used to describe portable bioinformatics workflows — uses Docker images to specify tool environments. AWS, Google Cloud, and Azure all support Docker-based batch computing for large genomics jobs.

⚠️

A note on rrBLUP and BGLR containers: The Bioconductor Docker images (e.g. bioconductor/bioconductor_docker) include R and most Bioconductor packages. You can build a custom image on top of this that adds rrBLUP and BGLR, giving your genomic selection pipeline a fully reproducible R environment. We will do exactly this in Lesson 7.

05 Docker's architecture — what happens when you type docker run

When you type docker run ubuntu:22.04 bash, a surprisingly sophisticated sequence of events happens in milliseconds. Understanding this sequence prevents confusion when things go wrong.

🔄 The docker run sequence — step by step

Step 1 — Client → Daemon: Your terminal's docker command sends a request to the Docker daemon (dockerd) via a Unix socket at /var/run/docker.sock.

Step 2 — Image check: The daemon checks if the ubuntu:22.04 image exists locally. If not, it automatically pulls it from Docker Hub.

Step 3 — Container creation: The daemon creates a new container — a writable filesystem layer on top of the read-only image layers, plus isolated namespaces (filesystem, network, PID, user).

Step 4 — Network setup: The daemon attaches the container to a virtual network bridge and assigns it an IP address.

Step 5 — Process launch: The daemon starts the requested process (bash) inside the container's namespace as PID 1.

Step 6 — Output: Stdin/stdout/stderr are connected back to your terminal.

The key architecture components are:

Component What it is Where it lives
Docker CLI The docker command you type. Just a client that sends API calls. Your terminal session
Docker Daemon (dockerd) Background service that manages containers, images, volumes, and networks. Host OS (runs as root)
containerd Lower-level container runtime that dockerd delegates to. Also used independently by Kubernetes. Host OS
runc The actual binary that calls Linux kernel namespaces/cgroups to start the container process. OCI-compliant. Host OS kernel interface
Docker Hub Public image registry. Default source for docker pull. Cloud (hub.docker.com)
Image layers Read-only filesystem snapshots stored in /var/lib/docker/overlay2/ Host disk
Container layer Writable layer unique to each container. Deleted when the container is removed. Host disk (temporary)
🧱

The overlay filesystem: Docker uses a union filesystem (usually OverlayFS on Ubuntu) to stack read-only image layers under a single writable container layer. When a container modifies a file that exists in a read-only layer, the file is copied up to the writable layer first (copy-on-write). This is why containers start instantly — they do not copy the entire image, just create a thin writable layer on top.

What gets isolated and what does not

Containers are isolated but not fully sandboxed like VMs. This matters for security and for understanding what your pipeline can and cannot access:

Resource Isolated by default? Notes
Filesystem ✅ Yes Container sees its own root filesystem. Host filesystem not visible unless explicitly mounted.
Network ✅ Yes Container has its own virtual network interface and IP. Ports must be explicitly exposed.
Process list ✅ Yes Container only sees its own processes. Cannot see host processes.
Users/UIDs ✅ Yes User namespace isolation. Root inside container ≠ root on host (in rootless mode).
Linux kernel ❌ Shared All containers share the host kernel. A kernel exploit breaks all containers.
CPU / RAM ❌ Shared (unless limited) Containers share host resources. Use --memory and --cpus flags to set limits.
GPU ❌ Not by default Requires --gpus all flag and NVIDIA Container Toolkit for GPU access (e.g. for deep learning variant callers).

06 Knowledge check exercises

These are conceptual exercises for Lesson 1 — no terminal needed yet. Lesson 2 is where you install Docker and run your first container.

1
Image vs Container distinction

You have an image called star:2.7.11b on your laptop. You start three separate STAR alignment jobs simultaneously, each processing a different FASTQ file. How many images exist? How many containers exist? Can you delete the image while the containers are running?

▶ Show answer

1 image exists — star:2.7.11b is a single read-only snapshot on disk. All three alignment jobs run from the same image.

3 containers exist — each running STAR alignment job is a separate container with its own writable layer and its own isolated process.

You cannot delete the image while containers are running from it. Docker will refuse with an error. You must stop and remove the containers first, then remove the image.

2
The reproducibility scenario

Your sorghum RNA-seq pipeline uses: STAR 2.7.10a, samtools 1.17, featureCounts 2.0.3, and DESeq2 1.38. A reviewer asks you to make this pipeline reproducible. You have two options: (A) write a detailed README with installation instructions, or (B) create a Docker image containing all four tools. What are the specific advantages of option B that option A cannot provide?

▶ Show answer

Option B (Docker) provides several guarantees that a README cannot:

1. Exact binary reproducibility: The Docker image captures not just the tool version but the exact compiled binary, including its linked C libraries, compiler version, and build flags. Two machines running the same image run the identical binary — not just the same source version compiled differently.

2. Dependency isolation: All four tools and their dependencies are bundled inside the image. There is no possibility of them interfering with the reviewer's system packages or each other.

3. One command to run: docker pull yourname/sorghum-pipeline:v1.0 takes 2 minutes and requires zero installation expertise. A README with 15 conda commands takes 45 minutes and still fails on some systems.

4. OS independence: The image works identically on Ubuntu 20.04, 22.04, Fedora, macOS (via Docker Desktop), and Windows — the reviewer's OS is irrelevant.

5. Version-controlled environment: The Dockerfile that built the image is a text file that can be committed to git alongside your analysis scripts, giving a complete audit trail of every tool version change.

3
Container isolation boundaries

You run a GATK variant calling container on your Ubuntu server. Inside the container, a malicious script tries to: (A) read files in /home/shajedur/data/ on the host, (B) kill a STAR alignment process running on the host, (C) exploit a kernel vulnerability in the host's Linux kernel, (D) use 100% of the host's RAM. Which of these would Docker prevent by default, and which would it not?

▶ Show answer

(A) Read host files: ✅ Prevented by default. The container filesystem is isolated — it cannot see /home/shajedur/data/ unless you explicitly mount it with -v /home/shajedur/data:/data.

(B) Kill host processes: ✅ Prevented by default. The container only sees its own PID namespace — the host's STAR process is completely invisible to it.

(C) Kernel exploit: ❌ NOT prevented. This is the fundamental security limitation of containers. The kernel is shared. A kernel-level exploit could break out of the container entirely. This is why security-sensitive workloads still use VMs.

(D) Use 100% RAM: ❌ NOT prevented by default. Containers share host RAM unless you set --memory 8g to limit the container to 8 GB. Without a memory limit, a runaway process inside the container can cause the host's OOM killer to terminate other processes.

4
Tag pinning — why :latest is dangerous

In January 2024, your pipeline uses docker pull samtools:latest and gets version 1.18. In September 2024, you run the same pull command on a fresh server and get 1.21. Both tags say :latest but they are different software. Explain why this breaks reproducibility and what you should do instead.

▶ Show answer

The problem: :latest is a floating tag — it points to whatever is the newest image at the moment of the pull. It is not a fixed reference. Every time you pull :latest, you may get a different image. This means the January analysis and the September analysis may have used different samtools code, with different default behaviours, bug fixes, and output formats — making the results incomparable even if the rest of the pipeline is identical.

The fix: Always use a specific version tag: docker pull quay.io/biocontainers/samtools:1.18--hd87286a_0. The Biocontainers build hash (hd87286a_0) is especially valuable — it encodes the exact conda build, including all compiled dependencies. This tag will always resolve to the identical binary, regardless of when or where you pull it.

Advertisement 300 × 250 rectangle — AdSense / sponsor banner goes here