Docker基本命令
鏡像
-
版本
docker version
-
登錄
docker login -u User -p Pasword <docker-server>
Docker會將token存儲在~/.docker/config.json文件中,從而作為拉取私有鏡像的憑證。
-
註銷
docker logout <docker-server>
-
查詢
docker images
-
搜索鏡像
docker search image
-
拉取鏡像
docker pull image:tag
docker pull ubuntu Using default tag: latest latest: Pulling from library/ubuntu da7391352a9b: Pull complete 14428a6d4bcd: Pull complete 2c2d948710f2: Pull complete Digest: sha256:c95a8e48bf88e9849f3e0f723d9f49fa12c5a00cfc6e60d2bc99d87555295e4c Status: Downloaded newer image for ubuntu:latest docker.io/library/ubuntu:latest
- 默認抓取的地址是官方的 docker hub,官方存放鏡像的位置默認在 library 目錄下
- 在抓取的時候,先有一個下載的過程,鏡像是多層存儲所構成,分層下載,並非單一文件,下載過程中給出了每一層的前 12 位 ID
- 下載結束後,顯示 pull complete,並給出該鏡像的完整
sha256
摘要
-
創建鏡像
docker image build -t <image name>:<tag> .
- -t 指定 image 文件,最後的
.
表示上下文環境,Dockerfile 在當前路徑 - -f 指定dockfile 文件
- -t 指定 image 文件,最後的
-
查看鏡像
# 列出所有鏡像,不包含中間層鏡像 docker images # 或者 docker image ls # 列出所有虛懸鏡像 docker image ls -f dangling=true # 列出所有鏡像,包含中間層鏡像 docker images -a # 或者 docker image ls -a # 列出指定鏡像 docker images <image name>
REPOSITORY TAG IMAGE ID CREATED SIZE mysql 8.0 ab2f358b8612 10 days ago 545MB
說明:
- REPOSITORY 表示鏡像名
- TAG 表示鏡像標記,通常是版本號,或者其他可以區別鏡像不同版本的標記
- IMAGE ID 表示鏡像 ID,鏡像可以通過
<REPOSITORY>:<TAG>
來識別,也可以通過<IMAGE ID>
來識別 - CREATED 表示這個鏡像製作的時間
- SIZE 表示這個鏡像的大小
注意:
無標籤的鏡像
<none>
,與之前的虛空鏡像不同,這些無標籤的鏡像很多都是中間層鏡像,是其他鏡像的依賴對象,只要刪除了這些中間層鏡像,這些依賴他們的鏡像也將會被刪除。 -
查看鏡像的詳細資訊
docker inspect <image name>:<tag>
-
刪除鏡像
docker rmi <image name>:<tag>
# 或者
docker image rm <image name>:<tag>
# 刪除所有鏡像
docker rmi $(docker images -q)
# 或者
docker image prune -f -a
標籤名預設是latest,如果標籤名是latest,則不用添加標籤名
- -f 參數: 強制刪除此鏡像,並會刪除通過此鏡像創建的容器
-
發布鏡像
docker push <image name>:<tag>
容器
容器的實質是進程,容器進程運行於屬於自己的獨立的命名空間。容器也是分層存儲,每一個容器運行時,是以鏡像為基礎層,在其上創建一個當前容器的存儲層。
- 列出正在運行的容器文件
docker ps
# 或者
docker container ls
# 列出所有的容器文件(包括停止運行的容器)
docker ps -a
# 或者
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6f4e1e80e33c echo1:1.0 "/bin/sh -c 'echo us…" 55 minutes ago Exited (0) 55 minutes ago strange_mirzakhani
0094e5d008c9 mysql:8.0 "docker-entrypoint.s…" 4 days ago Exited (255) 4 days ago 33060/tcp, 0.0.0.0:3308->3306/tcp slave_mysql
174711ccb475 mysql:8.0 "docker-entrypoint.s…" 4 days ago Exited (255) 4 days ago 33060/tcp, 0.0.0.0:3307->3306/tcp master_mysql
- CONTAINER ID 表示容器 ID
- IMAGE 表示運行的鏡像,鏡像和容器的關係,就像是面向對象程式設計中
類
和實例
一樣,鏡像是靜態的定義,容器是運行時的實體 - CREATED 表示運行的時間
- STATUS UP表示運行
- PORTS 表示可以通過指定的埠號來訪問
- NAMES 表示對鏡像容器的描述
- COMMAND 表示表示容器啟動後運行的命令
- STATUS UP表示運行,Exited表示已經停止運行了
-
運行容器
docker run -p 3307:3306 --name <container name> -d <image name>:<tag>
- -p參數:容器的 3306 埠映射到本機的 3307 埠
- –name參數:指定容器名
- -d參數: 後台運行
-
進入容器
docker exec -it <container ID>|<container name> /bin/bash
- -it參數:容器的 Shell 映射到當前的 Shell,然後你在本機窗口輸入的命令,就會傳入容器
- /bin/bash:容器啟動以後,內部第一個執行的命令。這裡是啟動 Bash,保證用戶可以使用 Shell
-
停止容器
docker stop <container ID>|<container name> # 停止所有容器 docker stop $(docker ps -aq)
-
刪除容器
docker rm <container ID>|<container name> # 刪除所有停止的容器 docker container prune # 或者 docker rm $(docker ps -aq)
-
查詢容器ip
docker inspect --format='{{.NetworkSettings.IPAddress}}' container_id|container_name
-
查看容器日誌
docker logs -f <container ID>|<container name>
- -f 參數: 代表會實時刷新日誌資訊
-
查看容器的詳細資訊
docker inspect <container ID>
-
複製文件
# docker -> local docker cp <container ID>:/opt/file.txt /opt/local/ # local -> docker docker cp /opt/local/file.txt <container ID>:/opt/
Dockfile
Dockerfile 中的每一條指令都會建立一個層,所以多條sh
指令最好使用&&
,;
等連接,這樣生成的層會很少,鏡像也會小很多。
- Dockerfile 必須以
FROM
開頭 - 一個 Dockerfile,只能有一個
ENTRYPOINT
,如果有多個以最後一個為準 - 一個 Dockerfile,只能有一個
CMD
,如果有多個以最後一個為準 - 在Dockerfile中,ENTRYPOINT指令或CMD指令,至少必有其一
-
Dockerfile
FROM alpine:latest as production LABEL Author="[email protected]" RUN mkdir /lib64 &&\ ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 &&\ echo "//mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories &&\ echo "//mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories &&\ apk add tzdata &&\ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\ echo "Asia/Shanghai" > /etc/timezone &&\ mkdir -p /app/ /config/ COPY ./bin/* /app/* COPY ./config/* /config/ EXPOSE 8080 ENTRYPOINT ["/app/server","-c","/config/app.yaml"]
-
FROM 指定基礎鏡像為 alpine,版本為 latest,並重命名為
production
-
LABEL 指定署名郵箱
-
RUN 指定在容器內執行的命令
# musl和glibc是兼容的,通過創建該符號鏈接修復缺少的依賴項,可以保證編譯後 go 程式可以正常運行 mkdir /lib64 ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 # 更新源 echo "//mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories echo "//mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories # 同步時間 apk add tzdata ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime echo "Asia/Shanghai" > /etc/timezone # 創建項目目錄 mkdir -p /app/ /config/
-
COPY 將當前本機上的文件複製到容器內指定位置
-
EXPOSE 容器將使用 8080 埠,這裡只是聲明並不會建立和本機的埠映射
-
ENTRYPOINT 容器啟動時執行的命令
/app/server -c /config/app.yaml
-
-
FORM
基礎鏡像必須指定,FROM指令指定基礎鏡像,因此一個 Dockerfile 文件中 FROM 是必備指令,而且是第一個指令
FROM scratch
指定一個空白鏡像,scratch 不以任何鏡像為基礎,接下來寫的指令將作為鏡像第一層開始存在 -
LABEL
添加元數據到鏡像。
LABEL
是以鍵值對形式出現的 -
RUN
在容器內執行指定命令
-
COPY
將本機構建上下文中的指定文件複製到鏡像中
-
ADD
僅在需要自動解壓縮的情況下才使用ADD指令,如果只是複製文件就使用COPY指令
-
ENV
設置容器的環境變數
ENV name=linux
-
EXPOSE
聲明容器將要使用的埠,並不建立和主機的埠映射。當運行容器時使用
-p
才是真正的建立埠映射 -
ENTRYPOINT
-
exec格式用法 [推薦]
程式入口點,執行
docker run
命令時,設置的任何命令參數或CMD指令的命令,都將作為ENTRYPOINT指令的命令參數,追加到ENTRYPOINT指令的命令之後。ENTRYPOINT ["top","-b","-H"]
如果此時創建docker 實例
docker run <container-name> -v
則實際執行的命令是
top -b -H -v
-
shell 格式用法
屏蔽追加任何參數,即CMD指令或docker run … 的參數都將被忽略。
ENTRYPOINT top -b -H
在創建容器後會首先調用Shell,即自動在命令前面追加
/bin/sh -c
。既容器啟動時,將執行/bin/sh -c top -b -H
。這樣會導致top
命令就不是容器中的第一個進程PID 1,這樣在容器停止的時候就無法收到系統的SIGTERM訊號。要想收到SIGTERM訊號,務必使用Bash的內置exec命令使得top的PID 1,定義ENTRYPOINT指令如下:ENTRYPOINT exec top -b -H
-
-
CMD
用於指定默認的容器主進程的啟動命令。
不同格式:
-
exec格式用法 [推薦]
參數追加模式,第一個參數必須是命令的全路徑
如果
docker run
沒有指定任何的執行命令或參數,但是,dockerfile 中有CMD和ENTRYPOINT, 那麼 CMD 中的全部內容將作為 ENTRYPOINT 的參數FROM ubuntu:latest CMD ["echo","username"] ENTRYPOINT ["echo","ENTRYPOINT"]
# 構建 docker image build -t echo1:2.0 -f Dockerfile . # 無參運行 docker run echo1:2.0 # 輸出:ENTRYPOINT # 帶參數運行 docker run echo1:2.0 echo "test" # 輸出:ENTRYPOINT echo test
輸出變數:
FROM ubuntu:latest ENV user=feiquan # 這種寫法無法輸出變數,會直接輸出 username:$user # CMD ["username:$user"] # ENTRYPOINT ["/bin/echo,"echo ENTRYPOINT:$user"] CMD ["/bin/sh","-c","echo username:$user"] ENTRYPOINT ["/bin/sh","-c","echo ENTRYPOINT:$user"]
# 構建 docker image build -t echo1:4.0 -f Dockerfile . # 無參運行 docker run echo1:4.0 # 輸出:ENTRYPOINT:feiquan # 帶參數運行 docker run echo1:4.0 docker run echo1:4.0 && echo "test:$user" # 輸出:
ENTRYPOINT:feiquan test:
由於在傳入
&& echo "test:$user"
時,$user
使用的本機中環境變數,它為空,所以這裡命令在追加後執行的其實是/bin/sh -c echo ENTRYPOINT:$user && echo "test:"
。設置
user=xx
後,再次執行輸出:ENTRYPOINT:feiquan test:xx
-
shell 格式用法
屏蔽追加任何參數,即CMD指令或docker run … 的參數都將被忽略。在創建容器後會首先調用Shell,即自動在命令前面追加
/bin/sh -c
。如果
docker run
沒有指定任何的執行命令或者dockerfile裡面也沒有ENTRYPOINT,那麼,就會使用cmd指定的默認的執行命令執行。FROM ubuntu:latest CMD echo username
# 構建 docker image build -t echo1:1.0 -f Dockerfile . # 無參運行 docker run echo1:1.0 # 輸出:username # 帶參數運行 docker run echo1:1.0 echo "test" # 輸出:test
輸出變數:
FROM ubuntu:latest ENV user=feiquan CMD echo username:$user
# 構建 docker image build -t echo1:3.0 -f Dockerfile . # 無參運行 docker run echo1:3.0 # 輸出:username:feiquan # 帶參數運行 docker run echo1:3.0 echo "test" # 輸出:test
-
-
WORKDIR
指定工作目錄,也就是啟動容器後終端所在路徑,默認
~
。如果WORKDIR指 定的目錄不存在,即使隨後的指令沒有用到這個目錄,都會創建 -
VOLUME
實現數據的持久化,為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在 Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。
-
管理卷
# 創建一個自定義容器卷 docker volume create mdata # 查看所有容器卷 docker volume ls # 查看指定容器卷詳情資訊 docker volume inspect mdata
[ { "CreatedAt": "2020-12-22T10:41:39Z", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/mdata/_data", "Name": "mdata", "Options": {}, "Scope": "local" } ]
-
使用指定卷
FROM ubuntu:latest VOLUME /data RUN ls -ah / > /data/dir.txt ENTRYPOINT sleep 10000
# 構建 docker image build -t echo1:5.0 -f Dockerfile . # 掛載 docker run -d -v mdata:/data echo1:5.0
- -v參數:-v代表掛載數據卷,這裡使用自定義卷
mdata
,並將其掛載到/data
- -v參數:-v代表掛載數據卷,這裡使用自定義卷
-
進入容器查看:
docker exec -it 90177637380d /bin/bash ls data
root@90177637380d:/# ll /data/ total 12 drwxr-xr-x 2 root root 4096 Dec 22 11:26 ./ drwxr-xr-x 1 root root 4096 Dec 22 11:12 ../ -rw-r--r-- 1 root root 119 Dec 22 11:10 dir.txt
-
本機查看
# mac 主機需要先執行 # screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty ll /var/lib/docker/volumes/mdata/_data
-
刪除卷
docker volume rm <volume-name>
-