方便查閱的 Docker 基本命令。

使用 容器(Container)

docker 程序是否存在,功能是否正常

1
docker info

新建並啟動

1
2
docker run hello-world  
docker run ubuntu /bin/echo 'Hello world'

啟動一個 bash 終端,允許使用者進行互動

1
docker run -i -t ubuntu /bin/bash
  • -t 選項讓 Docker 分配一個虛擬終端(pseudo-tty)並綁定到容器的標準輸入上。
  • -i 則讓容器的標準輸入保持打開。

查看系統中的容器列表

1
docker ps -a

只看執行中的

1
docker ps

指定容器名稱

有名稱方便重覆使用

1
docker run --name my_ubuntu -i -t -v $PWD/website:/var/www/html/website ubuntu /bin/bash

  • –name <指定名稱> : 可用字元 [a-zA-Z0-9_.-]。
  • -v:掛載本地的目錄到容器中的目錄 - 重要的能力。在 Docker Toolbox 中只有 Users 目錄有權限。

啟動已終止容器

1
docker start my_ubuntu

用 ID 也可以

1
docker start ac3f3b5f0f4e

進入已啟動的容器

重新啟動後,要 再進入 才能進行操作

1
docker attach my_ubuntu

  • attach 會接到啟動時指定的 /bin/bash 實例。所以多個視窗同時 attach 到同一個容器的時候,所有視窗都會同步顯示。
  • 從 stdin 中 exit, 會導致容器停止。
1
docker exec -i -t my_ubuntu /bin/bash
  • 如果啟動時沒有下 /bin/bash,就要用 exec 去建立 bash 的實例。
  • 從 stdin 中 exit, 不會導致容器停止。

以守護態(Daemonized)執行

1
docker run -d --name my_ubuntu2 ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
  • -d 參數 : 以守護態執行。
  • -c 要執行的命令串。
  • 只返回 ID。
  • 輸出訊息不輸出到 Stdout 了。
  • -p : 將容器內應甪程式的對外 port 對應到主機的 port,如 Oracle 為 -p 1521:1521

取得容器的輸出訊息

1
2
docker logs my_ubuntu2
docker logs -t -f --tail 10 my_ubuntu2

  • -t : 加上時間。
  • -f : 持續列出最新。
  • –tail 10 : 只列最後 10 筆。

停止容器

1
docker stop my_ubuntu2

查看容器內的進程

1
docker top my_ubuntu

容器的統計信息

1
docker stats my_ubuntu my_ubuntu2
  • 可以列表方式看到多個內容。

取得容器的詳細資訊

1
docker inspect my_ubuntu

配合 -f 或 –format 來選定結果,如以下取得 ip address

1
docker inspect --format '{{ .NetworkSettings.IPAddress }}' my_ubuntu

  • –format 支持完整的 Go 語言模板。

刪除容器

1
docker rm my_tmp_ubuntu
  • 加上 -f 參數 : 刪除執行中的容器。

刪除全部容器

1
docker rm `sudo docker ps -a -q`

  • -q : 只回容器 ID。

映像檔(Image) 及 倉庫(Repository)

倉庫

包括映像檔,層及關於映像檔的資訊(metadata)。

每個倉庫可以存放很多映像檔(不同版本),如 ubuntu 12.04 16.04 18.04,利用 TAG 功能就可以指定到特定映像檔,如 ubuntu:16.04。

Docker Hub 的用戶倉庫命名由用戶名和倉庫名組成,如 john/shoppingweb; 頂層倉庫則只包含倉庫名,如 ubuntu。

列出映像檔

1
docker images

列出特定映像檔

1
docker images ubuntu

拉取映像檔

1
docker pull httpd
  • 當 run 的時候本機還沒有所需的映像檔就會執行拉取。

查詢 Docker Hub 上可用映像檔

1
docker search aspnetcore

建立映像檔

用 docker commit 建立異動過的映像檔

如,在 my_ubuntu 中加入 apache2 後

1
docker commit 4aab3ce3cb76 user1/apache2

  • 4aab3ce3cb76 : 容器 ID。
  • user1/apache2 : 用戶倉庫名。
  • commit 提交的只是建立時的映像檔和現在況態有差異的部份。
1
docker commit -m "Added apache" -a "Docker Newbee" 4aab3ce3cb76 user1/apache2:v2
  • -m : 說明訊息。
  • -a : 更新的使用者訊息。

已不推薦使用 docker commit 方法,最好用 Dockerfile。

用 Dockerfile 來構建映像檔

  • 建立一個目錄做為構建環境。
  • 編寫 Dockerfile 文字檔 : Dockerfile 由一系列指令和參數組成。
  • docker build 基於 Dockerfile 進行構建。
    • -t : 映像檔名稱

例子:

Dockerfile

1
2
3
4
5
6
# Version: 0.0.1 
FROM ubuntu:16.04
MAINTAINER John Wick "john@example.com"
RUN apt-get update && apt-get install -y nginx 
RUN echo 'Hi, I am in your container' > /usr/share/nginx/html/index.html 
EXPOSE 80

docker build

1
docker build -t="user1/static_web" .

  • 最後的 . 指定 Dockerfile 在同目錄中。
  • Dockerfile 的路徑可以是 Git repository 根目錄 : git@github.com:user1/docker-static_web。
  • Dockerfile 可以在子目錄中且不用叫 Dockerfile : path/to/file。

錯誤處理

可以用 docker run 執行失敗的映像檔到已成功的部份,再手動執行出錯的命令做調試,找到正確的命令。

不使用暫存資料

構建過程中,沒問題的映像會被暫存下來以加快下次執行,如果要它重頭執行不用暫存資料,加上 --no-cache

