Docker容器操作和大量實(shí)用案例(含詳細(xì)圖文)
前言
我們?cè)谏弦黄恼吕锩嬷v了很多的docker容器的命令,那么光講那么多命令卻不拿來(lái)用其實(shí)是不好的,我們?cè)谶@篇文章里面會(huì)著重于docker容器的實(shí)戰(zhàn)部分,講解大量實(shí)用案例。
一.容器的基本操作
先查看一下本地有啥鏡像

我們只想要nginx的1.22.0版本的,這里卻沒(méi)有,我們需要先docker pull嗎?完全沒(méi)有必要,我們直接docker run即可
docker run -d --name mynginx001 -p 8081:80 nginx:1.22.0

我們發(fā)現(xiàn)這個(gè)docker run會(huì)自動(dòng)去pull這個(gè)nginx的1.22.0版本的。

執(zhí)行完后我們看看

root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 214522b9d48f nginx:1.22.0 "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp mynginx001
容器也正常運(yùn)行起來(lái)了?。∵€行不,接下來(lái)我們?nèi)g覽器看看
http://150.158.139.86:8081/

我們可以獲取這個(gè)容器的更多信息
docker inspect mynginx001
docker inspect會(huì)自動(dòng)識(shí)別mynginx001是鏡像還是容器
- 如果說(shuō)mynginx001是鏡像,就會(huì)調(diào)用docker image inspect mynginx001
- 如果說(shuō)mynginx001是容器,就會(huì)調(diào)用docker container inspect mynginx001

……

這里有很多信息,我不想多說(shuō)。
其實(shí)我們也可以查看一下這個(gè)容器的日志
docker logs -f -n 5 mynginx001

我們現(xiàn)在去瀏覽器刷新一下

怎么樣?日志是不是變多了?。?/p>
我們接著往下面看
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 214522b9d48f nginx:1.22.0 "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp mynginx001
我們現(xiàn)在需要?jiǎng)h掉這個(gè)容器

這樣子不行,我們需要先停止,再刪除

非常的完美了吧!!
二.容器的狀態(tài)遷移
先看本地的鏡像
![]()
接下來(lái)我們就執(zhí)行下面這個(gè)命令
docker create --name myginx002 -p 8002:80 nginx:1.22.0
![]()
我們查看一下它的狀態(tài)

顯然是沒(méi)有啟動(dòng),并且處于Created狀態(tài)。

接下來(lái)我們就啟動(dòng)這個(gè)容器
docker start myginx002

我們?nèi)タ纯此臓顟B(tài)
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691eb910da07 nginx:1.22.0 "/docker-entrypoint.…" 2 minutes ago Up 2 seconds 0.0.0.0:8002->80/tcp, [::]:8002->80/tcp myginx002
很顯然,啟動(dòng)成功了,并且狀態(tài)是Up

接下來(lái)我們執(zhí)行下面這個(gè)命令
docker kill myginx002

現(xiàn)在我們?nèi)ビ^察一下這個(gè)容器的狀態(tài)
root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691eb910da07 nginx:1.22.0 "/docker-entrypoint.…" 5 minutes ago Exited (137) 1 second ago myginx002 root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
狀態(tài)變成了下面這樣子

現(xiàn)在我們繼續(xù)啟動(dòng)這個(gè)容器
docker start myginx002

當(dāng)然它的狀態(tài)也變成了下面這個(gè)

接下來(lái)我們執(zhí)行下面這個(gè)命令
docker stop myginx002

我們查看一下?tīng)顟B(tài)
root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691eb910da07 nginx:1.22.0 "/docker-entrypoint.…" 8 minutes ago Exited (0) 3 seconds ago myginx002 root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
我們看看它的狀態(tài)

現(xiàn)在我們接著重新啟動(dòng)我們的容器
docker start myginx002

當(dāng)然它的狀態(tài)也變成了下面這個(gè)

接下來(lái)我們執(zhí)行下面這個(gè)命令
docker restart myginx002
我們看看它的前后狀態(tài)變化
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691eb910da07 nginx:1.22.0 "/docker-entrypoint.…" 12 minutes ago Up About a minute 0.0.0.0:8002->80/tcp, [::]:8002->80/tcp myginx002 root@VM-16-14-ubuntu:~# docker restart myginx002 myginx002 root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691eb910da07 nginx:1.22.0 "/docker-entrypoint.…" 12 minutes ago Up 2 seconds 0.0.0.0:8002->80/tcp, [::]:8002->80/tcp myginx002
狀態(tài)變化還是很明顯的

接下來(lái)我們先去瀏覽器看看

現(xiàn)在還是可以正常刷新的?。。?/p>
執(zhí)行下面這個(gè)命令
docker pause myginx002

現(xiàn)在我們?nèi)ゲ榭匆幌滤臓顟B(tài)
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 691eb910da07 nginx:1.22.0 "/docker-entrypoint.…" 17 minutes ago Up 4 minutes (Paused) 0.0.0.0:8002->80/tcp, [::]:8002->80/tcp myginx002

狀態(tài)變這樣子了。有一個(gè)Paused?。?/p>
現(xiàn)在我們回去瀏覽器,點(diǎn)擊刷新,發(fā)現(xiàn)一直就是刷新不了了,但是原來(lái)的界面還在
![]()
現(xiàn)在我們執(zhí)行下面這個(gè)命令
docker unpause myginx002

去查看一下容器的狀態(tài)

我們回去瀏覽器,發(fā)現(xiàn)可以正常刷新了

