![]()
2862字。這是過去五年Docker官方文檔被開發者翻爛的次數均值——但90%的人只用過其中3條命令。
容器技術普及的第十年,「docker run」已經成為程序員肌肉記憶的一部分。但當你凌晨三點被報警短信炸醒,發現生產環境磁盤寫滿、容器僵尸進程堆積成山時,才會意識到:那些真正救命的命令,從來沒人系統教過你。
01 | 從「工廠」到「汽車」:鏡像與容器的生死循環
Docker的核心隱喻其實就兩層。鏡像(Image)是工廠藍圖,容器(Container)是跑在路上的汽車。大多數開發者卡在第一步:藍圖造好了,車卻拋錨在半路上。
docker build 是造工廠的過程。你把代碼和Dockerfile扔進去,出來一個可移植的鏡像包。但這里有個反直覺的坑——每次build都會生成新鏡像層,舊的不會自動消失。我見過一個團隊的CI服務器攢了200GB的懸空鏡像,直到構建任務全部失敗才察覺。
docker run -d 是點火啟動。那個-d參數(Detached模式)是后臺運行的開關,沒有它,你的終端會被容器進程綁架。關掉窗口等于拔鑰匙,應用直接熄火。加了-d,容器變成 silent ninja——存在感為零,直到你主動檢查。
但「跑起來」只是開始。生產環境的殘酷在于:容器活著,不代表業務健康。
02 | 診斷三板斧:ps、exec、logs 的實戰陷阱
docker ps 是狀態儀表盤。默認只顯示運行中的容器,加上-a才能看見那些 crash 后橫尸街頭的。端口映射信息在這里一目了然——但新手常犯的錯誤是,看到「Up 3 days」就以為萬事大吉。容器進程活著,內部服務可能早已僵死。
這時候需要 docker exec -it [容器ID] /bin/bash 。exec是execute的縮寫,-it組合讓交互成為可能。你可以鉆進去查配置文件、手動跑數據庫遷移、用curl測試內部端口。這個命令的隱藏成本是:每次exec都會在容器內啟動一個新進程,暴力排查時可能把容器內存撐爆。
![]()
docker logs 是第一道防線,也是最后一道。它抓取容器的標準輸出(STDOUT),但默認行為是輸出全部歷史日志——一個跑了一年的數據庫容器,日志量可能讓終端直接卡死。生產環境務必配合 --tail 或 --since 參數使用,否則等于用消防水龍給自己洗臉。
這三個命令的組合拳,能解決80%的線上問題。但剩下的20%,往往藏在「優雅」與「暴力」的邊界上。
03 | 清理的藝術:stop、rm、rmi 與核選項
docker stop 是給容器發SIGTERM信號——「下班了,收拾東西回家」。容器內的進程有10秒(默認)時間優雅關閉。但某些應用對信號處理不完善,stop后會變成僵尸狀態,占用端口和卷掛載點。
這時候 docker rm 登場。它刪除容器實例,釋放磁盤空間。但rm有個反人類設計:運行中的容器不能直接rm,必須先stop或加-f強制刪除。我見過腳本里連環調用「docker stop && docker rm」,其實可以合并成「docker rm -f」——但后者等于拔電源,數據丟失風險自負。
docker rmi 針對的是鏡像層。容器是汽車,鏡像是藍圖,rmi是銷毀設計圖紙。但圖紙被銷毀前,所有基于它的汽車必須先報廢(rm)。依賴關系鏈可能很深:一個基礎鏡像被十個業務鏡像引用,rmi時會報錯「image is being used by stopped container」——那些你以為已經清理掉的容器尸體,其實還在占坑。
最后這條命令,是Docker官方文檔里語氣最克制、但開發者口碑最分裂的:
docker system prune -a
核選項。??
它會刪除所有停止的容器、所有未被使用的網絡、所有懸空鏡像、所有構建緩存。加-a后,連那些「被標簽引用但無容器運行」的鏡像也一并清除。我的MacBook曾因Docker磁盤占用膨脹到120GB,這條命令瞬間釋放90GB——代價是下次構建要重新拉取全部基礎鏡像,CI流水線原地爆炸20分鐘。
![]()
沒有銀彈。prune的暴力美學在于:它強迫你做選擇題,要么接受構建延遲,要么忍受磁盤慢性自殺。
04 | 單容器之后:Compose與網絡拓撲的暗戰
掌握這9條命令,你算是畢業了——從幼兒園畢業。真實世界的微服務架構里,5個容器起步、50個不稀奇。手動docker run每一條?那是原始人鉆木取火。
Docker Compose的出現,本質是「把命令行參數寫成YAML配置文件」。但別被「簡化」的表象欺騙:compose up背后隱藏的網絡拓撲、服務發現、卷共享機制,復雜度指數級上升。單容器時代你只需關心端口映射,多容器時代要處理DNS解析、橋接網絡、overlay網絡的性能損耗。
一個典型陷阱:compose默認創建bridge網絡,容器間通過服務名互訪。但服務名解析依賴Docker內置的DNS服務器,某些基礎鏡像(比如Alpine Linux)的DNS客戶端有bug,會導致「間歇性連接失敗」——時靈時不靈,調試時想砸鍵盤。
另一個隱蔽成本:compose down默認刪除容器和網絡,但不刪除卷(volume)。數據庫容器反復重建,數據卷卻像幽靈一樣累積。某次客戶環境的根目錄寫滿,排查發現是三年未清理的MySQL卷,單個卷文件膨脹到800GB。
單容器命令是生存技能,Compose是協作協議。兩者之間的鴻溝,需要你在生產環境里摔過幾次跤才能填平。
05 | 命令之外的真相:Docker不是銀彈
回到開頭那個數字:2862。這是Docker文檔被翻閱的均值,也是開發者平均花在「排查環境問題」上的小時數——每年。
容器技術的承諾是「一次構建,到處運行」,但隱藏條款是「只要內核版本兼容、只要cgroups配置一致、只要鏡像架構匹配」。ARM與x86的鏡像不互通,Windows容器和Linux容器是平行宇宙,生產環境的Kubernetes集群和你筆記本上的Docker Desktop,行為差異可能比人和猩猩還大。
那些「救急命令」的真正價值,不在于記住語法,而在于建立直覺:當系統異常時,快速定位是「容器層」還是「應用層」的問題。docker ps看出生入死,docker logs聽臨終遺言,docker exec做解剖驗尸——這套工作流,和十年前SSH進物理機排查并無本質不同。
技術迭代的幻覺在于,我們總以為新工具解決了舊問題。但Docker的9條生存命令,最終指向一個古老共識:生產環境的穩定性,不靠魔法,靠對底層機制的敬畏。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.