专栏名称: 生信媛
生信媛,从1人分享,到8人同行。坚持分享生信入门方法与课程,持续记录生信相关的分析pipeline, python和R在生物信息学中的利用。内容涵盖服务器使用、基因组转录组分析以及群体遗传。
51好读  ›  专栏  ›  生信媛

生信猿的docker入门课2

生信媛  · 公众号  · 生物  · 2020-11-30 07:45

正文

请到「今天看啥」查看全文


背景

小师妹突然找到我,问我是否知道怎么做singularity或者docker镜像。细问之下了解到,她的文章在投,因为涉及她自己写的一个工具以及数据分析,编辑要求她提供镜像。原因在上一篇推文其实提到过,总的来说,只提供分析源码和数据本身并不能保证分析的可重复性。因为还有依赖的库以及软件版本改变带来的隐忧。

也许,容器技术在生信领域已经成为其中一种标准了。

这篇推文主要介绍一下2种生成docker镜像的方法。

镜像封装

打包镜像的方法有2种:

  1. 以某个基础镜像,比如centos7,为基础,运行docker容器,在容器内将所有需要安装的安装完毕后,以该容器为基础生成一个新的镜像。
  2. 使用dockerfile生成镜像。

我自己的习惯是,先在容器内将需要安装的软件安装一遍,测试所需要安装的工具怎么装,以及是否有需要额外安装的依赖包等等,然后写成Dockerfile再生成新镜像。

对于需要安装的软件包,我们可以直接下载到本地,再使用某些方式放到容器内(后边会细说),也可以联网下载。

方式1:基于容器

先获取1个基础镜像并启动为容器。

docker run -it --name sxydemo --hostname sxy -v $PWD:/docker centos:7
  • docker run 其实本质上是docker pull(拉取镜像)+ docker start(启动容器)。拉取镜像是从 Docker-Hub 上。镜像相关信息也可以从上边获取。

  • -it,其实是-i 和 -t 的组合,一般一起使用,就是开启了一个伪终端,让你可以在终端输入命令进行交互

    Name, shorthand Default Description
    --interactive , -i
    Keep STDIN open even if not attached
    --tty , -t
    Allocate a pseudo-TTY
  • -v 挂载卷。这里我的当前路径就是放了很多需要安装软件的路径。在容器中,对应该卷路径为根目录下的docker目录。

  • --name 给容器命名,可选。这个参数不加对我们后续没有影响

  • --hostname 加了以后,容器内部的hostname就设定为你指定的这个,不加则为容器id。这个参数不加对我们后续没有影响

docker run后我们就进入了容器了。我们来看看挂载的情况:



docker目录下的东西跟我们本地的被挂载路径的东西是一模一样的。因为本质上,这俩就是同一个卷。通过这种方式,你在容器内分析的数据就可以存储到服务器上了。

你可以自己尝试在容器内创建一个空文件,在容器外部也会看到的。

因为我们拉取的是一个linux系统的基础镜像,因此在进入容器以后,我们就跟在一个linux的终端上体验没区别了。安装软件也完全一样的。并且原先你习惯用conda来安装软件,在docker内也是一样一样的。

来装2个软件试试。下载安装的方式以perl为例。使用已经下载好的安装包进行安装则以samtools为例。但其实二者没什么太大区别,完全使用前一种方法的话,无需挂载路径。而后者需要将能访问到软件包的路径挂载到容器内(注意,可以是软件包所在路径,也可以是其上级目录)。仅此而已。

perl

  • perl5.16.3源码地址:https://www.cpan.org/src/5.0/perl-5.16.3.tar.bz2

在正式开始之前,先装几个要用到的软件。

  • perl的源码是bz2压缩格式,需要bzip2
  • perl的编译需要gcc和make(或者gmake)
yum -y install bzip2 gcc make less

在这个镜像里面没有预装wget,我们用curl来下载。

