Accessibility Tools

- Le blog participatif de bioinformatique francophone depuis 2012 -

Virtualisez pour plus de reproductibilité

Pour commencer

Vous avez enten­du par­ler de repro­duc­ti­bi­li­té. Vous vou­lez vous y mettre ? Vous vous dites que la vir­tua­li­sa­tion vous aide­rait à uti­li­ser tou­jours la même ver­sion d'un outil pré­cis. En savoir plus sur Docker vous aide­rait bien ? Cet article est donc pour vous. Je pro­fite de l'occasion pour par­ler aus­si de Sin­gu­la­ri­ty. Mais pour bien com­men­cer, on va expli­quer le concept des Machines Vir­tuelles.

Une Machine Virtuelle c'est quoi ?

Alors pour tous ceux qui se posent la ques­tion, un grille-pain en réa­li­té vir­tuelle n'est pas une Machine Vir­tuelle. Une Machine Vir­tuelle c'est la simu­la­tion d'un sys­tème infor­ma­tique qui repro­duit son uti­li­sa­tion réelle. Une notion voi­sine est l'ému­la­tion, outil bien connu des retro-gamers, qui va simu­ler un maté­riel pour repro­duire son uti­li­sa­tion.

Dans notre cas, c'est la vir­tua­li­sa­tion qui nous inté­resse. Le grand inté­rêt étant de pou­voir faire abs­trac­tion de toutes les carac­té­ris­tiques du sys­tème sur lequel on est et de simu­ler un autre sys­tème pour avoir un envi­ron­ne­ment trans­por­table et donc repro­duc­tible d'une machine à une autre.

