由淺入深 docker 系列: (2) docker 構建

lixiang9194發表於2018-11-16

在上一篇教程裡,我們學會了docker的使用,也體驗了docker的隔離性,在裡面隨意增刪軟體,不用的時候直接刪除映象容器,很方便。但是,還有問題,如果你的朋友也想試用你的軟體,怎麼辦呢?或者你換了臺電腦,又要重新pull然後在docker裡install麼?

當然不用,我們說過docker具有快速部署的優點。今天我們學習怎麼構建我們自己的docker映象。


一:docker commit

最直觀的思路,自然是將我們的容器儲存下來。而docker也為此提供了很方便的命令,即 docker commit。其格式為

docker commit -a "author" -m "message" <exiting-container> <hub-user>/<repo-name>[:<tag>]

是不是很像 git的commit命令?其中 exiting-container為你的容器名稱或 id,hub-user 為你登入的 DockerHub 使用者名稱,repo-name 為你想給新映象起的名字。

映象構建成功之後,就可以分享了

你可以使用 docker save <image> | gzip > fileName 將 image 儲存為檔案,然後拷貝給他人,再通過 docker load -i fileName匯入使用。

這麼做太麻煩了。推薦方式是使用 docker push 命令將其推送到 DockerHub,當然你需要先登入。

我把上次的 ubuntu 做了commit,並 push 到了 DockerHub,成功之後就可以在DockerHub看到自己的映象了,之後可以隨時拉取使用。

另外,通過docker history 可以看到容器的建立歷史,我們可以試下。

我們發現,在軟體內部增刪軟體、檔案等操作在這裡都無法體現,因此我們的映象事實上成了一個黑盒,沒有文件就不知道其具體有什麼功能,即使你新增了文件,經過一次次更改文件很可能也沒有同步了,非常不方便別人或者自己以後使用。事實上,docker 提供了更方便強大的方式構建映象,即 Dockerfile。

另外,commit 方式在特定場景下也有其用途,比如程式崩潰、被入侵後儲存現場時,就很有用。


二:Dockerfile

Dockerfile 是一個文字檔案,其內包含了一條條的指令,描述我們的映象該如何構建,就像我們程式的原始碼。在這之前,補充一個知識,就是我們的 docker 映象檔案事實上是分層的。你應該注意到拉取 ubuntu 的時候,它pull 了很多次。而分層的操作也方便不同映象間共享相同的層,這顯著的節省了客戶機的儲存空間以及下載時間。

例如,我再拉取一個 nginx 映象,你會發現第一層已經存在了,直接複用。

為什麼要講這個?因為 Dockfile 的每一條指令的內容,就是描述該層應當如何構建。

我們首先來定製一個 nginx 映象。

任意新建一個資料夾,建立一個文字檔案,命名為 Dockerfile。

文字內容如下:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

然後執行docker build命令構建映象

docker build -t "name:tag" path


可以發現,如之前所說,新的容器分兩層構建。注意命令最後有一個點,表示當前資料夾。

然後,執行 docker run 啟動映象。

這時訪問http://127.0.0.1:8080 應該就能看到我們的頁面了。注意之前的映象可能已經繫結了本機8080埠,你需要停止它或者換一個埠。還有-d參數列示後臺執行,注意-d 並不影響容器的執行時間,只是將其放到了後臺,換句話說,如果你的容器本身沒有執行不退出的程式,即使加了-d 容器依然會自動退出。

同樣你可以將其推送到 DockerHub,或者僅僅將你的 Dockerfile 分享給他人就可使用。另外,你可以將 Dockerfile 與你的程式碼一同上傳 github 或其他系統,更方便你的應用環境搭建,也可以進行docker 的版本管理。甚至,你還可以設定Docker Hub結合Github自動化構建映象

接下介紹常用的 Dockerfile 命令。

1. FROM 命令
FROM為指定基礎映象,像之前我們基於官方 nginx 進行定製,這樣可以省略大量的重複工作。DockerHub 上有大量的映象,ubuntu、mysql、php、python 等等,一定要選擇合適的作為基礎映象,比如開發 django 就選用 python 或者django 映象,而不要去用 php 映象。

2. RUN 命令

RUN 命令即用來在容器中執行命令的,相當於你之前手動在 docker 裡面執行命令。

其格式也很簡單,RUN <command>即可,command可以是容器內能執行的任何命令。

這裡說下本人的經驗,RUN 命令不一定能成功執行,你不必一遍遍更改然後 build 實驗,可以直接 run 一個基礎映象,然後去執行命令,等成功了再寫入 Dockerfile,會方便很多。

另外,之前說過,每條命令會構建一層,所以不要寫太多層 RUN,也不要只有一層,單獨的功能模組組合到一層,更利於快速構建以及複用。比如下面這個例子:

FROM php:7.1.22-fpm

# Install PHP and composer dependencies
RUN apt-get update \
    && apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev \
    && RUN apt-get clean

# Install needed extensions
RUN docker-php-ext-install pdo pdo_mysql mcrypt zip gd

3. COPY 命令

COPY 命令用於將檔案拷貝到映象中。

COPY <源路徑> <目標路徑>
你可以將需要的檔案拷貝到映象內,注意這裡源路徑是相對路徑,即相對上文構建命令裡的最後一個引數所指定的目錄(上文例子為.),不能隨意引用其它檔案。另外,儘量不要在構建目錄裡放入無關檔案,因為 docker 會將目錄下所有檔案打包傳送給服務程式,如圖所示

4. CMD命令

CMD 命令為容器啟動時的預設命令,因為容器其實本質是一個程式(後面會細講)。比如 ubuntu 映象預設CMD 命令為/bin/bash,因此事實上我們只要執行 docker run -it ubuntu就可以得到一個互動式 shell。如果我們傳入其它命令,比如 執行 docker run ubuntu uname,容器就會執行我們指定的命令。

以上就是最常用的Dockerfile 命令,建議大家自己嘗試構建一個,會有更深的體會。另外還有很多命令以及細節,可以參考這篇教程,寫的特別好,強烈推薦。

相關文章