1
docker build --no-cache -t="user1/static_web" .

Dockerfile

Dockerfile 由一系列指令和參數組成。每條指令,如 FROM,都必須為大寫字母,且後面要跟隨一個參數:FROM ubuntu:14.04。
Dockerfile 中的指令會按順序從上到下執行,所以應該根據需要合理安排指令的順序。

每條指令都會創建一個新的文件層並對映像檔進行提交。Docker 大體上按照如下流程執行 Dockerfile 中的指令。

  • Docker 從基礎映像檔運行一個容器。
  • 執行一條指令,對容器做出修改。
  • 執行類似 docker commit 的操作,提交一個新的文件層。
  • Docker 再基於剛提交的映像檔運行一個新容器。
  • 執行 Dockerfile 中的下一條指令,直到所有指令都執行完畢。

註解

# 開頭的就是註解內容

FORM

第一條指令必須是 FROM,也是唯一必填指令。
FROM 指定一個已經存在的映像檔,後續指令都將基於該映像檔進行,這個映像檔被稱為基礎映像檔(base iamge)。

1
2
3
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>

如:
FROM ubuntu:14.04。

MAINTAINER

映像檔作者資訊

1
MAINTAINER <作者資訊>

如:
MAINTAINER John Wick
MAINTAINER John Wick “john@example.com”

RUN

在映像檔中執行命令

1
2
RUN <command>
RUN ["executable", "param1", "param2"]

  • RUN \:後面的命令其實是由 /bin/sh -c 來負責執行,所以,在映像檔中必須要有/bin/sh。
  • RUN [“executable”,”param1”,”param2”]:可以執行映像檔中任意一個可執行檔或命令,[]中的內容都會按照 JSON 字串的格式進行解析,因此只能使用雙引號 “。如用 bash 來執行:
    RUN ["/bin/bash", "-c", "echo hello"]
  • 命令產生的結果預設會被後續所有指令重用。

CMD

用來設定映像檔預設執行命令

1
2
3
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

  • 第 1 種用法:是推薦的用法,其設定的命令將作為容器啟動時的預設執行命令。
  • 第 2 種用法:param 將作為 ENTERPOINT 的預設參數使用。
  • 第 3 種用法:將後面的命令作為 shell 命令,依靠 /bin/sh –C 來執行。
  • 可以有多個 CMD,但只有最後一個 CMD 會生效。

LABEL

用鍵值對的形式來向映像檔中添加元數據(metadata)

1
LABEL <key>=<value> <key>=<value> <key>=<value> ...

如:
LABEL version=”1.0”

  • 執行完命令之後,同樣會產生一個新的文件層。
  • 新值會覆蓋舊值。
  • 可以用 Docker 的 inspec 命令查詢。

EXPOSE

通知 Docker 容器中哪些端口是應用程序開出來監聽

1
EXPOSE <port> [<port>...]

  • 容器啟動時配合 -p 或 -P 參數外部網路才可以訪問到這個 port。

ENV

設定環境變量

1
2
ENV <key> <value>
ENV <key>=<value> ...

  • 第 2 種用法:value 中存在空格時,需要使用「\」來進行轉義,如:ENV myDog=Rex\ The\ Dog \
  • 可以用 Docker 的 inspec 命令查詢。

COPY

向容器中指定路徑下添加文件

1
2
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

  • src 指定的路徑必須存在於 Dockerfile 所在目錄
  • 如果使用 STDIN 輸入 Dockerfile 內容,那麼 COPY 命令將失效

ADD

將 src 標記的文件,添加到容器中 dest 所標記的路徑中去

1
2
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

  • src 指定的路徑必須存在於 Dockerfile 所在目錄或指定外部 URL。
  • dest 是指向容器中的目錄,其路徑必須是絕對路徑,或相對於 WORKDIR 的相對路徑。
  • dest 有沒有以 “/“ 結尾會影響資料寫入的目的地。src 使用通配字元指定多個文件時,dest 必須以 “/“ 結尾的目錄。

ENTRYPOINT

1
2
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

設定容器運行時預設執行程序

  • 第 2 種用法:將後面的命令作為 shell 命令,依靠 /bin/sh –C 來執行。

如,MySQL官方提供的Dockerfile :

1
2
3
4
5
...
COPY Docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]

當 mysql 容器運行時,自動執行 /entrypoint.sh,而參數則是 mysqld

VOLUMN

在容器內部創建一個指定名稱的掛載點

1
VOLUME ["/data"]

  • 如果在 Dockerfile 中已經聲明了某個掛載點,那麼以後對此掛載點中文件的操作將不會生效。
    因此,通常只會在 Dockerfile 的結尾處聲明掛載點。

USER

切換用戶身份。當執行完命令後,後面所有的命令都將以新用戶的身份來執行

1
USER daemon

WORKDIR

切換當前工作目錄

1
WORKDIR /path/to/workdir

  • 影響到後續的 RUN、CMD、ENTRYPOINT、COPY和ADD指令中的路徑。
  • 可以在 Dockerfile 中出現多次,但最終生效的路徑是所有 WORKDIR 指定路徑的疊加 (使用相對路徑時)。
  • 只可以使用 ENV 設定的環境變量值。

ONBUILD

建立觸發命令集

1
ONBUILD [INSTRUCTION]

  • 觸發命令集在當前 Dockerfile 執行過程中不會執行,而當此鏡像被其他鏡像當作基礎鏡像使用時,將會被觸發執行。

參考資料及圖片來源

  1. Docker —— 從入門到實踐­ 簡中版(較新)
  2. The Go Programming Language - Package template

以上,開工吧!