從零創建一個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目錄,這樣就實現了本地和容器的文件傳輸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章