三.容器的批量搜索技巧
3.1.docker container ls
這里涉及到一個(gè)新的命令——docker container ls
實(shí)際上,docker ps 是 docker container ls 的簡(jiǎn)寫(xiě)形式。在早期的 Docker 版本中,我們使用 docker ps 來(lái)列出容器。后來(lái),Docker 引入了更明確的命令結(jié)構(gòu),將命令按功能分組,例如 container、image、network 等。因此,docker container ls 是更現(xiàn)代、更推薦的寫(xiě)法,但 docker ps 仍然被廣泛支持和使用。
首先,我們要明白 docker container ls(或者它的老版本寫(xiě)法 docker ps)是做什么的。
- 作用:列出當(dāng)前系統(tǒng)上的容器。
- 類(lèi)比:就像在 Windows 中打開(kāi)“任務(wù)管理器”查看運(yùn)行的程序,或者在 Linux/Mac 中使用 ps 命令查看進(jìn)程一樣。docker container ls 就是用來(lái)查看 Docker 世界的“進(jìn)程”(即容器)的。
現(xiàn)在,我們來(lái)深入理解你列出的這些“調(diào)味品”(參數(shù)),它們能讓 docker container ls 這道“主菜”變得更符合你的口味。
3.1.1. 基礎(chǔ)參數(shù):-a 和 -q
-a:顯示所有容器。
- 默認(rèn)情況:docker container ls 只顯示正在運(yùn)行的容器。
- 加上 -a:會(huì)顯示所有狀態(tài)的容器,包括正在運(yùn)行的和已經(jīng)退出/停止的。
- 使用場(chǎng)景:當(dāng)你需要查看曾經(jīng)運(yùn)行過(guò)的容器,或者確認(rèn)某個(gè)容器是否已經(jīng)停止時(shí)。
命令示例:
# 只查看正在運(yùn)行的容器 docker container ls # 查看所有容器(包括已停止的) docker container ls -a
-q:靜默模式,只返回容器 ID。
- 默認(rèn)情況:docker container ls 會(huì)返回一個(gè)表格,包含容器 ID、鏡像、命令、創(chuàng)建時(shí)間、狀態(tài)、端口等詳細(xì)信息。
- 加上 -q:它只返回純粹的容器 ID,沒(méi)有其他任何信息。
- 使用場(chǎng)景:這是批量操作的關(guān)鍵! 當(dāng)你需要將一堆容器的 ID 傳遞給另一個(gè)命令時(shí)(比如停止所有容器、刪除所有容器),-q 就變得極其有用。
命令示例:
# 查看所有容器的詳細(xì)信息 docker container ls -a # 只獲取所有容器的 ID(注意:包括已停止的) docker container ls -aq
3.1.2. 過(guò)濾參數(shù):-f 或 --filter
基本語(yǔ)法:
docker container ls --filter "<屬性鍵>=<屬性值>" # 或者使用短格式 docker container ls -f "<屬性鍵>=<屬性值>"
- 屬性鍵:你想根據(jù)容器的哪個(gè)特征來(lái)過(guò)濾。(例如:status、name……我們下面就會(huì)講)
- 屬性值:你希望這個(gè)特征符合什么條件。(例如:running、my-app、nginx)
工作原理:當(dāng)你使用 --filter 時(shí),Docker 會(huì):
- 檢查所有符合條件的容器。
- 只返回那些屬性與你的過(guò)濾條件匹配的容器。
- 忽略所有不匹配的容器。
讓我們來(lái)深入理解你列出的以及幾個(gè)最常用的屬性鍵。
1. 按狀態(tài)過(guò)濾:status
這是最常用的過(guò)濾器之一。
作用:根據(jù)容器的運(yùn)行狀態(tài)來(lái)篩選。
常用值:
- running:正在運(yùn)行
- exited:已停止/已退出
- created:已創(chuàng)建但未啟動(dòng)
- paused:已暫停
- restarting:正在重啟
示例:
# 只顯示正在運(yùn)行的容器 docker container ls -f "status=running" # 等價(jià)于不帶 -a 的 docker ps,但這樣寫(xiě)更明確 # 顯示所有已停止的容器 docker container ls -a -f "status=exited" # 注意:查看已停止的容器通常需要加上 -a
2. 按名稱(chēng)過(guò)濾:name
- 作用:根據(jù)容器的名稱(chēng)來(lái)篩選。
- 重要特點(diǎn):它使用的是模糊匹配(包含匹配),而不是精確匹配。只要容器名字包含你提供的字符串,就會(huì)被找出來(lái)。
示例:
假設(shè)你有以下幾個(gè)容器:web-server, my-database, database-backup, old-web-container。
# 查找名字中包含 "web" 的容器 docker container ls -a -f "name=web" # 結(jié)果:會(huì)顯示 'web-server' 和 'old-web-container' # 查找名字中包含 "data" 的容器 docker container ls -a -f "name=data" # 結(jié)果:會(huì)顯示 'my-database' 和 'database-backup'
3. 按鏡像過(guò)濾:ancestor
作用:根據(jù)容器是由哪個(gè)鏡像創(chuàng)建的來(lái)篩選。
“祖先”的含義:一個(gè)容器是從一個(gè)鏡像產(chǎn)生的,所以鏡像就是容器的“祖先”。
它可以匹配:
- 鏡像名(如 nginx, ubuntu)
- 鏡像名:標(biāo)簽(如 nginx:latest, ubuntu:20.04)
- 鏡像 ID(長(zhǎng)的哈希值,如 d123a6c6c6c6)
示例:
# 查找所有從 'nginx' 鏡像(任何標(biāo)簽)創(chuàng)建的容器 docker container ls -f "ancestor=nginx" # 查找所有從 'ubuntu:20.04' 這個(gè)特定鏡像創(chuàng)建的容器 docker container ls -a -f "ancestor=ubuntu:20.04" # 查找所有從某個(gè)特定鏡像ID創(chuàng)建的容器 docker container ls -a -f "ancestor=d123a6c6c6c6"
4. 按標(biāo)簽過(guò)濾:label
- 這是一個(gè)非常強(qiáng)大且在生產(chǎn)中常用的過(guò)濾器,用于篩選使用了自定義標(biāo)簽的容器。
- 作用:根據(jù)容器附帶的 label 來(lái)篩選。
- 背景:在運(yùn)行容器時(shí),可以使用 --label 或 -l 參數(shù)為容器添加自定義的鍵值對(duì),用于標(biāo)識(shí)其角色、環(huán)境等(例如 --label env=production)。
示例:
# 假設(shè)你運(yùn)行容器時(shí)這樣打標(biāo)簽: # docker run -d --label "env=prod" --label "team=backend" ... nginx # 查找所有帶有 `env=prod` 標(biāo)簽的容器 docker container ls -f "label=env=prod" # 查找所有帶有 `team` 這個(gè)標(biāo)簽鍵的容器,無(wú)論其值是什么 docker container ls -f "label=team"
3.1.3.命令替換——$(command)
什么是命令替換?
我們這里講的命令替換就是$(command)
它的作用就是:先執(zhí)行括號(hào)(或反引號(hào))中的命令,然后將這個(gè)命令的輸出結(jié)果替換到當(dāng)前位置。
舉個(gè)例子:
假設(shè)我們有一個(gè)命令 echo "Hello",它會(huì)輸出字符串 "Hello"。
如果我們這樣寫(xiě):
echo $(echo "Hello")
那么執(zhí)行步驟是:
先執(zhí)行 echo "Hello",得到輸出 "Hello"。
然后將 $(echo "Hello") 替換為 "Hello",所以整個(gè)命令變成了:
echo "Hello"
然后執(zhí)行這個(gè)命令,最后輸出 "Hello"。
看起來(lái)好像多此一舉,但實(shí)際上,命令替換的真正威力在于,它可以讓一個(gè)命令的輸出作為另一個(gè)命令的參數(shù)。
事實(shí)上,這個(gè)在在 Docker 中的實(shí)際應(yīng)用其實(shí)是非常廣泛的
示例一:停止所有正在運(yùn)行的容器
在 Docker 中,我們經(jīng)常需要處理多個(gè)容器。
比如,我們想停止所有正在運(yùn)行的容器。
沒(méi)有命令替換的做法:
- 先運(yùn)行 docker container ls 查看正在運(yùn)行的容器,記下它們的容器 ID。
- 然后運(yùn)行 docker container stop <容器ID1> <容器ID2> ...,手動(dòng)輸入所有容器 ID。
這樣做很麻煩,而且如果容器很多,很容易出錯(cuò)。
使用命令替換的做法:
docker container stop $(docker container ls -q)
我們來(lái)分解一下這個(gè)命令:
首先,Shell 會(huì)執(zhí)行 $(docker container ls -q) 中的命令 docker container ls -q。
docker container ls -q 會(huì)列出所有正在運(yùn)行的容器的 ID(-q 表示只顯示 ID)。
假設(shè)當(dāng)前運(yùn)行著三個(gè)容器,那么 docker container ls -q 的輸出可能是:
a1b2c3d4e5f6 x1y2z3u4v5w6 k9l8m7n6o5p4
然后,命令替換會(huì)發(fā)生,$(docker container ls -q) 會(huì)被替換為這三個(gè) ID,整個(gè)命令變成:
docker container stop a1b2c3d4e5f6 x1y2z3u4v5w6 k9l8m7n6o5p4
最后,Shell 執(zhí)行這個(gè)命令,停止這三個(gè)容器。
這樣,我們只需要一行命令就可以停止所有運(yùn)行中的容器,而不需要手動(dòng)輸入每個(gè)容器的 ID。
另一個(gè)例子:刪除所有已退出的容器
我們經(jīng)常需要清理已經(jīng)退出的容器。我們可以這樣寫(xiě):
docker container rm $(docker container ls -aq -f status=exited)
分解:
docker container ls -aq -f status=exited:
- -a:顯示所有容器(包括已退出的)
- -q:只顯示容器 ID
- -f status=exited:過(guò)濾出狀態(tài)為已退出的容器
假設(shè)這個(gè)命令輸出兩個(gè)已退出容器的 ID:
c1 c2
然后命令替換會(huì)發(fā)生,整個(gè)命令變成:
docker container rm c1 c2
命令替換的注意事項(xiàng)
當(dāng)然看了上面2個(gè)例子,我們應(yīng)該就能看懂下面這個(gè)了吧
# 停止所有運(yùn)行中的容器 docker container stop $(docker container ls -q) # 刪除所有已退出的容器 docker container rm $(docker container ls -aq -f status=exited) # 【危險(xiǎn)!】強(qiáng)制刪除所有容器 docker container rm -f $(docker container ls -aq)
不過(guò)呢,這個(gè)命令替換還是有很多值得注意的地方的
- 如果內(nèi)部命令輸出多行,命令替換默認(rèn)會(huì)將這些輸出合并為一個(gè)字符串,用空格分隔。所以上面的例子中,三個(gè)容器的 ID 被空格分開(kāi),然后作為參數(shù)傳遞給 docker container stop。
- 如果內(nèi)部命令沒(méi)有輸出,那么命令替換的結(jié)果是空,那么外部命令可能就會(huì)因?yàn)槿鄙賲?shù)而報(bào)錯(cuò)。例如,如果沒(méi)有運(yùn)行中的容器,那么 docker container stop $(docker container ls -q) 就會(huì)變成 docker container stop,而 stop 命令需要至少一個(gè)參數(shù),所以會(huì)報(bào)錯(cuò)。
- 命令替換中的命令如果執(zhí)行失敗,那么外部命令也會(huì)受到影響。
3.2.示例
話(huà)不多說(shuō),我們直接實(shí)戰(zhàn)一下

