Building Custom Images (Dockerfiles)
While pulling existing images is useful, the true power of Docker lies in writing your own Dockerfiles. A Dockerfile is simply a text document containing all the commands a user could call on the command line to assemble an environment.
In this section, we will build a custom bioinformatics container capable of taking raw SARS-CoV-2 reads, cleaning them, aligning them to a reference genome, and generating a sorted BAM file.
1. Writing the Dockerfile
First, create a new directory for this project and open a blank file named exactly Dockerfile (no extension):
Add the following "recipe" to your Dockerfile:
# Start from a stable, clean Ubuntu base
FROM ubuntu:22.04 # (1)!
# Prevent interactive prompts from halting the build
ENV DEBIAN_FRONTEND=noninteractive # (2)!
# Update the package manager and install our tools
RUN apt-get update && apt-get install -y \
wget \
fastqc \
fastp \
bwa \
samtools \
&& rm -rf /var/lib/apt/lists/* # (3)!
# Set the default directory when the container starts
WORKDIR /data # (4)!
FROMdefines the base operating system.ENVsets environmental variables. Here, we tellaptnot to ask us[Y/n]questions that would break an automated build.RUNexecutes standard Linux commands inside the image during the build process. Notice how we clean up the downloaded package lists (rm -rf) in the exact same command; this is a strict Docker best practice to keep the final image size small!WORKDIRensures that any time we mount a volume or log into this container, we automatically start in the/datafolder.
2. Building the Image
Now, tell Docker to build this recipe into a ready-to-use image. Run this command in the same folder as your Dockerfile:
The Build Context
Don't forget the period (.) at the end of the command! It tells Docker to look in the current directory for the Dockerfile.
3. Preparing the Data
Let's download our specific SARS-CoV-2 dataset and reference genome to our host machine:
mkdir ~/covid_data
cd ~/covid_data
# Download the raw single-end COVID reads
wget https://biox.unr.edu/ftp/biox_microbiome_workshop/SRR19195566_covid_sra_data.fastq.gz
# Download the reference genome
wget http://ftp.ensemblgenomes.org/pub/viruses/fasta/sars_cov_2/dna/Sars_cov_2.ASM985889v3.dna.toplevel.fa.gz
4. Running the Pipeline
Now we mount our local ~/covid_data directory into our custom covid-pipeline:v1 container and run our tools.
Because we set WORKDIR /data in the Dockerfile, the tools will automatically look in the mounted directory!
Step 1: Index the Reference Genome
docker run --rm -v ~/covid_data:/data covid-pipeline:v1 bwa index Sars_cov_2.ASM985889v3.dna.toplevel.fa.gz
Step 2: Quality Control & Trimming
docker run --rm -v ~/covid_data:/data covid-pipeline:v1 \
fastp -i SRR19195566_covid_sra_data.fastq.gz \
-o trimmed_reads.fastq.gz \
-h fastp_report.html
Step 3: Alignment & Sorting
We can chain commands together using bash -c to align the trimmed reads with bwa mem and immediately pipe the output into samtools to generate a sorted BAM file.
Try writing the command yourself first!
We need to mount the volume, call bash -c, run bwa mem, pipe (|) to samtools view -bS, and pipe to samtools sort.
Solution:
Step 4: Generate Mapping Statistics
To see how well our reads aligned to the reference genome, we can use samtools stats on our newly sorted BAM file. This generates a text file that MultiQC will automatically detect and plot for us.
docker run --rm -v ~/covid_data:/data covid-pipeline:v1 bash -c \
"samtools stats covid_aligned.sorted.bam > covid_aligned.stats"
Check your local folder. You successfully took raw sequencer output, trimmed it, aligned it to a viral genome, and generated mapping statistics, all without installing a single bioinformatics tool on your actual computer!
5. Other Package Managers: pip and Conda
Using apt-get is great for core system tools, but bioinformatics relies heavily on Python and Conda environments. You can absolutely use these package managers inside a Dockerfile.
Let's build two more containers and actually run them on the SARS-CoV-2 data we just generated!
Example 1: Building a Python/pip Container
Since we ran fastp earlier, we generated quality control reports. Let's build a Python container with MultiQC to summarize those results.
Create a new directory and a new Dockerfile:
Add this recipe:
# Start from an official, lightweight Python base image
FROM python:3.11-slim # (1)!
# Install Python packages using pip
RUN pip install --no-cache-dir multiqc # (2)!
# Set the working directory
WORKDIR /data
# Set the default command that runs if no command is provided
CMD ["multiqc", "--help"] # (3)!
- Using
python:3.11-slimgives you a pre-configured Python environment that is much smaller than a full Ubuntu image, saving download time. --no-cache-diris thepipequivalent of cleaning upaptlists. It forces pip to delete the downloaded package files after installation, drastically reducing your final image size.CMDprovides a default executable. If a user runsdocker run custom-multiqcwithout specifying a command, it will automatically print the MultiQC help menu.
Build and Run:
Build the image, then mount our covid_data directory and run MultiQC. Because we told it to scan the current directory (.), it will automatically find both the fastp JSON log and the samtools stats file we generated!
# Build the image
docker build -t custom-multiqc:v1 .
# Run MultiQC on our existing data folder
docker run --rm -v ~/covid_data:/data custom-multiqc:v1 multiqc .
If you check your ~/covid_data folder on your host machine, you will now see a beautiful multiqc_report.html file! Open it in your web browser to see an interactive dashboard showing both your read trimming quality and your viral genome alignment rates.
Example 2: Building a Bioconda Container
Conda is incredibly popular in genomics because it handles messy C++ dependencies seamlessly. Let's use Miniconda to install bedtools, which we can use to convert our sorted BAM file into a BED file.
Create a new directory and a new Dockerfile:
Add this recipe:
# Start from the official Miniconda image
FROM continuumio/miniconda3 # (1)!
# Set up the standard bioinformatics channels
RUN conda config --add channels defaults \
&& conda config --add channels bioconda \
&& conda config --add channels conda-forge # (2)!
# Install bedtools and clean up the cache in the same step
RUN conda install -y bedtools \
&& conda clean -a -y # (3)!
WORKDIR /data
continuumio/miniconda3comes with the Conda package manager pre-installed and ready to use immediately.- We configure the standard Conda channels, ensuring
conda-forgeandbiocondaare available so it can find our specific bioinformatics software. - Just like with
aptandpip, we useconda clean -a -yimmediately after installation to strip out all the downloaded cache files and keep the container lightweight.
Build and Run:
Build the image, mount our data, and use bedtools bamtobed to extract the genomic coordinates from our aligned BAM file.
# Build the image
docker build -t custom-bedtools:v1 .
# Convert the BAM file to a BED file
docker run --rm -v ~/covid_data:/data custom-bedtools:v1 \
bedtools bamtobed -i covid_aligned.sorted.bam > ~/covid_data/covid_aligned.bed
You now have a clean covid_aligned.bed file on your local machine, generated entirely by a custom Conda container!