mkdir /src && cd /src
curl -OL https://www.cpan.org/src/5.0/perl-5.16.3.tar.bz2
tar -jxvf perl-5.16.3.tar.bz2
cd perl-5.16.3
# -d use defaults for all answers.否则一项项地确认好麻烦。
./Configure -d 
make
make install


plink

解压zip需要unzip工具:

yum install -y unzip

为了避免出现读写权限问题,将/docker下的plink拷贝到/src下再进行后续操作.

cp /docker/plink_linux_x86_64.zip /src
unzip plink_linux_x86_64.zip -d ./plink
ls plink
# LICENSE  plink  prettify  toy.map  toy.ped

因为这里只有2个可执行文件,我将plink和prettify直接拷贝到其中一个PATH路径下。

查看:

echo $PATH        
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

拷贝:

cp ./plink/{plink,prettify} /usr/local/bin

其他的软件安装方法都是跟linux下一样的(因为是基于centos7镜像),不再赘述了。

将容器打包成镜像:

docker commit sxydemo sxydemo:20201126

sxydemo是docker的名称,你也可以用容器id。二者是一样的。

docker images|head -2


我们使用新打包好的镜像生成容器,然后简单验证一下:

docker run -it --rm -u $(id -u):$(id -g) sxydemo:20201126

另外,我们挂载的容器内路径还在,但是内容是空的(因为我们这次没挂载了)。而拷贝到容器内的目录下的文件还会在。为了使得我们最后打包的镜像体积小一点,其实在安装后无用的文件我们都应该清除。

另外,我们可以看到,这次因为我使用了 -u 命令进入容器,因此此时,对于docker容器内部,我是一个普通的用户身份。

--rm :当我退出容器的时候,便将容器销毁。这个命令在我们频繁使用docker进行数据分析的时候很有必要加上。

方式2:基于dockerfile

将上述过程,整理成dockerfile的形式,打包镜像。

FROM centos:7
ADD . /src
RUN yum install -y bzip2 gcc less unzip
RUN cd /src && curl -OL https://www.cpan.org/src/5.0/perl-5.16.3.tar.bz2 && \
  tar -jxvf perl-5.16.3.tar.bz2 && \
  cd perl-5.16.3 && \
  ./Configure -d -e && \
  make && make install && \
  rm -rf /src/perl-5.16.3*

RUN cd /src && unzip plink_linux_x86_64.zip -d ./plink && \
  cp ./plink/{plink,prettify} /usr/local/bin && \
  rm -rf /src/plink*

CMD ["/bin/bash"]

将上述文件名字命名为 Dockerfile docker build 的时候会自动去找指定路径下的这个名称的文件,然后根据描述去构建镜像。你也可以更改名字,只要在 docker build 的时候用 --file 或者 -f 指定一下就好了。

docker build -t sxydemo:20201126 .

这里多说一句,为什么两次RUN我都需要 cd /src ,上一次进入这个路径以后,不是应该就在这个路径下了吗?但是对于Dockerfile打包镜像的时候,每一行命令都是基于上一个打包好的基础上作为一个新的docker启动的,因此每次都是回到某个设定好的最初进入的路径(比如你在linux下每次登陆进去都是进入你的home目录),可以使用 WORKDIR 进行设置进入docker后的路径是哪里。

另外,Docker镜像是一层一层的,容器只是在镜像最上边加了一层读写层。而每一层需要删除的东西得在这一层进行删除(比如第2个和第3个RUN命令),在下一层删除是没有意义的,它其实仍然存在,只是对你不可见了而已,这样镜像打包后大小并不会改变。

同样,打包完自行检查一下软件等是不是都正确能使用了。

docker run -it --rm -u $(id -u):$(id -g) sxydemo:20201126

如果需要将这个镜像分享给别人,可以使用下边命令打包成tar文件:

docker save -o /YOUR/PATH/docker_tar/sxydemo_20201126.tar sxydemo:20201126

参考资料

  • docker命令行使用文档
  • Dockerfile reference








请到「今天看啥」查看全文