我們先看看它們的狀態(tài)

很好,都啟動(dòng)了,現(xiàn)在我們停止一個(gè)容器mynginx4

我們檢查一下它的狀態(tài)
root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 40aa5a938cb6 nginx:1.22.0 "/docker-entrypoint.…" 3 minutes ago Exited (0) 2 minutes ago mynginx4 613f84699414 nginx:1.22.0 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp mynginx3 f5477340fa83 nginx:1.22.0 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp mynginx2 6c43bc46b679 nginx:1.22.0 "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp mynginx1
現(xiàn)在我們就來(lái)測(cè)驗(yàn)一下
實(shí)際上,docker ps 是 docker container ls 的簡(jiǎn)寫(xiě)形式。在早期的 Docker 版本中,我們使用 docker ps 來(lái)列出容器。后來(lái),Docker 引入了更明確的命令結(jié)構(gòu),將命令按功能分組,例如 container、image、network 等。因此,docker container ls 是更現(xiàn)代、更推薦的寫(xiě)法,但 docker ps 仍然被廣泛支持和使用。
root@VM-16-14-ubuntu:~# docker ps -q 613f84699414 f5477340fa83 6c43bc46b679 root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 613f84699414 nginx:1.22.0 "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 80/tcp mynginx3 f5477340fa83 nginx:1.22.0 "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 80/tcp mynginx2 6c43bc46b679 nginx:1.22.0 "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 80/tcp mynginx1 root@VM-16-14-ubuntu:~# docker ps -q 613f84699414 f5477340fa83 6c43bc46b679 root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 40aa5a938cb6 nginx:1.22.0 "/docker-entrypoint.…" 16 minutes ago Exited (0) 15 minutes ago mynginx4 613f84699414 nginx:1.22.0 "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 80/tcp mynginx3 f5477340fa83 nginx:1.22.0 "/docker-entrypoint.…" 16 minutes ago Up 16 minutes 80/tcp mynginx2 6c43bc46b679 nginx:1.22.0 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes 80/tcp mynginx1 root@VM-16-14-ubuntu:~# docker ps -aq 40aa5a938cb6 613f84699414 f5477340fa83 6c43bc46b679
大家仔細(xì)比對(duì)??!
root@VM-16-14-ubuntu:~# docker ps -f status=running CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 613f84699414 nginx:1.22.0 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes 80/tcp mynginx3 f5477340fa83 nginx:1.22.0 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes 80/tcp mynginx2 6c43bc46b679 nginx:1.22.0 "/docker-entrypoint.…" 17 minutes ago Up 17 minutes 80/tcp mynginx1 root@VM-16-14-ubuntu:~# docker ps -f status=exited CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 40aa5a938cb6 nginx:1.22.0 "/docker-entrypoint.…" 17 minutes ago Exited (0) 16 minutes ago mynginx4 root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 40aa5a938cb6 nginx:1.22.0 "/docker-entrypoint.…" 18 minutes ago Exited (0) 16 minutes ago mynginx4 613f84699414 nginx:1.22.0 "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 80/tcp mynginx3 f5477340fa83 nginx:1.22.0 "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 80/tcp mynginx2 6c43bc46b679 nginx:1.22.0 "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 80/tcp mynginx1
怎么樣?還是不錯(cuò)的吧?。〗酉聛?lái)我們執(zhí)行下面這個(gè)命令
docker stop $(docker ps -q)

怎么樣?
docker start $(docker ps -aq -f status=exited)
![]()
現(xiàn)在是不是都啟動(dòng)了?
接下來(lái)我們就批量停止

現(xiàn)在我們?nèi)タ纯此鼈兊臓顟B(tài)
root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 40aa5a938cb6 nginx:1.22.0 "/docker-entrypoint.…" 2 hours ago Exited (0) 46 seconds ago mynginx4 613f84699414 nginx:1.22.0 "/docker-entrypoint.…" 2 hours ago Exited (0) 46 seconds ago mynginx3 f5477340fa83 nginx:1.22.0 "/docker-entrypoint.…" 2 hours ago Exited (0) 46 seconds ago mynginx2 6c43bc46b679 nginx:1.22.0 "/docker-entrypoint.…" 2 hours ago Exited (0) 46 seconds ago mynginx1
再把它們批量刪除
docker rm $(docker ps -aq -f status=exited)

怎么樣?懂了沒(méi)
四.容器交互模式
4.1.attached模式(前臺(tái)模式)
Attached 模式(前臺(tái)模式):在這個(gè)模式下,你的終端(命令行窗口)會(huì)變成容器主進(jìn)程的“控制臺(tái)”。你會(huì)在當(dāng)前終端里直接看到容器的輸出,并且可以直接向它發(fā)送輸入。簡(jiǎn)單說(shuō),你的終端和容器“粘”在了一起。
一個(gè)生動(dòng)的比喻
想象一下,你正在運(yùn)行一個(gè)程序,比如 python app.py:
- 在普通命令行里,你運(yùn)行它,所有的打印(print)信息都會(huì)顯示在當(dāng)前窗口,你可以通過(guò) Ctrl+C 來(lái)終止它。
- Attached 模式運(yùn)行容器,就相當(dāng)于你把容器內(nèi)部的這個(gè)主進(jìn)程(比如 python app.py)“嫁接”到了你的終端上。對(duì)你而言,感覺(jué)就像直接在宿主機(jī)上運(yùn)行那個(gè)進(jìn)程一樣。
1. 如何進(jìn)入 Attached 模式?
情況1:這是默認(rèn)的模式。
當(dāng)你使用 docker run 命令且沒(méi)有使用 -d(detach 分離)參數(shù),并且沒(méi)有使用-i,-t參數(shù)時(shí),你就會(huì)以 Attached 模式啟動(dòng)容器。
示例 :前臺(tái)運(yùn)行的應(yīng)用
# 運(yùn)行一個(gè)簡(jiǎn)單的 Python Web 應(yīng)用 docker run -p 5000:5000 my-python-app
這個(gè)應(yīng)用的日志(例如 “* Running on http://0.0.0.0:5000/”)會(huì)直接打印在你的終端上。
情況2:真正的附加模式
# 先啟動(dòng)一個(gè)長(zhǎng)期運(yùn)行的容器 docker run -d --name my-container ubuntu bash -c "while true; do echo 'tick'; sleep 1; done" # 然后附加到它 docker attach my-container
你可以看到實(shí)時(shí)輸出
在某些情況下可以發(fā)送輸入給主進(jìn)程
按
Ctrl+C會(huì)終止主進(jìn)程
2. Attached 模式的特點(diǎn)
實(shí)時(shí)輸出:容器主進(jìn)程(PID 1)的標(biāo)準(zhǔn)輸出(STDOUT)和標(biāo)準(zhǔn)錯(cuò)誤(STDERR)會(huì)直接顯示在你的終端上。這是查看日志最直接的方式。
直接交互:你可以通過(guò)鍵盤(pán)向容器的主進(jìn)程發(fā)送輸入(STDIN)。這對(duì)于交互式程序(如 shell)至關(guān)重要。
生命週期綁定:你的終端與容器的生命周期綁定在一起。
- 如果你在終端中按下 Ctrl+C,這個(gè)中斷信號(hào)會(huì)發(fā)送給容器的主進(jìn)程,通常會(huì)導(dǎo)致容器停止。
- 如果你關(guān)閉終端窗口,相當(dāng)于切斷了容器主進(jìn)程與控制端的連接,根據(jù)配置,這也可能導(dǎo)致容器停止。
3. 如何退出 Attached 模式而不停止容器?
這是一個(gè)非常常見(jiàn)的痛點(diǎn)。你進(jìn)入了容器的 bash,做了一些操作,然后想退出,但不希望容器停止。
方法:使用“分離序列”
默認(rèn)的分離序列是 Ctrl+P 然后緊接著 Ctrl+Q(先按住 Ctrl,然后按 P,松開(kāi),再按 Q)。
- 作用:這個(gè)操作會(huì)讓你自己從容器的終端中“抽離”出來(lái),返回到宿主機(jī)的命令行,而容器會(huì)在后臺(tái)繼續(xù)運(yùn)行。
- 注意:這和 Ctrl+C 有本質(zhì)區(qū)別!Ctrl+C 是終止進(jìn)程,而 Ctrl+P Ctrl+Q 是斷開(kāi)連接。
另一種方式:在啟動(dòng)時(shí)就用 Detached 模式
如果你本來(lái)就打算讓容器在后臺(tái)運(yùn)行,最好一開(kāi)始就使用:
docker run -d -it --name my_container ubuntu:latest /bin/bash
然后使用 docker attach 命令在需要時(shí)連接上去。
4. docker attach 命令
這個(gè)命令是專(zhuān)門(mén)用來(lái)將你的終端重新附著到一個(gè)已經(jīng)正在運(yùn)行的容器的 Attached 模式上。
# 首先,在后臺(tái)啟動(dòng)一個(gè)容器 docker run -d --name my_detached_container my-python-app # 然后,將你的終端附著到它上面 docker attach my_detached_container
執(zhí)行 docker attach 后,你就能看到那個(gè)容器的實(shí)時(shí)日志了,并且可以與之交互(如果它的主進(jìn)程接受輸入的話(huà))。
退出 docker attach:同樣,使用 Ctrl+P Ctrl+Q 可以安全分離,讓容器繼續(xù)運(yùn)行。使用 Ctrl+C 會(huì)向容器主進(jìn)程發(fā)送終止信號(hào)。
話(huà)不多說(shuō),我們直接看例子

現(xiàn)在我們?nèi)g覽器訪問(wèn)一下這個(gè)網(wǎng)頁(yè),我們回去看看

