[小抄] Docker 基本命令
方便查閱的 Docker 基本命令。
使用 容器(Container)
docker 程序是否存在,功能是否正常
1 | docker info |
新建並啟動
1 | docker run 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
2docker 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 address1
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 : 映像檔名稱
例子:
Dockerfile1
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 build1
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
3FROM <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
2RUN <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
3CMD ["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
2ENV <key> <value>
ENV <key>=<value> ...
- 第 2 種用法:value 中存在空格時,需要使用「\」來進行轉義,如:
ENV myDog=Rex\ The\ Dog \
。 - 可以用 Docker 的 inspec 命令查詢。
COPY
向容器中指定路徑下添加文件1
2COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
- src 指定的路徑必須存在於 Dockerfile 所在目錄
- 如果使用 STDIN 輸入 Dockerfile 內容,那麼 COPY 命令將失效
ADD
將 src 標記的文件,添加到容器中 dest 所標記的路徑中去1
2ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
- src 指定的路徑必須存在於 Dockerfile 所在目錄或指定外部 URL。
- dest 是指向容器中的目錄,其路徑必須是絕對路徑,或相對於 WORKDIR 的相對路徑。
- dest 有沒有以 “/“ 結尾會影響資料寫入的目的地。src 使用通配字元指定多個文件時,dest 必須以 “/“ 結尾的目錄。
ENTRYPOINT
1 | ENTRYPOINT ["executable", "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 執行過程中不會執行,而當此鏡像被其他鏡像當作基礎鏡像使用時,將會被觸發執行。