从零创建一个Docker镜像指南

因为工作需要, 需要制作一个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目录,这样就实现了本地和容器的文件传输。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • docker基本概念 1. Image Definition 镜像 Image 就是一堆只读层 read-only...
    慢清尘阅读 8,720评论 1 21
  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,506评论 15 147
  • 《Docker从入门到实践》阅读笔记 原书地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo阅读 11,352评论 1 39
  • 基本概念 镜像Docker 镜像就是一个只读的模板,镜像可以用来创建 Docker 容器 容器容器是从镜像创建的运...
    巨子联盟阅读 7,541评论 0 3
  • 雪白的床单轻轻滑落 如少女诱人的胴体立于床前 蜘蛛忙碌地在角落 寻找落日的情人 血管里汩汩流淌着兑水的酒精 醉里看...
    汤生明阅读 291评论 0 2