怎么樣?是不是打印出一條新的日志了?。。?/p>
我們每刷新一次,就會(huì)多打印出一條日志

現(xiàn)在我們往里面輸入任何字符都沒(méi)有反應(yīng)

這個(gè)時(shí)候我們ctrl+C看看

我們發(fā)現(xiàn)它退出了
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9d89ba23f141 nginx:1.22.0 "/docker-entrypoint.…" 3 minutes ago Exited (0) 32 seconds ago frosty_solomon
確實(shí)是如此。
4.2.detached 模式(后臺(tái)模式)
Detached模式,顧名思義,就是“分離”模式,也稱(chēng)為后臺(tái)模式。
在Detached模式下,容器會(huì)在后臺(tái)運(yùn)行,不會(huì)占用當(dāng)前的終端。
我們通過(guò)對(duì)比來(lái)深入理解。
如何以Detached模式啟動(dòng)容器?
使用-d或--detach選項(xiàng)。
示例:
docker run -d --name my_detached_container nginx
執(zhí)行這個(gè)命令后,終端會(huì)打印出容器的ID,然后立即返回,并顯示新的命令提示符。這意味著容器已經(jīng)在后臺(tái)啟動(dòng)了。
Detached模式的特點(diǎn)
終端立即返回:啟動(dòng)容器后,終端不會(huì)被占用,你可以繼續(xù)執(zhí)行其他命令。
看不到實(shí)時(shí)日志:容器內(nèi)進(jìn)程的輸出(標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤)不會(huì)顯示在當(dāng)前的終端上。
生命周期與終端無(wú)關(guān):即使你關(guān)閉了啟動(dòng)容器時(shí)所用的終端,容器也不會(huì)停止,它會(huì)繼續(xù)在后臺(tái)運(yùn)行。
如何與Detached模式的容器交互?
雖然容器在后臺(tái)運(yùn)行,但我們?nèi)匀挥卸喾N方式與之交互。
1. 查看日志:docker logs
docker logs my_detached_container
你可以通過(guò)docker logs命令來(lái)查看容器的輸出。如果加上-f(follow)選項(xiàng),可以像Attached模式一樣實(shí)時(shí)查看日志。
docker logs -f my_detached_container
2. 進(jìn)入容器執(zhí)行命令:docker exec
如果你想在容器內(nèi)執(zhí)行命令,可以使用docker exec。這對(duì)于調(diào)試、查看容器內(nèi)部狀態(tài)非常有用。
例如,進(jìn)入容器的shell(前提是容器內(nèi)有shell,比如bash):
docker exec -it my_detached_container /bin/bash
注意:docker exec命令中,-it選項(xiàng)表示交互式終端,這樣你才能與容器的shell交互。
執(zhí)行一個(gè)一次性命令(不需要進(jìn)入交互式shell):
docker exec my_detached_container ls /usr/share/nginx/html
3. 連接到容器的Attached模式:docker attach
你可以使用docker attach命令將終端重新附著到正在后臺(tái)運(yùn)行的容器上。
docker attach my_detached_container
但是要注意,一旦你使用docker attach,你就會(huì)進(jìn)入Attached模式,看到容器的輸出,并且可以發(fā)送輸入(如果容器主進(jìn)程接受輸入的話(huà))。同樣,要退出Attached模式而不停止容器,可以使用分離序列Ctrl+P Ctrl+Q。如果直接按Ctrl+C,則會(huì)停止容器。
注意:如果容器的主進(jìn)程是一個(gè)shell(比如/bin/bash),那么docker attach會(huì)連接到這個(gè)shell,但你可能會(huì)發(fā)現(xiàn)它沒(méi)有響應(yīng),因?yàn)閟hell可能正在等待輸入。所以,對(duì)于交互式容器,通常我們使用docker exec來(lái)進(jìn)入。
如何停止Detached模式的容器?
直接實(shí)用docker stop命令
docker stop my_detached_container
如何將已經(jīng)以Attached模式運(yùn)行的容器轉(zhuǎn)為Detached模式?
如果你已經(jīng)以Attached模式啟動(dòng)了一個(gè)容器,并且不想停止它,但又想收回終端的控制權(quán),你可以使用分離序列Ctrl+P Ctrl+Q來(lái)將容器轉(zhuǎn)為后臺(tái)運(yùn)行(即Detached模式)。
反之,如果你啟動(dòng)了一個(gè)Detached模式的容器,你可以用docker attach命令將終端附著上去,轉(zhuǎn)為Attached模式。
最佳實(shí)踐
- 長(zhǎng)期運(yùn)行的服務(wù)(如Web服務(wù)器、數(shù)據(jù)庫(kù)等)通常以Detached模式運(yùn)行,這樣它們不會(huì)占用終端,并且可以在后臺(tái)持續(xù)運(yùn)行。
- 調(diào)試和交互式任務(wù)(如構(gòu)建鏡像、運(yùn)行一次性腳本或調(diào)試容器內(nèi)部)通常使用Attached模式或docker exec命令。
注意點(diǎn)
- 以Detached模式啟動(dòng)的容器,其生命周期與啟動(dòng)它的終端無(wú)關(guān)。這意味著即使終端關(guān)閉,容器也會(huì)繼續(xù)運(yùn)行。
- 默認(rèn)情況下,容器內(nèi)的主進(jìn)程的日志輸出(標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤)會(huì)被Docker捕獲,你可以通過(guò)docker logs查看。但請(qǐng)注意,如果日志量很大,可能需要配置日志驅(qū)動(dòng)和日志輪轉(zhuǎn),以防止磁盤(pán)空間被占滿(mǎn)。
4.3.interactive模式(交互模式)
第一問(wèn):什么是“交互模式”?
想象一下,你買(mǎi)了一臺(tái)新的電腦(這就是一個(gè)容器),但它現(xiàn)在處于關(guān)機(jī)狀態(tài)。交互模式,就像是你按下了這臺(tái)電腦的開(kāi)機(jī)鍵,并且直接坐在了它的屏幕和鍵盤(pán)前面。
在 Docker 的世界里:
- 容器:就是一個(gè)輕量級(jí)的、隔離的軟件運(yùn)行環(huán)境(可以理解為那臺(tái)小電腦)。
- 交互模式:就是讓你能進(jìn)入這個(gè)容器內(nèi)部,像一個(gè)真正的用戶(hù)一樣,在里面輸入命令、執(zhí)行程序、查看結(jié)果。
- 核心思想: 把容器從一個(gè)“后臺(tái)靜默運(yùn)行的進(jìn)程”,變成一個(gè)“可以與之對(duì)話(huà)的臨時(shí)操作系統(tǒng)”。
第二問(wèn):為什么需要它?它解決什么問(wèn)題?
沒(méi)有交互模式會(huì)怎樣?我們來(lái)看一個(gè)常見(jiàn)的場(chǎng)景。
你想在一個(gè)干凈的 Ubuntu 容器里隨便看看,比如檢查一下 ls 命令。如果你直接運(yùn)行:
docker run ubuntu:latest ls
容器會(huì)執(zhí)行 ls 命令,把根目錄列表打印出來(lái),然后任務(wù)完成,容器立即退出。你就像讓一個(gè)機(jī)器人幫你拍一張房間的照片,它拍完照、把照片遞給你,然后就消失了。你并沒(méi)有“進(jìn)入”那個(gè)房間。
交互模式解決的問(wèn)題就是:
- 保持容器運(yùn)行:不讓它執(zhí)行完一個(gè)命令就退出。
- 提供一個(gè)人機(jī)交互的接口:讓你能向容器內(nèi)部發(fā)送命令,并看到它的輸出。
第三問(wèn):怎么啟動(dòng)交互模式?(核心命令)
啟動(dòng)交互模式,秘訣在于使用兩個(gè)關(guān)鍵的參數(shù):-i 和 -t。它們通常形影不離,寫(xiě)成 -it。
- -i 或 --interactive:保持標(biāo)準(zhǔn)輸入流打開(kāi)。簡(jiǎn)單說(shuō),就是允許你向容器里輸入命令。
- -t 或 --tty:分配一個(gè)偽終端。這相當(dāng)于為你的容器啟動(dòng)了一個(gè)“虛擬的屏幕和鍵盤(pán)”,讓你感覺(jué)就像在用一臺(tái)真實(shí)的電腦終端。
經(jīng)典命令如下:
docker run -it <鏡像名> <shell>
最常用的例子,啟動(dòng)一個(gè) Ubuntu 容器并進(jìn)入:
docker run -it ubuntu:latest /bin/bash
讓我們拆解一下這個(gè)命令:
- docker run:創(chuàng)建并啟動(dòng)一個(gè)新容器。
- -it:開(kāi)啟交互模式和偽終端。
- ubuntu:latest:使用的鏡像。
- /bin/bash:容器啟動(dòng)后要運(yùn)行的命令。這里我們運(yùn)行的是 Bash shell,它是一個(gè)強(qiáng)大的命令行解釋器,我們就是通過(guò)它來(lái)與容器交互的。
第四問(wèn):?jiǎn)?dòng)后會(huì)發(fā)生什么?
執(zhí)行上面的命令后,你的命令行提示符會(huì)立刻發(fā)生變化!它可能看起來(lái)像這樣:
root@a1b2c3d4e5f6:/#
這表示你已經(jīng)成功進(jìn)入了容器內(nèi)部!
- root:你現(xiàn)在是容器的 root 用戶(hù)(超級(jí)管理員)。
- @a1b2c3d4e5f6:@ 后面是你的容器 ID。
- :/#:/ 表示你當(dāng)前在容器的根目錄。
現(xiàn)在,你可以像使用一臺(tái)普通的 Ubuntu 系統(tǒng)一樣,執(zhí)行任何命令:
- ls - 查看當(dāng)前目錄文件
- pwd - 顯示當(dāng)前目錄
- cat /etc/os-release - 查看系統(tǒng)信息,確認(rèn)你確實(shí)在容器里
- apt update && apt install -y python3 - 甚至可以安裝軟件!
第五問(wèn):如何退出交互模式?
這里有兩個(gè)選項(xiàng),非常重要:
1.退出并停止容器:
- 在容器內(nèi)部的命令行中,直接輸入 exit 或者按 Ctrl + D。
- 效果:Bash shell 會(huì)結(jié)束,因?yàn)檫@個(gè) shell 是容器的主進(jìn)程,主進(jìn)程結(jié)束,容器也就隨之停止運(yùn)行了。這就像你把那臺(tái)小電腦的電源給關(guān)了。
2.只退出交互,但保持容器在后臺(tái)運(yùn)行:
- 按快捷鍵 Ctrl + P,然后 Ctrl + Q(先按 Ctrl+P,松開(kāi),再按 Ctrl+Q)。
- 效果:你會(huì)退回到你宿主機(jī)的命令行,但那個(gè)容器并沒(méi)有停止。你可以用 docker ps 命令看到它依然在運(yùn)行。這就像你從一臺(tái)虛擬機(jī)的屏幕上走開(kāi),但虛擬機(jī)本身還在后臺(tái)開(kāi)著。
- 之后如果你想再次進(jìn)入這個(gè)容器,可以使用:docker exec -it <容器名或ID> /bin/bash
五.容器與宿主機(jī)內(nèi)容復(fù)制

