因?yàn)楣ぷ餍枰?需要制作一個Docker來打包一個python程序蓖议。該python程序是開源的虏杰, 但是要下載對比數(shù)據(jù)庫及其他輔助文件,配置好環(huán)境變量勒虾,并且要安裝很多python的依賴包才能運(yùn)行纺阔。雖然不是很麻煩,但是為了讓其他人方便使用修然,最好還是可以直接下載就用笛钝。稍微花了兩天學(xué)了一下Docker來打包這個程序,這樣只要下載鏡像直接運(yùn)行就可以使用了愕宋。
本項(xiàng)目python程序介紹
該python開源軟件是MetaPhlAn玻靡,用于分析從基因序列數(shù)據(jù)中提取的微生物群落的組成。該程序要運(yùn)行必須在本機(jī)安裝biobakery和bowtie2中贝。并且將這兩個包所在的路徑加入到環(huán)境變量中囤捻。同時還需要安裝numpy,pandas等安裝包邻寿。如果follow本博客來生成鏡像的話蝎土。可以先把上面連接中的文件下載下來绣否。
什么是docker
國際慣例誊涯,簡單介紹一下什么是docker。簡單來說蒜撮,Docker是對Linux一些容器的打包暴构。Docker 將應(yīng)用程序與該程序的所有依賴及一些配置,打包在一個文件里面,運(yùn)行這個文件丹壕,就會生成一個容器庆械,可以直接在容器上運(yùn)行任務(wù)。例如我有一個apache服務(wù)網(wǎng)站菌赖,現(xiàn)在想要再另一臺服務(wù)器上復(fù)現(xiàn)缭乘,那么就必須先安裝apache服務(wù),配置運(yùn)行環(huán)境琉用,將網(wǎng)站文件復(fù)制過去堕绩,再運(yùn)行。這樣就很麻煩邑时,而且打不準(zhǔn)會出現(xiàn)環(huán)境變量或者配置問題奴紧。但如果使用docker將這個服務(wù)打包的話就不用這么麻煩了。直接在另一臺服務(wù)器上運(yùn)行復(fù)現(xiàn)就可以了晶丘。
安裝docker
docker的安裝按照官網(wǎng)的來就行了黍氮,不同系統(tǒng)的安裝方法都有。由于我使用的是ubuntu系統(tǒng)浅浮,這里就只講Ubuntu系統(tǒng)下docker的安裝沫浆。Ubuntu下的安裝非常簡單(不是最新版的話)。一般來說只要apt直接安裝就可以了滚秩。最新版的安裝比較復(fù)雜专执,大家還是去看官網(wǎng)的安裝方法吧。
sudo apt-get install docker
安裝完之后可以測試一下
sudo docker run hello-world
如果出現(xiàn)下面的輸出則說明安裝成功了
Hello from Docker!
This message shows that your installation appears to be working correctly.
... ...
修改image倉庫的鏡像地址
在上面的命令中
sudo docker run hello-world
會根據(jù)hello-world這個鏡像,生成一個容器運(yùn)行郁油。 當(dāng)然第一次運(yùn)行的時候我們本地并沒有這個鏡像, 這時候docker會從官網(wǎng)尋找鏡像, 并pull到本地本股。也就是先執(zhí)行了下面的語句
sudo docker pull hello-world
但是如果使用默認(rèn)的官方倉庫下載速度將會非常慢,沒辦法官網(wǎng)在國外桐腌。我們可以把默認(rèn)docker下載倉庫改成國內(nèi)倉庫拄显,這樣下載速度會快很多。
sudo vim /etc/default/docker
在文件的最后面加上一句
DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"
然后重啟docker服務(wù)
sudo service docker restart
這樣就會從國內(nèi)倉庫下載鏡像了案站。
創(chuàng)建docker用戶組(可選)
大家如果注意我上面的命令凿叠,會發(fā)現(xiàn)再docker命令之前都有sudo,也就是只有root用戶才有權(quán)限運(yùn)行docker的命令嚼吞。這是由于在默認(rèn)情況下,docker只允許root用戶和docker用戶組的用戶訪問Docker引擎蹬碧。一般情況下我們不會直接使用root用戶舱禽,因此最好的方法是將當(dāng)前使用的用戶加入到docker用戶組。
# 建立docker用戶組
sudo groupadd docker
# 將當(dāng)前用戶添加到docker用戶組中
sudo usermod -aG docker $USER
這樣當(dāng)前用戶就添加到了docker用戶中恩沽,可以直接運(yùn)行docker命令了誊稚。測試一下
docker run hello-world
如果執(zhí)行成功,那就說明配置生效了。如果出現(xiàn)下面類似的情況里伯, 就說明當(dāng)前用戶的docker配置文件權(quán)限方面存在問題城瞎。
WARNING: Error loading config file:/home/user/.docker/config.json - stat /home/user/.docker/config.json: permission denied
可以用下面的命令修改一下權(quán)限
sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
sudo chmod g+rwx "/home/$USER/.docker" -R
這樣應(yīng)該就可以了。
使用Dockerfile定制鏡像
上面的準(zhǔn)備工作做完之后疾瓮,就可以開始創(chuàng)建鏡像了脖镀。一般我們很少從頭創(chuàng)建一個鏡像,我們會根據(jù)現(xiàn)有的鏡像來進(jìn)行定制狼电。鏡像的創(chuàng)建有多種方法蜒灰,這里采用官網(wǎng)推薦的方法。使用Dockerfile創(chuàng)建肩碟,Dockerfile是包含一串指令的文本文件强窖。Dockerfile首先要指定一個基礎(chǔ)鏡像,然后在這個鏡像上執(zhí)行指令削祈,例如安裝軟件翅溺,修改配置等。這樣就生成了一個定制的鏡像了髓抑。
創(chuàng)建一個文件夾并進(jìn)入該文件夾創(chuàng)建一個Dockerfile咙崎。
mkdir MetaPhlAn
cd MetaPhlAn
touch Dockerfile
再創(chuàng)建一個content文件夾,用來存放本項(xiàng)目中需要用到的依賴包启昧。也就是前面所說的biobakery和bowtie2叙凡。然后將下載下來的biobakery和bowtie2存放到該目錄下。
mkdir content
# 將biobakery和bowtie2拷貝到該目錄下
接下來開始編寫Dockerfile文件密末。在Dockerfile文件中寫入下面的內(nèi)容握爷。
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指定為基礎(chǔ)鏡像严里。也就是說我們接下來的指令都是在ubuntu鏡像下執(zhí)行的新啼。這條語句是必須的。這里有一個特殊的鏡像值得一提刹碾。那就是 scratch鏡像燥撞,它表示一個空白的鏡像,有什么用呢迷帜?有時候僅僅只是把二進(jìn)制的可執(zhí)行文件進(jìn)行打包物舒。這時候并不依賴任何環(huán)境,這時候scratch鏡像就可以用到了戏锹。
WORKDIR /bowtie2
COPY content /root/
WORKDIR指令用來指定鏡像中的工作目錄冠胯,如果鏡像中沒有這個目錄,則會自動幫你創(chuàng)建锦针。
COPY指令是將文件傳入到鏡像中荠察。源文件的各種元數(shù)據(jù)都會保留置蜀。比如讀、寫悉盆、執(zhí)
行權(quán)限盯荤、文件變更時間等。這條指令的意思就是把該content文件夾下的所有文件拷貝到鏡像中的/root/目錄下焕盟。注意是content文件夾下的內(nèi)容秋秤,而不是文件夾。
ENV MDIR="/root/metaphlan2" PATH="/root/metaphlan2:/root/metaphlan2/utils:$PATH" \
PATH="$PATH:/root/bowtie2-2.3.4.1-linux-x86_64"
這條指令的意思是給鏡像中Ubuntu添加環(huán)境變量京髓,這是為了讓我的python程序可以運(yùn)行航缀,因?yàn)樵損ython程序必須用到biobakery和bowtie2。因此將它們添加到環(huán)境變量堰怨,以便程序運(yùn)行時可以找到芥玉。
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包的依賴揽涮。
值得注意的是當(dāng)你安裝的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的地址告抄,這里當(dāng)然就是本目錄了。
如無意外的話嵌牺, 就會生成一個metaphlan-docker鏡像(有點(diǎn)久打洼,需要耐心等一等)。
運(yùn)行鏡像
安裝完之后自然是需要試試的逆粹。
docker run -i -t --rm -v ~/data:/bowtie2 metaphlan-docker bash
-i 是交互的意思募疮。
-t 是打開一個terminal的意思
-v 是掛載目錄,后面的參數(shù)是 本地的目錄:鏡像目錄僻弹, 像我這里的意思就是把鏡像中的 /bowtie2掛載到本地的 ~/data目錄下酝锅。也就是我在本地~/data目錄下的任何操作,都會映射到容器中的 /bowtie2目錄奢方,這樣就實(shí)現(xiàn)了本地和容器的文件傳輸搔扁。