美文网首页我爱编程
从零创建一个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镜像指南

    因为工作需要, 需要制作一个Docker来打包一个python程序。该python程序是开源的, 但是要下载对比数...

  • Docker从入门到实践

    基本概念 镜像Docker 镜像就是一个只读的模板,镜像可以用来创建 Docker 容器 容器容器是从镜像创建的运...

  • Docker基本操作

    Docker 镜像就是一个只读的模板,镜像可以用来创建 Docker 容器。容器是从镜像创建的运行实例,它可以被启...

  • Docker从入门到放弃

    Docker概念 镜像(Image):只读模板。容器从镜像启动时,Docker在镜像的上层创建一个可写层,镜像本身...

  • Docker+Jenkins持续集成搭建

    docker search jenkins可以搜索docker官方仓库的镜像然后从docker仓库中下载镜像 创建...

  • 用一分钟能搭建DNS服务器信么?

    这里我们使用dnsmasq对应的docker版本docker-dnsmasq。 使用指南 下载镜像 创建最简单的配...

  • 如何把ISO镜像转换成Docker镜像

    最近开始研究docker,如果想要自己创建个镜像,必须从Docker Hub上面获取一个基础镜像来创建;对于我们公...

  • Docker基础原理理解

    Docker核心概念 镜像 Docker镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器...

  • docker相关概念理解

    Docker 镜像(Images):Docker 镜像是用于创建 Docker 容器的模板。 Docker 容器(...

  • Docker仓库、镜像和容器的关系

    Docker 容器是独立运行的一个或一组应用,通过 Docker 镜像来创建。 Docker 镜像是用于创建 Do...

网友评论

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

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