接下來(lái)我們啟動(dòng)一個(gè)容器
![]()
現(xiàn)在我們使用瀏覽器去訪問(wèn)一下這個(gè)界面

如果說(shuō)我們想要編輯這個(gè)頁(yè)面,我們就需要進(jìn)去看看


這個(gè)就是我們界面的代碼。我們?cè)囈幌履懿荒躹im它

可以看到這個(gè)鏡像里面沒(méi)有vim這個(gè)工具,所以我們可以先在宿主機(jī)里面寫(xiě)好了,再拷貝到這里來(lái)。

現(xiàn)在我們就把鏡像里面的那個(gè)index拷貝過(guò)來(lái)
docker cp mynginx1:/usr/share/nginx/html/index.html .

現(xiàn)在我們使用vim進(jìn)行修改一下

保存退出,我們?nèi)グ堰@個(gè)文件拷貝回那個(gè)容器里面
docker cp ./index.html mynginx1:/usr/share/nginx/html/index.html
![]()
現(xiàn)在我們回去容器進(jìn)行檢查


怎么樣?是不是拷貝成功了。
我們回去瀏覽器刷新一下

怎么樣?是不是就成功了。
容器和容器之間能不能進(jìn)行拷貝?
話(huà)不多說(shuō),我們先運(yùn)行一個(gè)新的容器
![]()
我們現(xiàn)在去瀏覽器看看

現(xiàn)在我們就把mynginx1的index.html文件拷貝給mynginx2
docker cp mynginx1:/usr/share/nginx/html/index.html mynginx2:/usr/share/nginx/html/index.html
我們一執(zhí)行,就發(fā)現(xiàn)報(bào)錯(cuò)了

不,這個(gè)命令是不正確的。Docker cp 命令不支持直接在兩個(gè)容器之間復(fù)制文件。
docker cp 命令的語(yǔ)法是:
- 從容器復(fù)制到主機(jī):docker cp <container>:<path> <host_path>
- 從主機(jī)復(fù)制到容器:docker cp <host_path> <container>:<path>
六.容器的自動(dòng)刪除
- --rm:此參數(shù)是一個(gè)自動(dòng)化清理選項(xiàng)。它指定當(dāng)容器退出時(shí),Docker 守護(hù)進(jìn)程將自動(dòng)刪除該容器。這主要用于臨時(shí)性的測(cè)試容器,以避免產(chǎn)生大量停止?fàn)顟B(tài)的容器,占用磁盤(pán)空間。
-it容器指定--rm選項(xiàng)
docker run -it --rm --name mywebsite1 -p 8081:80 nginx:1.22.0 bash

