美文网首页我爱编程
从零创建一个Docker镜像指南

从零创建一个Docker镜像指南

作者: peakhell | 来源:发表于2018-05-09 11:01 被阅读87次

    因为工作需要, 需要制作一个Docker来打包一个python程序。该python程序是开源的, 但是要下载对比数据库及其他辅助文件,配置好环境变量,并且要安装很多python的依赖包才能运行。虽然不是很麻烦,但是为了让其他人方便使用,最好还是可以直接下载就用。稍微花了两天学了一下Docker来打包这个程序,这样只要下载镜像直接运行就可以使用了。

    本项目python程序介绍

    该python开源软件是MetaPhlAn,用于分析从基因序列数据中提取的微生物群落的组成。该程序要运行必须在本机安装biobakerybowtie2。并且将这两个包所在的路径加入到环境变量中。同时还需要安装numpy,pandas等安装包。如果follow本博客来生成镜像的话。可以先把上面连接中的文件下载下来。

    什么是docker

    国际惯例,简单介绍一下什么是docker。简单来说,Docker是对Linux一些容器的打包。Docker 将应用程序与该程序的所有依赖及一些配置,打包在一个文件里面,运行这个文件,就会生成一个容器,可以直接在容器上运行任务。例如我有一个apache服务网站,现在想要再另一台服务器上复现,那么就必须先安装apache服务,配置运行环境,将网站文件复制过去,再运行。这样就很麻烦,而且打不准会出现环境变量或者配置问题。但如果使用docker将这个服务打包的话就不用这么麻烦了。直接在另一台服务器上运行复现就可以了。

    安装docker

    docker的安装按照官网的来就行了,不同系统的安装方法都有。由于我使用的是ubuntu系统,这里就只讲Ubuntu系统下docker的安装。Ubuntu下的安装非常简单(不是最新版的话)。一般来说只要apt直接安装就可以了。最新版的安装比较复杂,大家还是去看官网的安装方法吧。

    sudo apt-get install docker
    

    安装完之后可以测试一下

    sudo docker run hello-world
    

    如果出现下面的输出则说明安装成功了

    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    ... ...
    

    修改image仓库的镜像地址

    在上面的命令中

    sudo docker run hello-world
    

    会根据hello-world这个镜像,生成一个容器运行。 当然第一次运行的时候我们本地并没有这个镜像, 这时候docker会从官网寻找镜像, 并pull到本地。也就是先执行了下面的语句

    sudo docker pull hello-world
    

    但是如果使用默认的官方仓库下载速度将会非常慢,没办法官网在国外。我们可以把默认docker下载仓库改成国内仓库,这样下载速度会快很多。

    sudo vim /etc/default/docker
    

    在文件的最后面加上一句

    DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
    

    然后重启docker服务

    sudo service docker restart
    

    这样就会从国内仓库下载镜像了。

    创建docker用户组(可选)

    大家如果注意我上面的命令,会发现再docker命令之前都有sudo,也就是只有root用户才有权限运行docker的命令。这是由于在默认情况下,docker只允许root用户和docker用户组的用户访问Docker引擎。一般情况下我们不会直接使用root用户,因此最好的方法是将当前使用的用户加入到docker用户组。

    # 建立docker用户组
    sudo groupadd docker
    # 将当前用户添加到docker用户组中
    sudo usermod -aG docker $USER
    

    这样当前用户就添加到了docker用户中,可以直接运行docker命令了。测试一下

    docker run hello-world
    

    如果执行成功,那就说明配置生效了。如果出现下面类似的情况, 就说明当前用户的docker配置文件权限方面存在问题。

    WARNING: Error loading config file:/home/user/.docker/config.json - stat /home/user/.docker/config.json: permission denied
    

    可以用下面的命令修改一下权限

    sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
    sudo chmod g+rwx "/home/$USER/.docker" -R
    

    这样应该就可以了。

    使用Dockerfile定制镜像

    上面的准备工作做完之后,就可以开始创建镜像了。一般我们很少从头创建一个镜像,我们会根据现有的镜像来进行定制。镜像的创建有多种方法,这里采用官网推荐的方法。使用Dockerfile创建,Dockerfile是包含一串指令的文本文件。Dockerfile首先要指定一个基础镜像,然后在这个镜像上执行指令,例如安装软件,修改配置等。这样就生成了一个定制的镜像了。

    创建一个文件夹并进入该文件夹创建一个Dockerfile。

    mkdir MetaPhlAn
    cd MetaPhlAn
    touch Dockerfile
    

    再创建一个content文件夹,用来存放本项目中需要用到的依赖包。也就是前面所说的biobakery和bowtie2。然后将下载下来的biobakery和bowtie2存放到该目录下。

    mkdir content
    # 将biobakery和bowtie2拷贝到该目录下
    

    接下来开始编写Dockerfile文件。在Dockerfile文件中写入下面的内容。

    FROM ubuntu:16.04
    
    WORKDIR /bowtie2
    COPY content /root/
    
    ENV MDIR="/root/metaphlan2" PATH="/root/metaphlan2:/root/metaphlan2/utils:$PATH" \
    PATH="$PATH:/root/bowtie2-2.3.4.1-linux-x86_64"
    
    RUN apt-get update \  
        && apt-get install -y python \
                           python-dev \
                           python-pip  \
        && apt-get clean \
        && apt-get autoclean \
        && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
        && pip install numpy pandas biopython scipy matplotlib h5py \
        && pip install biom-format
    

    下面开始逐条解释每一句的含义。

    FROM ubuntu:16.04
    

    这条语句意思是把ubuntu16:04指定为基础镜像。也就是说我们接下来的指令都是在ubuntu镜像下执行的。这条语句是必须的。这里有一个特殊的镜像值得一提。那就是 scratch镜像,它表示一个空白的镜像,有什么用呢?有时候仅仅只是把二进制的可执行文件进行打包。这时候并不依赖任何环境,这时候scratch镜像就可以用到了。

    WORKDIR /bowtie2
    COPY content /root/
    

    WORKDIR指令用来指定镜像中的工作目录,如果镜像中没有这个目录,则会自动帮你创建。
    COPY指令是将文件传入到镜像中。源文件的各种元数据都会保留。比如读、写、执
    行权限、文件变更时间等。这条指令的意思就是把该content文件夹下的所有文件拷贝到镜像中的/root/目录下。注意是content文件夹下的内容,而不是文件夹。

    ENV MDIR="/root/metaphlan2" PATH="/root/metaphlan2:/root/metaphlan2/utils:$PATH" \
    PATH="$PATH:/root/bowtie2-2.3.4.1-linux-x86_64"
    

    这条指令的意思是给镜像中Ubuntu添加环境变量,这是为了让我的python程序可以运行,因为该python程序必须用到biobakery和bowtie2。因此将它们添加到环境变量,以便程序运行时可以找到。

    RUN apt-get update \  
        && apt-get install -y python \
                           python-dev \
                           python-pip  \
        && apt-get clean \
        && apt-get autoclean \
        && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
        && pip install numpy pandas biopython scipy matplotlib h5py \
        && pip install biom-format
    

    上面的指令很好理解,首先是再ubuntu下安装python及其安装包。然后清除安装包,这是为了减少镜像的大小。最后在安装python包的依赖。
    值得注意的是当你安装的python包之间有依赖时,一定要把依赖其他包的包放在后面安装。像我这里就是这样。

        && pip install numpy pandas biopython scipy matplotlib h5py \
        && pip install biom-format
    

    由于biom-format依赖与numpy包,所以不能把biom-format包放在上面一行一起安装。这样会报错。

    生成镜像

    编写完Dockerfile之后, 就可以生成镜像了。

    docker image build -t metaphlan-docker .
    

    -t 是用来指定镜像名称的,注意镜像名称不能包含大写字母
    最后的 . 是指Dockerfile的地址,这里当然就是本目录了。

    如无意外的话, 就会生成一个metaphlan-docker镜像(有点久,需要耐心等一等)。

    运行镜像

    安装完之后自然是需要试试的。

    docker run -i -t --rm -v ~/data:/bowtie2 metaphlan-docker bash
    

    -i 是交互的意思。
    -t 是打开一个terminal的意思
    -v 是挂载目录,后面的参数是 本地的目录:镜像目录, 像我这里的意思就是把镜像中的 /bowtie2挂载到本地的 ~/data目录下。也就是我在本地~/data目录下的任何操作,都会映射到容器中的 /bowtie2目录,这样就实现了本地和容器的文件传输。

    相关文章

      网友评论

        本文标题:从零创建一个Docker镜像指南

        本文链接:https://www.haomeiwen.com/subject/uqcwrftx.html