Java fonc­tionne sur ce prin­cipe de Machine Vir­tuelle (et oui, JVM c'est pour Java Vir­tual Machine). Vir­tual Box est un des outils les plus connus per­met­tant de faire des Machines Vir­tuelles.

Les environnements virtuels

Alors oui, les Machines Vir­tuelles c'est bien joli, mais c'est un peu lourd. Du coup si au lieu de simu­ler le sys­tème dans son inté­gra­li­té, on ne simu­lait que ce dont on avait besoin, c'est-à-dire les appli­ca­tions. Bon quelques librai­ries ça peut être pra­tique aus­si, mais vous voyez l'idée.

Le grand inté­rêt d'utiliser des envi­ron­ne­ments vir­tuels c'est aus­si de pou­voir com­par­ti­men­ter et iso­ler ces envi­ron­ne­ments dans des conte­neurs. Et par exemple, de pou­voir ins­tal­ler plu­sieurs ver­sions de Python et plu­sieurs outils uti­li­sant plu­sieurs ver­sions sans trop s'embêter. Les adeptes de Python et de vir­tua­lenv se recon­naî­tront.

Docker c'est quoi ?

Docker c'est un outil qui s'appuie sur les fonc­tion­na­li­tés du sys­tème d'exploitation sous-jacent (le noyau Linux). Docker s'interface avec le noyau Linux et pro­pose plu­sieurs ins­tances de vir­tua­li­sa­tion iso­lées. Ces ins­tances sont appe­lées conte­neurs, et ils sont donc très légers (com­pa­rés aux Machines Vir­tuelles clas­siques). Une simple recherche sur votre moteur de recherche pré­fé­ré vous amène faci­le­ment sur des tuto­riaux si le work­shop de l'IFB et le site de Docker ne vous suf­fisent pas. Pour la petite his­toire, Docker a été créé par un fran­co-amé­ri­cain, et la des­si­na­trice Lau­rel y tra­vaille actuel­le­ment et elle fait entre autres choses de jolis auto­col­lants.

Les avantages et les inconvénients ?

Le grand avan­tage de Docker est sa sim­pli­ci­té de mise en place et d'utilisation. Les conte­neurs donnent accès à des envi­ron­ne­ments iso­lés et contrô­lés. Docker-Hub est le site de dépôt de Docker, conçu pour faci­li­ter la recherche et le par­tage de conte­neurs Docker.

Créer son propre conte­neur Docker est aus­si simple. Il suf­fit de le construire à par­tir d'un fichier de confi­gu­ra­tion Docker­file qui contient toutes les com­mandes néces­saires à sa construc­tion. Si votre Docker­file est ver­sion­né sur GitHub, une construc­tion auto­ma­tique du conte­neur peut être réa­li­sée sur les ser­veurs de Docker à chaque push. Ce qui per­met une véri­fi­ca­tion sup­plé­men­taire du bon fonc­tion­ne­ment de votre conte­neur.

Le gros incon­vé­nient de Docker est qu'il fonc­tionne en root sur votre machine. Ce qui signi­fie qu'il a tous les droits. Ce qui peut poten­tiel­le­ment être un pro­blème de sécu­ri­té, et fait que cet outil n'est sou­vent pas dis­po­nible sur les clus­ters de cal­culs.

Avant d'utiliser un conte­neur, soyez sûr de sa pro­ve­nance ;-).

Quelles sont les initiatives en Bioinformatique ?

Du coup, main­te­nant vous vous dites, eh mais ça m'intéresse ça jus­te­ment, j'aimerais bien avoir un conte­neur avec BWA pour ali­gner mes séquences, et il m'en fau­drait aus­si un avec GATK pour conti­nuer mes ana­lyses.

Bien évi­dem­ment ça marche avec n'importe quoi d'autre. Mais si vous n'avez pas envie de vous prendre la tête à créer vos propres contai­ners, pas de sou­cis, Ikea est là.

Euh non, c'est quand même plus simple à mon­ter ;-). Comme expli­qué plus haut, vous pou­vez cher­cher sur Docker-Hub. Mais il n'y a pas que ça, Bio­Con­tai­ners et Bio­Sha­dock sont des ini­tia­tives qui four­nissent des conte­neurs d'outils bio­in­for­ma­tiques.

Et Singularity dans tout ça ?

Gros­so modo c'est pareil que Docker sans le sou­cis d'utilisateur root. Et c'est aus­si un poil plus com­pli­qué pour rapi­de­ment exé­cu­ter un conte­neur. Mais le pro­jet est récent, et facile d'utilisation. Leur pla­te­forme Sin­gu­la­ri­ty-Hub a qua­si­ment les mêmes fonc­tion­na­li­tés que Docker-Hub. Bref, c'est à sur­veiller.

On peut avoir un exemple ?

J'ai un fichier

sur mon ordi, il me paraît plu­tôt petit, et je me demande donc ce qu'il s'est pas­sé avec ce fichier. Je vou­drais notam­ment véri­fier quel génome de réfé­rence a été uti­li­sé lors du trai­te­ment de ce fichier. Un simple

aurait nor­ma­le­ment suf­fit à me don­ner le hea­der qui répon­dra à cette ques­tion. Mais j'ai réins­tal­lé mon ordi il y a plu­sieurs mois, et n'ai pas vrai­ment eu besoin de

depuis, et là c'est le drame… Bon, je pour­rais l'installer, c'est facile, mais je pour­rais pas faire d'exemple pour cet article… Et puis, si je ne l'ai pas déjà ré-ins­tal­lé, c'est vrai­sem­bla­ble­ment que j'en ai pas super besoin, on va donc uti­li­ser Docker.
Le début de la com­mande change un petit peu, et je vais l'expliquer en détail

docker run # Tout simplement pour lancer Docker
-v pwd:/tmp -w /tmp # Pour spécifier un volume à monter depuis le conteneur, et à utiliser.
biocontainers/samtools:1.2 # Pour spécifier le dépot, le conteneur et la version à utiliser.

Ce qui nous donne tout sim­ple­ment :

> docker run -v pwd:/tmp -w /tmp biocontainers/samtools:1.2 samtools view -H 1234N_0.md.bam
Unable to find image 'biocontainers/samtools:1.2' locally
# Le conteneur n'étant pas déjà sur mon ordinateur, Docker le télécharge
# La version 1.2 du conteneur ayant été demandé, c'est celle là qui est téléchargée
1.2: Pulling from biocontainers/samtools
# Les différentes couches sont téléchargées.
c62795f78da9: Pull complete
d4fceeeb758e: Pull complete
5c9125a401ae: Pull complete
0062f774e994: Pull complete
6b33fd031fac: Pull complete
af6fedb9c521: Pull complete
fd673780b023: Pull complete
6126667f3f67: Pull complete
bb944ca99002: Pull complete
c40c4efd2448: Pull complete
3ddbf72562fd: Pull complete
8e7e9c932556: Pull complete
46c6dd154e56: Pull complete
d1bcaa2afb2e: Pull complete
17063abba50e: Pull complete
a90ebfcb0e1f: Pull complete
bda5ce9124fe: Pull complete
Digest: sha256:e303bc7271392d0553b3f7782fd40bd009a7c85351dc64c58ba597857b26bd76
Status: Downloaded newer image for biocontainers/samtools:1.2
# Le téchargement ayant réussi, la commande est alors exécutée
# Voici donc notre fameux header
@HD VN:1.5 SO:coordinate
# On a donc quatre chromosomes
@SQ SN:1 LN:200000
@SQ SN:2 LN:200000
@SQ SN:3 LN:200000
@SQ SN:X LN:200000
@RG ID:1234N_7 PU:1234N_7 SM:1234N LB:1234N PL:illumina
@RG ID:1234N_8 PU:1234N_8 SM:1234N LB:1234N PL:illumina
@RG ID:1234N_4 PU:1234N_4 SM:1234N LB:1234N PL:illumina
@RG ID:1234N_1 PU:1234N_1 SM:1234N LB:1234N PL:illumina
@RG ID:1234N_2 PU:1234N_2 SM:1234N LB:1234N PL:illumina
@PG ID:bwa PN:bwa VN:0.7.8-r455 CL:bwa mem -R @RG\tID:1234N_7\tPU:1234N_7\tSM:1234N\tLB:1234N\tPL:illumina -t 2 -M human_g1k_v37_decoy.small.fasta tiny_normal_L007_R1.fastq.gz tiny_normal_L007_R2.fastq.gz
@PG ID:bwa-38484E5B PN:bwa VN:0.7.8-r455 CL:bwa mem -R @RG\tID:1234N_8\tPU:1234N_8\tSM:1234N\tLB:1234N\tPL:illumina -t 2 -M human_g1k_v37_decoy.small.fasta tiny_normal_L008_R1.fastq.gz tiny_normal_L008_R2.fastq.gz
@PG ID:bwa-DA88A9 PN:bwa VN:0.7.8-r455 CL:bwa mem -R @RG\tID:1234N_4\tPU:1234N_4\tSM:1234N\tLB:1234N\tPL:illumina -t 2 -M human_g1k_v37_decoy.small.fasta tiny_normal_L004_R1.fastq.gz tiny_normal_L004_R2.fastq.gz
@PG ID:bwa-5111873F PN:bwa VN:0.7.8-r455 CL:bwa mem -R @RG\tID:1234N_1\tPU:1234N_1\tSM:1234N\tLB:1234N\tPL:illumina -t 2 -M human_g1k_v37_decoy.small.fasta tiny_normal_L001_R1.fastq.gz tiny_normal_L001_R2.fastq.gz
@PG ID:bwa-7F33CF22 PN:bwa VN:0.7.8-r455 CL:bwa mem -R @RG\tID:1234N_2\tPU:1234N_2\tSM:1234N\tLB:1234N\tPL:illumina -t 2 -M human_g1k_v37_decoy.small.fasta tiny_normal_L002_R1.fastq.gz tiny_normal_L002_R2.fastq.gz
@PG ID:MarkDuplicates VN:2.0.1(fe51f432e4b918385037e6d15e958f0298203e28_1449251266) CL:picard.sam.markduplicates.MarkDuplicates INPUT=[1234N.bam] OUTPUT=1234N_0.md.bam METRICS_FILE=1234N.bam.metrics ASSUME_SORTED=true TMP_DIR=[.] VALIDATION_STRINGENCY=LENIENT CREATE_INDEX=true MAX_SEQUENCES_FOR_DISK_READ_ENDS_MAP=50000 MAX_FILE_HANDLES_FOR_READ_ENDS_MAP=8000 SORTING_COLLECTION_SIZE_RATIO=0.25 REMOVE_DUPLICATES=false DUPLICATE_SCORING_STRATEGY=SUM_OF_BASE_QUALITIES PROGRAM_RECORD_ID=MarkDuplicates PROGRAM_GROUP_NAME=MarkDuplicates READ_NAME_REGEX=[a-zA-Z0-9]+:[0-9]:([0-9]+):([0-9]+):([0-9]+).* OPTICAL_DUPLICATE_PIXEL_DISTANCE=100 VERBOSITY=INFO QUIET=false COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_MD5_FILE=false GA4GH_CLIENT_SECRETS=client_secrets.json PN:MarkDuplicates
# Le fichier fasta source de la référence est human_g1k_v37_decoy.small.fasta
# C'est donc une version light du génome humain faite pour des tests rapides.

# Si nous essayons une autre version de samtools.
> docker run -v pwd:/tmp -w /tmp biocontainers/samtools:1.3.1 samtools view -H 1234N_0.md.bam
# C'est la version 1.3.1 qui a été demandée ici
Unable to find image 'biocontainers/samtools:1.3.1' locally
1.3.1: Pulling from biocontainers/samtools
c62795f78da9: Already exists
d4fceeeb758e: Already exists
5c9125a401ae: Already exists
0062f774e994: Already exists
6b33fd031fac: Already exists
af6fedb9c521: Already exists
fd673780b023: Already exists
6126667f3f67: Already exists
bb944ca99002: Already exists
c40c4efd2448: Already exists
3ddbf72562fd: Already exists
8e7e9c932556: Already exists
46c6dd154e56: Already exists
d1bcaa2afb2e: Already exists
17063abba50e: Already exists
a90ebfcb0e1f: Already exists
d5d1e4532146: Pull complete
# Seule la dernière couche étant différente, c'est la seule qui est à nouveau téléchargée
Digest: sha256:8ba8a7dedbeef7ba8f9f2b99305cdba48590b4c9a2edf354cbd9d591dde62323
Status: Downloaded newer image for biocontainers/samtools:1.3.1
# Le résultat de la commande étant la même, je ne le remet pas.

Et voi­là, en deux rela­ti­ve­ment simples com­mandes, on a pu uti­li­ser deux ver­sions d'un même pro­gramme en moins de 5 min.

En regar­dant plus en détail le fichier de confi­gu­ra­tion du conte­neur Docker uti­li­sé (cf BioContainers/samtools/1.3.1/Dockerfile):

# Base Image

FROM biocontainers/biocontainers:latest

# Metadata
LABEL base.image="biocontainers:latest"
LABEL version="2"
LABEL software="Samtools"
LABEL software.version="1.3.1"
LABEL description="Tools for manipulating next-generation sequencing data"
LABEL website="https://github.com/samtools/samtools"
LABEL documentation="https://github.com/samtools/samtools"
LABEL license="https://github.com/samtools/samtools"
LABEL tags="Genomics"

# Maintainer
MAINTAINER Saulo Alves Aflitos <sauloal@gmail.com>

RUN conda install samtools=1.3.1

WORKDIR /data/

CMD ["samtools"]

On peut voir que ce conte­neur est basé sur un autre conte­neur et que

est ici ins­tal­lé en uti­li­sant

. En regar­dant cet autre conte­neur source :

# Base image

FROM ubuntu:16.04

# Metadata
LABEl base.image="ubuntu:16.04"
LABEL version="4"
LABEL software="Biocontainers base Image"
LABEL software.version="08252016"
LABEL description="Base image for BioDocker"
LABEL website="http://biocontainers.pro"
LABEL documentation="https://github.com/BioContainers/specs/wiki"
LABEL license="https://github.com/BioContainers/containers/blob/master/LICENSE"
LABEL tags="Genomics,Proteomics,Transcriptomics,General,Metabolomics"

# Maintainer
MAINTAINER Felipe da Veiga Leprevost <felipe@leprevost.com.br>

ENV DEBIAN_FRONTEND noninteractive

RUN mv /etc/apt/sources.list /etc/apt/sources.list.bkp && \
bash -c 'echo -e "deb mirror://mirrors.ubuntu.com/mirrors.txt xenial main restricted universe multiverse\n\
deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-updates main restricted universe multiverse\n\
deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-backports main restricted universe multiverse\n\
deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-security main restricted universe multiverse\n\n" > /etc/apt/sources.list' && \
cat /etc/apt/sources.list.bkp >> /etc/apt/sources.list && \
cat /etc/apt/sources.list

RUN apt-get clean all && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y \
autotools-dev \
automake \
cmake \
curl \
grep \
sed \
dpkg \
fuse \
git \
wget \
zip \
openjdk-8-jre \
build-essential \
pkg-config \
python \
python-dev \
python-pip \
bzip2 \
ca-certificates \
libglib2.0-0 \
libxext6 \
libsm6 \
libxrender1 \
git \
mercurial \
subversion \
zlib1g-dev && \
apt-get clean && \
apt-get purge && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
wget --quiet https://repo.continuum.io/miniconda/Miniconda2-4.0.5-Linux-x86_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh

RUN TINI_VERSION=curl https://github.com/krallin/tini/releases/latest | grep -o "/v.*\"" | sed 's:^..\(.*\).$:\1:' && \
curl -L "https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini_${TINI_VERSION}.deb" > tini.deb && \
dpkg -i tini.deb && \
rm tini.deb && \
apt-get clean

RUN mkdir /data /config

# Add user biodocker with password biodocker
RUN groupadd fuse && \
useradd --create-home --shell /bin/bash --user-group --uid 1000 --groups sudo,fuse biodocker && \
echo echo "biodocker\nbiodocker\n" | passwd biodocker && \
chown biodocker:biodocker /data && \
chown biodocker:biodocker /config

# give write permissions to conda folder
RUN chmod 777 -R /opt/conda/

# Change user
USER biodocker

ENV PATH=$PATH:/opt/conda/bin
ENV PATH=$PATH:/home/biodocker/bin
ENV HOME=/home/biodocker

RUN mkdir /home/biodocker/bin

RUN conda config --add channels r
RUN conda config --add channels bioconda

RUN conda upgrade conda

VOLUME ["/data", "/config"]

# Overwrite this with 'CMD []' in a dependent Dockerfile
CMD ["/bin/bash"]

WORKDIR /data

On se rend compte qu'il contient la plu­part des outils pour com­pi­ler et ins­tal­ler des outils. J'ai donc envie d'utiliser une autre image plus légere que je vais réa­li­ser moi même :

FROM debian:8.6

LABEL author="Maxime Garcia" \
description="SAMTools 1.4 image for bioinfo-fr" \
maintainer="mon.email@gmail.com"

# Install libraries
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
libbz2-dev \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
zlib1g-dev \
&& rm -rf /var/lib/apt/lists/*

# Setup ENV variables
ENV SAMTOOLS_BIN="samtools-1.4.tar.bz2" \
SAMTOOLS_VERSION="1.4"

# Install SAMTools
RUN curl -fsSL https://github.com/samtools/samtools/releases/download/$SAMTOOLS_VERSION/$SAMTOOLS_BIN -o /opt/$SAMTOOLS_BIN \
&& tar xvjf /opt/$SAMTOOLS_BIN -C /opt/ \
&& cd /opt/samtools-$SAMTOOLS_VERSION \
&& make \
&& make install \
&& rm /opt/$SAMTOOLS_BIN

J'ai choi­si une approche dif­fé­rente, me base sur

et n'installe que le strict néces­saire pour com­pi­ler

avec

. Mon conte­neur est donc plus léger que celui de bio­con­tai­ners. Je n'ai construit ici qu'un seul simple conte­neur, et n'utilise pas un conte­neur ser­vant de base à plus de 50 conte­neurs dif­fé­rents. L'approche de bio­con­tai­ners est expli­cable par le nombre de conte­neurs à gérer, et j'aurai pro­ba­ble­ment la même approche pour un pro­jet de grande ampleur.

Quelque soit le conte­neur que vous uti­li­sez, l'important est que vous puis­siez être sur de tou­jours uti­li­ser le même, et de le faire uti­li­ser à vos col­la­bo­ra­teurs ou vos uti­li­sa­teurs. C'est l'essentiel de la repro­duc­ti­bi­li­té.

Conflits d'intérêts

Aucun.

Remerciements

Je remer­cie Yoann M. pour sa moti­va­tion concer­nant cet article, ain­si que Norore, M4rsu et Lroy bien-aimés relec­teurs pour leurs avis et dis­cus­sions.

Vous avez aimé ? Dites-le nous !

Moyenne : 0 /​ 5. Nb de votes : 0

Pas encore de vote pour cet article.

We are sor­ry that this post was not use­ful for you !

Let us improve this post !

Tell us how we can improve this post ?




Commentaires

5 réponses à “Virtualisez pour plus de reproductibilité”

  1. Avatar de Alice

    Mer­ci pour l'article !! Vrai­ment très inté­res­sant. J'attendais des infos sur Docker car on m'en parle tout le temps et que vu que la pla­te­forme bioin­fo de l'AP-HP a déci­dé de baser leurs pipe­line sur Docker, je savais que c'était à suivre !
    Dès que j'ai du temps je me forme là des­sus…

    1. Content que l'article t'ait plu. Pour ma part j'utilise essen­tiel­le­ment Docker avec Next­flow. Vous uti­li­sez quoi à l'APHP pour vos pipe­lines ?

  2. Avatar de Alice

    Je suis pas à l'APHP, j'ai assis­té à une de leur pré­sen­ta­tion quand la pla­te­forme venait d'être créer il y a quelques mois. Et comme c'est une domaine qui m'est encore plu­tôt incon­nu je vais pas m'avancer pour eux.

  3. Mer­ci pour cet article super inté­res­sant ! Je ne connais­sais pas du tout les contai­ners, et ça semble vrai­ment révo­lu­tion­naire sur pas mal d'aspects : repro­du­ci­bi­li­té, par­tage, et liber­té d'utiliser n'importe quel pro­gramme sur un ser­veur (pour Sin­gu­la­ri­ty du moins). Je m'y mets de ce pas !

    1. Content que ça te plaise ;-).
      Si tu veux un peu plus de lec­ture tu peux aus­si jeter un coup d'œil à l'article que j'ai rédi­gé pour le blog de Next­flow sur com­ment j'ai mis en place Sin­gu­la­ri­ty sur notre pipe­line : https://​www​.next​flow​.io/​b​l​o​g​/​2​0​1​7​/​c​a​w​-​a​n​d​-​s​i​n​g​u​l​a​r​i​t​y​.​h​tml
      Et si t'as d'autres ques­tions, n'hésite pas 😉

Laisser un commentaire

Pour insérer du code dans vos commentaires, utilisez les balises <code> et <\code>.