我們現(xiàn)在打開(kāi)另外一個(gè)終端看看
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d2355f475b16 nginx:1.22.0 "/docker-entrypoint.…" 28 seconds ago Up 28 seconds 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp mywebsite1
現(xiàn)在我們回到第一個(gè)終端,執(zhí)行exit

現(xiàn)在我們執(zhí)行docker ps -a

發(fā)現(xiàn)沒(méi)有一個(gè)容器了,這就是--rm在起作用。
-d容器指定--rm選項(xiàng)
![]()
現(xiàn)在我們?nèi)タ纯此臓顟B(tài)
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03ffd52873ff nginx:1.22.0 "/docker-entrypoint.…" 27 seconds ago Up 26 seconds 0.0.0.0:8082->80/tcp, [::]:8082->80/tcp mywebsite2
現(xiàn)在我們執(zhí)行下面這個(gè)命令
docker stop mywebsite2

現(xiàn)在我們?nèi)タ纯?/p>

容器沒(méi)有了,這就是--rm在起著作用。
所以:生產(chǎn)環(huán)境一定要小心使用--rm選項(xiàng)
七.容器的自動(dòng)重啟
--restart 參數(shù)是 Docker 容器的高可用性核心配置,它定義了當(dāng)容器退出后,Docker 守護(hù)進(jìn)程是否以及如何嘗試自動(dòng)重新啟動(dòng)它。
工作原理:Docker 守護(hù)進(jìn)程會(huì)監(jiān)控容器的退出狀態(tài)。一旦檢測(cè)到容器退出,它會(huì)根據(jù) --restart 策略來(lái)決定后續(xù)動(dòng)作。只有設(shè)置了此參數(shù)的容器,Docker 才會(huì)嘗試自動(dòng)重啟。
策略選項(xiàng):
重啟策略的類(lèi)別
no(默認(rèn)):
- 行為:容器退出后,Docker守護(hù)進(jìn)程不會(huì)嘗試重啟它。容器將保持在退出(Exited)狀態(tài)。
- 使用場(chǎng)景:適用于一次性任務(wù)或不需要自動(dòng)恢復(fù)的容器。
on-failure:
- 行為:只有在容器非正常退出時(shí)才會(huì)重啟。所謂“非正常退出”,是指容器的退出狀態(tài)碼(exit code)不為 0(在 Linux 中,0 通常表示成功)。
- 可以可選地指定最大重試次數(shù)(例如on-failure:5),當(dāng)重啟嘗試超過(guò)指定次數(shù)后,Docker將放棄重啟。
- 使用場(chǎng)景:適用于需要處理臨時(shí)性錯(cuò)誤(如依賴(lài)服務(wù)暫時(shí)不可用)的應(yīng)用,但希望永久性錯(cuò)誤(如應(yīng)用代碼bug)時(shí)不再重啟。
always:
- 行為:無(wú)論容器退出狀態(tài)如何(包括正常退出和非正常退出),Docker都會(huì)無(wú)限次地嘗試重啟容器。
- 但是,如果容器是被docker stop或docker rm命令停止或刪除的,則不會(huì)重啟。
- 注意:當(dāng)Docker守護(hù)進(jìn)程啟動(dòng)時(shí),如果容器設(shè)置為always,那么即使容器之前被停止(除非是手動(dòng)停止),它也會(huì)被啟動(dòng)。
- 實(shí)際上,在Docker守護(hù)進(jìn)程啟動(dòng)時(shí),對(duì)于always策略的容器,只要不是被用戶(hù)明確停止的(即通過(guò)docker stop停止的),都會(huì)被重啟。但是,注意always和unless-stopped的區(qū)別。
- 使用場(chǎng)景:適用于需要持續(xù)運(yùn)行的服務(wù),即使服務(wù)正常退出(例如完成了一個(gè)任務(wù),但需要立即再次運(yùn)行)也需要重啟的情況。但注意,如果容器正常退出,使用always會(huì)導(dǎo)致不斷重啟,可能并不適合所有場(chǎng)景。
unless-stopped:
- 行為:與always類(lèi)似,無(wú)論容器退出狀態(tài)如何(包括正常退出和非正常退出),Docker都會(huì)無(wú)限次地嘗試重啟容器。
- 但是有一個(gè)關(guān)鍵區(qū)別:如果容器是被手動(dòng)停止(即通過(guò)docker stop命令),那么即使Docker守護(hù)進(jìn)程重啟,該容器也不會(huì)被自動(dòng)啟動(dòng)。也就是說(shuō),unless-stopped尊重用戶(hù)手動(dòng)停止容器的操作,并記住這個(gè)狀態(tài)。
- 使用場(chǎng)景:適用于需要持續(xù)運(yùn)行的服務(wù),但同時(shí)允許用戶(hù)手動(dòng)停止容器并希望該狀態(tài)在Docker守護(hù)進(jìn)程重啟后得以保持。
例子:
docker run --restart no my-once-off-script 這兩條是等價(jià)的 docker run my-once-off-script # 只要因?yàn)殄e(cuò)誤退出就無(wú)限重啟 docker run --restart on-failure my-web-api # 最多嘗試重啟5次 docker run --restart on-failure:5 my-web-api
測(cè)試1——測(cè)試always
我們先啟動(dòng)一個(gè)容器
![]()
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 27fee1645e24 nginx:1.22.0 "/docker-entrypoint.…" 2 seconds ago Up 2 seconds 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp mywebsite1
我們可以看看重啟策略
docker container inspect mywebsite1

這給非常清楚了。
現(xiàn)在我們使用docker ps查看一下

現(xiàn)在我們?nèi)ネV惯@個(gè)容器

可以看到這個(gè)其實(shí)是退出碼是0的情況。
這個(gè)時(shí)候我們?cè)偃ナ褂胐ocker ps查看一下,發(fā)現(xiàn)它的狀態(tài)變化了

這就說(shuō)明它重啟過(guò)了。
接下來(lái)我們?cè)囈幌耫ocker stop能不能觸發(fā)重啟
![]()
我們使用docker ps -a看看

很明顯這個(gè)always不能重啟這個(gè)手動(dòng)停止的。
測(cè)試2——測(cè)試測(cè)試always和unless-stopped的相同點(diǎn)
首先我們先運(yùn)行兩個(gè)容器
docker run -d --name always-container --restart=always nginx:1.22.0 docker run -d --name unless-stopped-container --restart=unless-stopped nginx:1.22.0

接下來(lái)我們執(zhí)行下面這些命令

我們回去查看一下它們的狀態(tài)

發(fā)現(xiàn)了沒(méi),都自動(dòng)進(jìn)行重啟了。
現(xiàn)在我們將docker 守護(hù)進(jìn)程進(jìn)行重啟,看看它們是不是會(huì)自動(dòng)進(jìn)行重啟啊
重啟Docker守護(hù)進(jìn)程(注意:這會(huì)影響所有容器)
systemctl restart docker # 或者重啟Docker服務(wù) systemctl status docker

步驟4:檢查容器狀態(tài)
docker ps -a
我們看看
root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8e0cab99cdbf nginx:1.22.0 "/docker-entrypoint.…" 11 minutes ago Up 30 seconds 80/tcp unless-stopped-container 79857c3ef4d7 nginx:1.22.0 "/docker-entrypoint.…" 11 minutes ago Up 30 seconds 80/tcp always-container

都進(jìn)行重啟了啊??!
在 Docker 守護(hù)進(jìn)程重啟的場(chǎng)景下,能夠?qū)е氯萜髯詣?dòng)重新啟動(dòng)的策略包括:
- always - 總是重新啟動(dòng)
- unless-stopped - 只有非手動(dòng)停止的容器會(huì)重新啟動(dòng)
- 而 no 和 on-failure 策略在這種情況下不會(huì)觸發(fā)自動(dòng)重啟。
測(cè)試3——測(cè)試always和unless-stopped的區(qū)別(手動(dòng)停止)
步驟1:創(chuàng)建兩個(gè)容器,分別使用always和unless-stopped策略
docker run -d --name always-container --restart=always nginx:1.22.0 docker run -d --name unless-stopped-container --restart=unless-stopped nginx:1.22.0

步驟2:使用docker stop停止這兩個(gè)容器
docker stop always-container docker stop unless-stopped-container


我們使用docker ps -a查看一下

步驟3:重啟Docker守護(hù)進(jìn)程(注意:這會(huì)影響所有容器)
systemctl restart docker # 或者重啟Docker服務(wù) systemctl status docker

步驟4:檢查容器狀態(tài)
docker ps -a
我們看看
root@VM-16-14-ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8e0cab99cdbf nginx:1.22.0 "/docker-entrypoint.…" 2 minutes ago Exited (0) 2 minutes ago unless-stopped-container 79857c3ef4d7 nginx:1.22.0 "/docker-entrypoint.…" 2 minutes ago Up 46 seconds 80/tcp always-container
我們發(fā)現(xiàn),只有這個(gè)always策略的容器重啟了,而這個(gè)unless-stopped策略的居然沒(méi)有進(jìn)行重啟!
注意:實(shí)際上,在Docker守護(hù)進(jìn)程重啟后,它會(huì)檢查容器的重啟策略和當(dāng)前狀態(tài)。
- 對(duì)于always,它會(huì)重啟所有容器(即使之前是被docker stop停止的)。
- 而對(duì)于unless-stopped,他也會(huì)所有重啟容器,只不過(guò)它不會(huì)重啟那些被手動(dòng)停止的容器。
因此,如果你希望一個(gè)容器在Docker守護(hù)進(jìn)程重啟時(shí)總是被啟動(dòng),即使它之前被docker stop停止了,那么使用always。但通常情況下,我們更希望手動(dòng)停止的容器保持停止?fàn)顟B(tài),這時(shí)應(yīng)該使用unless-stopped。
另外,注意:如果容器是因?yàn)樗拗鳈C(jī)重啟而停止的(即Docker守護(hù)進(jìn)程隨著宿主機(jī)重啟而重啟),那么:
對(duì)于always和unless-stopped,容器都會(huì)在Docker守護(hù)進(jìn)程啟動(dòng)時(shí)被啟動(dòng),除非這個(gè)容器在宿主機(jī)重啟前已經(jīng)被手動(dòng)停止了(unless-stopped會(huì)記住手動(dòng)停止的狀態(tài),而always不會(huì))。
八.容器的環(huán)境變量設(shè)置
在 Docker 中,環(huán)境變量是向容器傳遞配置的一種常見(jiàn)方式。有兩種主要方法:使用 -e 或 --env 標(biāo)志直接設(shè)置變量,以及使用 --env-file 從文件加載多個(gè)變量。
方式一:使用多個(gè)-e選項(xiàng)來(lái)配置環(huán)境變量
我們先看看第一種設(shè)置多個(gè)環(huán)境變量的方式
docker run -it --rm -e MYTEST1=1 -e MYTEST2=2 -e MYTEST3=3 nginx:1.22.0 bash

方式二:通過(guò)配置文件來(lái)配置環(huán)境變量

現(xiàn)在我們?cè)谶@里創(chuàng)建一個(gè)配置文件
vim myenv

docker run -it --rm --env-file=./myenv nginx:1.22.0 bash
![]()
九.容器詳情查看
首先我們先運(yùn)行起來(lái)一個(gè)容器
docker run -d --name mynginx1 -p 8081:80 -e MYTEST=1 -h mynginx.com nginx:1.22.0
![]()
現(xiàn)在我們就去查看一下它的信息
docker container inspect mynginx1

可以說(shuō)是非常簡(jiǎn)單的?。?!
十.借助容器執(zhí)行某些特殊任務(wù)
我們可以直接借助docker的容器環(huán)境執(zhí)行一些命令,比如容器中有某個(gè)命令而宿主機(jī) 上沒(méi)有這個(gè)時(shí)候借助容器可以完成某些任務(wù)。

這個(gè)其實(shí)是容器的ip,我們看一下宿主機(jī)的ip


這個(gè)其實(shí)是非常常用的。
十一.容器的導(dǎo)入導(dǎo)出
首先我們先啟動(dòng)一個(gè)容器,
docker run -d --name mynginx1 -p 8081:80 nginx:1.22.0

我們現(xiàn)在去瀏覽器看看

接下來(lái)我們進(jìn)入容器內(nèi)部去修改一下主頁(yè)的內(nèi)容
docker exec -it mynginx1 bash

echo "I am from bit docker" > index.html

我們現(xiàn)在回去瀏覽器看看

這個(gè)還是很符合預(yù)期的。

現(xiàn)在我們就把上面這個(gè)容器打包成一個(gè).tar文件
docker export -o mynginx1.tar mynginx1

現(xiàn)在就完成導(dǎo)出了吧。
現(xiàn)在我們就把這個(gè).tar文件還原成一個(gè)鏡像
docker import mynginx1.tar mynginx1:v1.0

還是很不錯(cuò)的吧,現(xiàn)在我們就基于這個(gè)鏡像來(lái)啟動(dòng)一個(gè)新的容器。
docker run -d --name mynginx2 -p 8082:80 mynginx1:v1.0

我們發(fā)現(xiàn)報(bào)錯(cuò)了啊,這是是因?yàn)槲覀儗⑷萜鞅4鏋?tar文件時(shí),會(huì)丟失一些元數(shù)據(jù)
docker inspect mynginx1:v1.0

這個(gè)啟動(dòng)命令變成了null了。
我們可以看看我們最初的鏡像的啟動(dòng)命令是啥?
docker inspect nginx:1.22.0

其實(shí)不止這個(gè),還有很多別的屬性也都丟失了
可以看到啊,使用這個(gè).tar包的缺點(diǎn)就是會(huì)丟失一些元數(shù)據(jù)啊。
那么我們?cè)趺磫?dòng)這個(gè)容器呢?
docker run -d --name mynginx2 -p 8082:80 mynginx1:v1.0 nginx -g "daemon off;"

我們現(xiàn)在再去瀏覽器看看

怎么樣?是不是成功了。
十二.容器日志的查看
docker run -d --name mynginx1 -p 8081:80 nginx:1.22.0
![]()
接下來(lái)我們可以查看它的日志
docker logs mynginx1

可以看到,一運(yùn)行起來(lái)就退出了。不能實(shí)時(shí)更新,如果說(shuō)想要實(shí)時(shí)更新,就需要使用-f參數(shù)
docker logs -f mynginx1

我們?nèi)g覽器多刷新幾下

就會(huì)多打印出幾個(gè)這個(gè)

實(shí)時(shí)刷新。如果說(shuō)你覺(jué)得顯示的日志的數(shù)量太多了,那么我們就帶上-n選項(xiàng)來(lái)指定只顯示最新的幾條
docker logs -n 5 -f mynginx1

我們?nèi)g覽器刷新幾次

這個(gè)其實(shí)還是很簡(jiǎn)單的。
現(xiàn)在我們需要把這個(gè)日志放到一個(gè)文件里面,其實(shí)是有兩個(gè)做法的
- 重定向
- 使用docker官方內(nèi)部的日志
方法一:重定向
docker logs mynginx1 > info.log 2> err.log
這個(gè)會(huì)把標(biāo)準(zhǔn)輸出流輸出到info.log,把這個(gè)標(biāo)準(zhǔn)錯(cuò)誤流輸出到err.log



還是很不錯(cuò)的吧
方法二:使用docker官方的內(nèi)部記錄的日志
首先我們先執(zhí)行下面這個(gè)命令
docker info
找到下面這一行

這個(gè)/var/lib/docker就是docker的數(shù)據(jù)目錄

我們?nèi)ニ腸ontainers子目錄看看
root@VM-16-14-ubuntu:~# ls -l /var/lib/docker/containers total 4 drwx--x--- 4 root root 4096 Nov 2 14:56 793cc3851a6f322bb6274ab2454b5d2a0b3086a1f5d17e2ebe9354c354ccb464
![]()
可以看到這里有一個(gè)目錄啊,這個(gè)目錄怎么是一堆亂七八糟的數(shù)字啊,其實(shí)這個(gè)就是我們?nèi)萜鞯腎D
root@VM-16-14-ubuntu:~# docker ps --no-trunc CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 793cc3851a6f322bb6274ab2454b5d2a0b3086a1f5d17e2ebe9354c354ccb464 nginx:1.22.0 "/docker-entrypoint.sh nginx -g 'daemon off;'" 16 minutes ago Up 16 minutes 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp mynginx1
看到了吧,是不是完全對(duì)上了!

我們進(jìn)去看看
這里有這個(gè)793cc3851a6f322bb6274ab2454b5d2a0b3086a1f5d17e2ebe9354c354ccb464-json.log,這個(gè)就是docker內(nèi)部記錄的日志

如果說(shuō),我們需要這個(gè)日志,只需拷貝出去即可。
十三.容器資源的查看
話(huà)不多說(shuō),我們直接先運(yùn)行一個(gè)容器再說(shuō)
![]()

現(xiàn)在我們就來(lái)監(jiān)控整個(gè)容器的資源的使用
docker stats mynginx1

現(xiàn)在我們打開(kāi)瀏覽器,瘋狂刷新

可以看到這些資源都在上升??!
十四.綜合實(shí)戰(zhàn)一——Mysql容器安裝使用
首先我們需要先去docker hub官網(wǎng)尋找這個(gè)mysql的鏡像

點(diǎn)進(jìn)去看到

我們往下面翻,發(fā)現(xiàn)就有怎么使用它的方法

我們現(xiàn)在就來(lái),首先我們先拉取一下鏡像


現(xiàn)在我們就根據(jù)這個(gè)來(lái)啟動(dòng)鏡像
docker run --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 -p 8201:3306 -d mysql:8.0.42
![]()
我們看一下它的狀態(tài)
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 73b429ced4a3 mysql:8.0.42 "docker-entrypoint.s…" 59 seconds ago Up 59 seconds 33060/tcp, 0.0.0.0:8201->3306/tcp, [::]:8201->3306/tcp mysql1
很明顯,我們運(yùn)行起來(lái)了。
現(xiàn)在是運(yùn)行起來(lái)了,那么我們要是想要登錄這個(gè)mysql進(jìn)程該怎么做?
docker exec -it mysql1 bash

怎么樣?是不是就登錄進(jìn)來(lái)了。



我們發(fā)現(xiàn),使用起來(lái)完全沒(méi)有一點(diǎn)問(wèn)題。
就跟安裝在自己電腦上一樣。

我們退出來(lái)之后,這個(gè)進(jìn)程還在運(yùn)行
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 73b429ced4a3 mysql:8.0.42 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 33060/tcp, 0.0.0.0:8201->3306/tcp, [::]:8201->3306/tcp mysql1
還是很不錯(cuò)的吧。
我們可以嘗試一下跨主機(jī)訪問(wèn)這個(gè)mysql
mysql -h 主機(jī)ip -P 8201 -u root -p
我們使用windows上面的mysql來(lái)訪問(wèn)一下我們的mysql

我們發(fā)現(xiàn)這個(gè)遠(yuǎn)程登陸完全沒(méi)有任何問(wèn)題。
十五.綜合實(shí)戰(zhàn)二——Redis容器安裝使用
Redis是什么我不想多說(shuō)。我只想講解安裝使用
還是去docker hub官網(wǎng)先尋找到我們需要的鏡像


我們這里拉取redis 8.0

現(xiàn)在我們就來(lái)啟動(dòng)redis容器
docker run --name redis1 -p 8300:6379 -d redis:8.0

查看一下它的狀態(tài)
root@VM-16-14-ubuntu:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fb127d956fb6 redis:8.0 "docker-entrypoint.s…" 20 seconds ago Up 19 seconds 0.0.0.0:8300->6379/tcp, [::]:8300->6379/tcp redis1
很好,已經(jīng)運(yùn)行起來(lái)了。
接下來(lái)我們執(zhí)行下面這個(gè)
docker exec -it redis1 bash

很完美吧!!
接下來(lái)我們需要測(cè)試遠(yuǎn)程連接這個(gè)redis服務(wù)器
這個(gè)需要一個(gè)新的可視化工具:AnotherRedisDesktopManager 發(fā)行版 - Gitee.com




輸入IP地址和端口號(hào),然后點(diǎn)擊OK即可。
然后我們就會(huì)看到下面這個(gè)

可以看到右邊的1了嗎?那就是它的值。
我們現(xiàn)在回原來(lái)云服務(wù)器執(zhí)行下面這個(gè)

現(xiàn)在我們回去這個(gè)客戶(hù)端看看

看到了沒(méi),左邊就是鍵!!它也更新了,我們?nèi)タ纯?/p>


都對(duì)上了,遠(yuǎn)程登陸沒(méi)有問(wèn)題?。?!
十六.綜合實(shí)戰(zhàn)三——C++容器制作
首先我們需要拉取一個(gè)ububtu鏡像

現(xiàn)在我們就啟動(dòng)這個(gè)容器
docker run -it --name mycpp ubuntu:22.04 bash

啟動(dòng)之后,我們需要修改Ubuntu系統(tǒng)的軟件源配置文件
sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list apt update

現(xiàn)在我們就能安裝一些軟件了
apt install gcc vim g++ -y
我們這里先安裝gcc,g++,vim
mkdir src cd src vim main.cpp
我們?cè)趍ain.cpp里面寫(xiě)下面這個(gè)
#include<iostream>
using namespace std;
int main()
{
cout<<"hello docker"<<endl;
}我們進(jìn)行編譯一下
g++ -o test main.cpp

后續(xù)我們?cè)侔堰@個(gè)容器打包成一個(gè)鏡像,再進(jìn)行一些簡(jiǎn)單的操作,就能把這個(gè)做成鏡像發(fā)布出去了。只不過(guò)我們?cè)谶@里不能好好講講,我們后續(xù)會(huì)專(zhuān)門(mén)寫(xiě)幾篇文章來(lái)詳細(xì)講解如何制作鏡像的。
總結(jié)
到此這篇關(guān)于Docker容器操作和大量實(shí)用案例的文章就介紹到這了,更多相關(guān)Docker容器操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過(guò)Docker為本地DeepSeek-r1部署WebUI界面的完整教程
本文詳細(xì)介紹了如何通過(guò)Docker安裝并配置OpenWebUI,一個(gè)功能豐富的自托管Web用戶(hù)界面,用于與大型語(yǔ)言模型交互,文章步驟包括安裝Docker、配置WSL2、使用dockerrun命令部署OpenWebUI,并提供了詳細(xì)的命令解釋和部署結(jié)果,需要的朋友可以參考下2025-02-02
遷移docker數(shù)據(jù)目錄,釋放硬盤(pán)數(shù)據(jù)過(guò)程
這篇文章主要介紹了遷移docker數(shù)據(jù)目錄,釋放硬盤(pán)數(shù)據(jù)過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2026-05-05
docker安裝tomcat8的實(shí)現(xiàn)方法
這篇文章主要介紹了docker安裝tomcat8的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Docker安裝Minio+SpringBoot上傳下載文件方式
本文主要介紹了如何通過(guò)Docker安裝Minio并進(jìn)行訪問(wèn)測(cè)試,同時(shí)也講解了如何在SpringBoot中上傳文件到Minio,內(nèi)容包含了pom文件引入依賴(lài),application.properties配置,Minio配置,MinioClinet,FileService,FileServiceImpl的配置2024-10-10
如何利用Docker部署一個(gè)簡(jiǎn)單的springboot項(xiàng)目
這篇文章主要介紹了如何利用Docker部署一個(gè)簡(jiǎn)單的springboot項(xiàng)目,本文通過(guò)實(shí)例圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02
docker-compose啟動(dòng)mysql雙機(jī)熱備互為主從的方法實(shí)現(xiàn)
本文主要介紹了docker-compose啟動(dòng)mysql雙機(jī)熱備互為主從的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
MongoDB從入門(mén)到實(shí)戰(zhàn)之Docker快速安裝MongoDB的詳細(xì)過(guò)程
這篇文章主要介紹了MongoDB從入門(mén)到實(shí)戰(zhàn)之Docker快速安裝MongoDB的詳細(xì)過(guò)程,本文給大家分享詳細(xì)實(shí)戰(zhàn)教程,幫助大家快速把MongoDB環(huán)境搭建起來(lái),感興趣的朋友一起看看吧2025-05-05

