)
1. 從“Hello, World!”到容器化思維為什么Docker是你的第一站如果你剛開始接觸軟件開發(fā)、運維或者只是單純地對“云原生”、“微服務(wù)”這些聽起來很酷的詞感到好奇那么Docker幾乎是你繞不開的起點。很多人把Docker的第一個“Hello, World!”程序看作一個簡單的入門儀式就像學(xué)編程時在屏幕上打印出第一行字。但在我看來這個簡單的操作背后隱藏著理解現(xiàn)代軟件開發(fā)和部署范式的鑰匙。它不僅僅是一個命令更是一次思維模式的切換——從“在我的機器上能跑”到“在任何地方都能以相同的方式跑”。為什么是Docker想象一下你開發(fā)了一個基于Python Flask的Web應(yīng)用本地測試一切正常。當(dāng)你興沖沖地把代碼和一份requirements.txt文件交給運維同事或者部署到云服務(wù)器上時卻可能遭遇一連串的“玄學(xué)”問題服務(wù)器上的Python版本是3.6而你的代碼需要3.9某個底層C庫的版本不匹配甚至操作系統(tǒng)比如CentOS和Ubuntu的細微差異都可能導(dǎo)致應(yīng)用行為異常。這就是經(jīng)典的“開發(fā)環(huán)境-測試環(huán)境-生產(chǎn)環(huán)境”不一致的困境。Docker通過容器技術(shù)將應(yīng)用及其所有依賴代碼、運行時、系統(tǒng)工具、系統(tǒng)庫、設(shè)置打包成一個標(biāo)準(zhǔn)化的、輕量級的、可移植的“鏡像”。這個鏡像在任何安裝了Docker引擎的機器上都能以完全一致的方式運行起來徹底解決了“環(huán)境依賴”這個老大難問題。所以運行第一個Docker的“Hello, World!”其意義遠大于屏幕上輸出一行文字。它是在驗證你的Docker環(huán)境是否就緒是在體驗“一次構(gòu)建處處運行”的魔力更是為你后續(xù)構(gòu)建、分享和部署更復(fù)雜的應(yīng)用打下堅實的基礎(chǔ)。無論你是前端、后端、數(shù)據(jù)科學(xué)家還是運維工程師掌握Docker都意味著你擁有了讓應(yīng)用交付變得更可靠、更高效的核心能力。接下來我們就從零開始完成這個儀式并深入理解那些讓你真正駕馭Docker的常用命令。2. 環(huán)境準(zhǔn)備不僅僅是安裝一個軟件在興奮地敲下第一個docker run命令之前我們必須確保戰(zhàn)場——也就是你的計算機環(huán)境——已經(jīng)準(zhǔn)備妥當(dāng)。Docker的安裝過程因操作系統(tǒng)而異并且會涉及到一些底層系統(tǒng)特性的檢查這也是很多新手遇到的第一個“攔路虎”。我們分別看看在主流操作系統(tǒng)上的準(zhǔn)備要點。2.1 Windows與macOS擁抱Docker Desktop對于Windows和macOS用戶官方推薦且最便捷的方式是安裝Docker Desktop。它是一個集成了Docker引擎、Docker CLI客戶端、Docker Compose、Kubernetes等工具的一體化桌面應(yīng)用。Windows用戶特別注意這是最容易出問題的環(huán)節(jié)。Docker依賴于操作系統(tǒng)的虛擬化技術(shù)Hyper-V或WSL 2后端。安裝時Docker Desktop會嘗試自動啟用這些功能但有時會失敗并彈出經(jīng)典的錯誤提示“Docker Desktop failed to start because virtualisation support wasn’t detected”。這個錯誤的根源通常有兩個BIOS/UEFI中的虛擬化未開啟這是硬件層面的支持。你需要重啟電腦進入BIOS/UEFI設(shè)置通常在開機時按F2、Del、F10等鍵找到類似“Intel Virtualization Technology (VT-x)”或“AMD-V”的選項將其設(shè)置為“Enabled”。Windows功能中的“Hyper-V”或“Windows Subsystem for Linux”未啟用這是操作系統(tǒng)層面的支持。即使BIOS開啟了虛擬化Windows也可能默認關(guān)閉相關(guān)功能。你需要打開“控制面板 - 程序和功能 - 啟用或關(guān)閉Windows功能”確保“Hyper-V”和“適用于Linux的Windows子系統(tǒng)”被勾選如果使用WSL 2后端。啟用后需要重啟。提示對于Windows 10家庭版它不支持Hyper-V。此時Docker Desktop會默認使用WSL 2后端。你必須先安裝WSL 2包括一個Linux發(fā)行版如Ubuntu并在Docker Desktop設(shè)置中指定使用WSL 2。macOS用戶過程相對簡單。確保你的macOS版本符合要求通常是較新的版本直接從Docker官網(wǎng)下載.dmg文件安裝即可。對于基于Apple SiliconM1/M2等的MacDocker Desktop提供了原生ARM版本性能很好。安裝成功后啟動Docker Desktop你會在系統(tǒng)托盤Windows或菜單欄macOS看到Docker的鯨魚圖標(biāo)。等待其狀態(tài)變?yōu)椤癉ocker Desktop is running”就表示環(huán)境就緒了。2.2 Linux原生的高效體驗Linux是Docker的“老家”安裝方式多樣且直接。不同的發(fā)行版有不同的包管理工具。Ubuntu/Debian通常使用APT倉庫安裝。# 1. 更新軟件包索引并安裝依賴 sudo apt-get update sudo apt-get install ca-certificates curl gnupg # 2. 添加Docker官方GPG密鑰和倉庫 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 3. 安裝Docker引擎 sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 4. 驗證安裝 sudo docker run hello-worldCentOS/RHEL使用YUM倉庫。# 1. 安裝yum工具集 sudo yum install -y yum-utils # 2. 添加Docker倉庫 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 3. 安裝Docker引擎 sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 4. 啟動Docker服務(wù)并設(shè)置開機自啟 sudo systemctl start docker sudo systemctl enable docker # 5. 驗證安裝 sudo docker run hello-world一個關(guān)鍵步驟將用戶加入docker組Linux默認情況下在Linux上運行Docker命令需要sudo權(quán)限。為了避免每次輸入sudo你可以將當(dāng)前用戶加入docker用戶組sudo usermod -aG docker $USER執(zhí)行此命令后必須完全注銷并重新登錄或者重啟終端用戶組變更才會生效。之后你就可以直接運行docker命令了。2.3 安裝后的重要配置鏡像加速由于Docker Hub默認的公共鏡像倉庫位于海外國內(nèi)直接拉取鏡像速度可能很慢甚至失敗。配置一個國內(nèi)的鏡像加速器是提升體驗的關(guān)鍵一步。Docker Desktop (Windows/macOS)在設(shè)置Settings中找到“Docker Engine”編輯其中的JSON配置添加鏡像加速器地址。例如使用阿里云加速器需要先登錄阿里云容器鏡像服務(wù)獲取專屬地址{ registry-mirrors: [https://your-mirror.mirror.aliyuncs.com] }Linux編輯/etc/docker/daemon.json文件如果不存在則創(chuàng)建{ registry-mirrors: [https://your-mirror.mirror.aliyuncs.com] }然后重啟Docker服務(wù)sudo systemctl restart docker完成以上所有步驟后你的Docker戰(zhàn)場才算真正準(zhǔn)備完畢。打開終端或命令提示符/PowerShell輸入docker version如果能看到Client和Server的版本信息恭喜你可以開始真正的旅程了。3. 神圣的“Hello, World!”深入理解docker run現(xiàn)在讓我們執(zhí)行那個具有里程碑意義的命令docker run hello-world如果你的網(wǎng)絡(luò)和配置都正確終端會滾動輸出一段歡迎文字。這個過程看似簡單背后卻是一系列精密的操作。讓我們拆解docker run hello-world到底做了什么解析鏡像名Docker CLI接收到hello-world這個鏡像名。由于沒有指定倉庫地址它默認去Docker Hubdocker.io的官方倉庫查找。檢查本地鏡像Docker引擎首先檢查本地是否存在名為hello-world:latest的鏡像未指定標(biāo)簽時默認為latest。拉取鏡像因為本地沒有引擎會從配置的鏡像倉庫默認是Docker Hub拉取hello-world:latest鏡像。你會看到Unable to find image hello-world:latest locally和latest: Pulling from library/hello-world的輸出。創(chuàng)建容器鏡像拉取到本地后Docker引擎會基于這個鏡像創(chuàng)建一個新的、可寫的容器層。容器是鏡像的運行實例。運行默認命令hello-world鏡像的Dockerfile中指定了一個默認命令通常是/hello。Docker引擎在容器內(nèi)部執(zhí)行這個命令。輸出并退出該命令執(zhí)行的結(jié)果就是打印出那段歡迎信息到你的終端。命令執(zhí)行完畢后容器進程終止容器進入“Exited”狀態(tài)。關(guān)鍵概念辨析鏡像 vs. 容器這是Docker中最核心的一對概念必須理解透徹。鏡像Image一個只讀的模板。它包含了運行應(yīng)用所需的文件系統(tǒng)、依賴和配置。你可以把它理解為一個軟件的“安裝包”或“藍圖”。hello-world就是一個非常小的鏡像。容器Container鏡像的一個運行實例。當(dāng)你執(zhí)行docker run時就是從鏡像創(chuàng)建了一個容器。容器是動態(tài)的、有生命周期的創(chuàng)建、運行、停止、刪除。容器在鏡像的只讀層之上添加了一個可寫的“容器層”所有運行時的修改都發(fā)生在這個層不會影響底層的鏡像。一個鏡像可以創(chuàng)建出多個相互獨立的容器。所以docker run實際上是一個復(fù)合命令它包含了docker pull如果本地沒有鏡像、docker create創(chuàng)建容器和docker start啟動容器等多個步驟。理解了這一點我們再來看一個更接近真實場景的例子docker run -d -p 8080:80 --name my-nginx nginx-d讓容器在后臺運行detached mode。-p 8080:80進行端口映射。將宿主機的8080端口映射到容器的80端口。這樣你訪問http://localhost:8080就能看到容器內(nèi)Nginx的服務(wù)。--name my-nginx給容器起一個名字方便后續(xù)管理。如果不指定Docker會隨機生成一個名字。nginx要運行的鏡像名這里拉取并運行官方的Nginx鏡像。執(zhí)行后你可以用docker ps看到這個正在運行的容器用瀏覽器訪問localhost:8080就能看到Nginx的歡迎頁。這比hello-world更直觀地展示了Docker如何運行一個真實的服務(wù)。4. 鏡像管理獲取、查看與清理鏡像是容器世界的基石。管理好鏡像是高效使用Docker的前提。4.1 拉取鏡像docker pull雖然docker run會自動拉取不存在的鏡像但顯式使用docker pull可以讓你更靈活地控制拉取過程例如只拉取不運行或者拉取特定標(biāo)簽的鏡像。# 拉取最新標(biāo)簽的Ubuntu鏡像 docker pull ubuntu # 拉取指定標(biāo)簽的鏡像例如Ubuntu 20.04 docker pull ubuntu:20.04 # 從特定倉庫拉取鏡像非Docker Hub docker pull registry.example.com/myapp:v1.0關(guān)于鏡像標(biāo)簽Tag標(biāo)簽通常用于標(biāo)識鏡像的不同版本。latest是一個特殊的、移動的標(biāo)簽通常指向該倉庫的最新穩(wěn)定版。在生產(chǎn)環(huán)境中強烈建議使用明確的版本標(biāo)簽如nginx:1.25-alpine而不是latest以確保環(huán)境的一致性。4.2 查看本地鏡像docker images或docker image ls這個命令列出所有本地存儲的鏡像。docker images # 或者 docker image ls # 輸出示例 # REPOSITORY TAG IMAGE ID CREATED SIZE # nginx latest 2b7d6430f78d 2 weeks ago 142MB # ubuntu 20.04 ba6acccedd29 2 months ago 72.8MB # hello-world latest d2c94e258dcb 9 months ago 13.3kB你可以看到鏡像的倉庫名、標(biāo)簽、唯一的鏡像ID、創(chuàng)建時間和大小。鏡像ID是鏡像的唯一標(biāo)識在很多命令中可以只用其前幾位能唯一區(qū)分即可來指代鏡像。4.3 刪除鏡像docker rmi或docker image rm當(dāng)鏡像不再需要時可以刪除以釋放磁盤空間。# 通過鏡像名刪除 docker rmi hello-world # 通過鏡像ID刪除取前幾位即可 docker rmi d2c94e # 強制刪除即使有容器基于此鏡像慎用 docker rmi -f ubuntu:20.04 # 刪除所有未被使用的鏡像懸空鏡像dangling images docker image prune重要提示如果鏡像有正在運行的容器或者有其它鏡像依賴它作為父鏡像則無法直接刪除。你需要先停止并刪除相關(guān)容器。docker image prune是一個清理利器可以安全地刪除那些沒有標(biāo)簽且沒有被任何容器引用的中間鏡像它們通常是在構(gòu)建新鏡像過程中產(chǎn)生的。4.4 搜索鏡像docker search如果你想在Docker Hub上尋找某個軟件的鏡像可以使用此命令。docker search nginx不過更常見的做法是直接去Docker Hub網(wǎng)站hub.docker.com進行搜索因為網(wǎng)站提供了更詳細的描述、標(biāo)簽列表、使用統(tǒng)計和Dockerfile鏈接。5. 容器生命周期管理從創(chuàng)建到銷毀容器是有狀態(tài)的、有生命周期的對象。掌握其生命周期的管理命令是日常工作的核心。5.1 查看容器docker ps這是使用頻率最高的命令之一用于列出容器。# 查看正在運行的容器 docker ps # 查看所有容器包括已停止的 docker ps -a # 查看最近創(chuàng)建的容器 docker ps -l # 以簡潔格式只顯示容器ID docker ps -q-a參數(shù)至關(guān)重要因為很多問題排查需要查看已經(jīng)停止的容器。5.2 停止與啟動容器docker stopdocker start# 停止一個運行中的容器發(fā)送SIGTERM信號允許優(yōu)雅退出 docker stop my-nginx # 強制停止一個容器發(fā)送SIGKILL信號立即終止 docker kill my-nginx # 啟動一個已停止的容器 docker start my-nginx # 重啟容器先stop再start docker restart my-nginxstop和kill的區(qū)別在于信號的溫和程度。stop是首選它給容器內(nèi)進程時間進行清理工作kill則用于容器無響應(yīng)時。5.3 進入容器內(nèi)部docker exec這是調(diào)試和排查問題的神器。它可以在一個正在運行的容器內(nèi)部啟動一個新的進程通常是啟動一個shell。# 以交互模式進入容器并啟動一個bash shell docker exec -it my-nginx /bin/bash # 在容器內(nèi)執(zhí)行一個一次性命令例如查看進程 docker exec my-nginx ps aux-i保持標(biāo)準(zhǔn)輸入STDIN打開允許你與命令交互。-t分配一個偽終端pseudo-TTY讓shell看起來像是在本地終端一樣。-it通常組合使用用于交互式會話。注意docker exec和早期另一個命令docker attach不同。attach是連接到容器的主進程PID 1如果主進程是一個Web服務(wù)器你attach進去看到的是它的日志輸出而不是一個shell。而exec是新建一個進程更為常用和安全。5.4 查看容器日志docker logs容器內(nèi)應(yīng)用輸出的標(biāo)準(zhǔn)輸出STDOUT和標(biāo)準(zhǔn)錯誤STDERR會被Docker引擎捕獲成為容器的日志。# 查看容器日志 docker logs my-nginx # 實時跟蹤日志輸出類似 tail -f docker logs -f my-nginx # 查看最近10行日志 docker logs --tail 10 my-nginx # 查看某個時間點之后的日志 docker logs --since 2024-01-01T00:00:00 my-nginx當(dāng)你的容器內(nèi)應(yīng)用沒有按預(yù)期工作時第一時間查看日志是定位問題的標(biāo)準(zhǔn)操作流程。5.5 刪除容器docker rm容器停止后其文件系統(tǒng)可寫層仍然占用磁盤空間需要手動刪除。# 刪除一個已停止的容器 docker rm my-nginx # 強制刪除一個容器即使正在運行 docker rm -f my-nginx # 刪除所有已停止的容器清理空間常用 docker container prune和鏡像一樣prune命令是清理的好幫手。docker container prune會交互式地詢問你是否刪除所有已停止的容器。5.6 容器與宿主機的文件交換docker cp有時你需要將宿主機的文件復(fù)制到容器內(nèi)或者將容器內(nèi)的文件復(fù)制到宿主機進行分析。# 將宿主機文件復(fù)制到容器內(nèi) docker cp /path/on/host/file.txt my-nginx:/path/in/container/ # 將容器內(nèi)文件復(fù)制到宿主機 docker cp my-nginx:/var/log/nginx/error.log /path/on/host/這是一個非常實用的調(diào)試和備份工具。6. 構(gòu)建自定義鏡像理解Dockerfile運行現(xiàn)成的鏡像只是開始真正的威力在于構(gòu)建屬于自己的鏡像。這通過一個名為Dockerfile的文本文件來實現(xiàn)。Dockerfile包含了一系列指令描述了如何一步步組裝出一個鏡像。讓我們創(chuàng)建一個最簡單的自定義鏡像。新建一個目錄在里面創(chuàng)建兩個文件1. 編寫應(yīng)用文件app.py#!/usr/bin/env python3 from flask import Flask app Flask(__name__) app.route(/) def hello(): return Hello, Dockerized World!\n if __name__ __main__: app.run(host0.0.0.0, port5000)這是一個簡單的Python Flask應(yīng)用。2. 編寫依賴文件requirements.txtFlask2.3.33. 編寫Dockerfile# 第一階段使用官方Python輕量級鏡像作為構(gòu)建環(huán)境 FROM python:3.9-slim AS builder # 設(shè)置工作目錄 WORKDIR /app # 將依賴文件復(fù)制到工作目錄 COPY requirements.txt . # 安裝依賴到 /usr/local RUN pip install --no-cache-dir --user -r requirements.txt # 第二階段創(chuàng)建更小的運行時鏡像 FROM python:3.9-slim # 設(shè)置工作目錄 WORKDIR /app # 從構(gòu)建階段復(fù)制已安裝的Python包 COPY --frombuilder /root/.local /root/.local # 將應(yīng)用代碼復(fù)制到工作目錄 COPY app.py . # 確保運行時可以找到用戶安裝的包 ENV PATH/root/.local/bin:$PATH # 聲明容器運行時監(jiān)聽的端口 EXPOSE 5000 # 定義容器啟動時執(zhí)行的命令 CMD [python, app.py]這個Dockerfile做了幾件關(guān)鍵事情FROM指定基礎(chǔ)鏡像。我們選擇官方的python:3.9-slim它是一個刪減了非必要文件的Python環(huán)境比完整版小很多。WORKDIR設(shè)置容器內(nèi)的工作目錄后續(xù)的COPY、RUN等命令都會在此目錄下執(zhí)行。COPY將宿主機的文件或目錄復(fù)制到鏡像中。RUN在構(gòu)建鏡像時執(zhí)行命令。這里用于安裝Python依賴。ENV設(shè)置環(huán)境變量。這里將用戶安裝包的路徑添加到PATH中。EXPOSE聲明容器運行時監(jiān)聽的端口。這只是一個文檔說明實際映射需要在docker run時用-p參數(shù)指定。CMD指定容器啟動時默認運行的命令。一個Dockerfile中只能有一個CMD指令。4. 構(gòu)建鏡像 在包含Dockerfile、app.py和requirements.txt的目錄下執(zhí)行docker build -t my-flask-app:1.0 .-t為鏡像打標(biāo)簽格式為name:tag。.指定構(gòu)建上下文context的路徑。Docker客戶端會將這個目錄下的所有文件打包發(fā)送給Docker守護進程因此要避免包含不必要的文件如node_modules,.git通常使用.dockerignore文件來排除。5. 運行自定義鏡像docker run -d -p 5000:5000 --name my-app my-flask-app:1.0訪問http://localhost:5000你應(yīng)該能看到“Hello, Dockerized World!”。通過Dockerfile構(gòu)建鏡像你將應(yīng)用代碼、運行環(huán)境、配置全部固化到了一個可移植的鏡像中。這是實現(xiàn)持續(xù)集成和持續(xù)部署CI/CD的基石。7. 數(shù)據(jù)持久化與網(wǎng)絡(luò)超越單容器當(dāng)應(yīng)用變得復(fù)雜你會面臨兩個新問題容器內(nèi)的數(shù)據(jù)如何持久化多個容器之間如何通信7.1 數(shù)據(jù)卷Volumes持久化數(shù)據(jù)的正確方式容器本身是易失的ephemeral。當(dāng)容器被刪除其可寫層中的所有數(shù)據(jù)也會丟失。為了持久化數(shù)據(jù)如數(shù)據(jù)庫文件、配置文件、日志Docker提供了數(shù)據(jù)卷機制。數(shù)據(jù)卷是宿主機文件系統(tǒng)中由Docker管理的一個特殊目錄它獨立于容器的生命周期。即使容器被刪除數(shù)據(jù)卷依然存在。# 創(chuàng)建一個命名數(shù)據(jù)卷 docker volume create my-data # 運行容器并掛載數(shù)據(jù)卷到容器內(nèi)的路徑 docker run -d -p 8080:80 \ --name my-nginx-with-data \ -v my-data:/usr/share/nginx/html \ nginx # 查看所有數(shù)據(jù)卷 docker volume ls # 查看數(shù)據(jù)卷詳情包括在宿主機上的實際路徑 docker volume inspect my-data # 刪除未使用的數(shù)據(jù)卷 docker volume prune在上面的例子中我們將名為my-data的數(shù)據(jù)卷掛載到了Nginx容器存放網(wǎng)頁文件的目錄。你對/usr/share/nginx/html目錄的任何修改實際上都保存在了宿主機的my-data卷中。下次你用同樣的卷啟動一個新容器數(shù)據(jù)依然存在。綁定掛載Bind Mounts另一種方式是將宿主機的特定目錄直接掛載到容器內(nèi)。這在開發(fā)時非常方便因為你可以即時在宿主機修改代碼容器內(nèi)立即生效。docker run -d -p 5000:5000 \ --name my-dev-app \ -v /path/to/your/code:/app \ my-flask-app:1.0這里宿主機的/path/to/your/code目錄被掛載到容器的/app目錄覆蓋了鏡像中原來的內(nèi)容。7.2 容器網(wǎng)絡(luò)讓容器彼此發(fā)現(xiàn)默認情況下每個容器都運行在獨立的網(wǎng)絡(luò)命名空間中擁有自己的網(wǎng)絡(luò)棧。Docker提供了幾種網(wǎng)絡(luò)模式最常用的是橋接網(wǎng)絡(luò)bridge。當(dāng)你安裝Docker時它會自動創(chuàng)建一個名為bridge的默認網(wǎng)絡(luò)。通過docker run啟動的容器如果沒有指定網(wǎng)絡(luò)就會連接到這個默認的橋接網(wǎng)絡(luò)。在這個網(wǎng)絡(luò)內(nèi)的容器可以通過IP地址相互通信但無法通過容器名通信。為了更好的服務(wù)發(fā)現(xiàn)我們可以創(chuàng)建自定義的橋接網(wǎng)絡(luò)。# 創(chuàng)建一個自定義橋接網(wǎng)絡(luò) docker network create my-app-network # 運行一個MySQL容器并連接到自定義網(wǎng)絡(luò) docker run -d \ --name mysql-db \ --network my-app-network \ -e MYSQL_ROOT_PASSWORDsecret \ mysql:8.0 # 運行一個Web應(yīng)用容器連接到同一個網(wǎng)絡(luò) docker run -d \ --name web-app \ --network my-app-network \ -p 8080:80 \ -e DATABASE_HOSTmysql-db \ my-web-app:latest關(guān)鍵點在于--network my-app-network。在同一個自定義橋接網(wǎng)絡(luò)中的容器不僅可以通過IP通信還可以直接使用容器名如mysql-db作為主機名進行通信。這對于多容器應(yīng)用例如一個Web應(yīng)用容器和一個數(shù)據(jù)庫容器的編排至關(guān)重要。在上面的例子中web-app容器可以通過mysql-db這個主機名連接到MySQL服務(wù)而無需知道其具體IP地址。8. 多容器應(yīng)用編排初探Docker Compose當(dāng)你需要管理多個相互關(guān)聯(lián)的容器比如一個Web前端、一個后端API、一個數(shù)據(jù)庫、一個緩存時手動使用docker run并設(shè)置網(wǎng)絡(luò)、卷、環(huán)境變量會變得非常繁瑣且容易出錯。Docker Compose就是為解決這個問題而生的工具。它允許你使用一個YAML文件docker-compose.yml來定義和運行多容器應(yīng)用。假設(shè)我們有一個簡單的“WordPress MySQL”博客應(yīng)用。創(chuàng)建一個docker-compose.yml文件version: 3.8 services: db: image: mysql:8.0 # 數(shù)據(jù)持久化 volumes: - db_data:/var/lib/mysql # 重啟策略除非手動停止否則總是重啟 restart: always environment: MYSQL_ROOT_PASSWORD: some_root_password MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress_password # 自定義網(wǎng)絡(luò)服務(wù)間可通過服務(wù)名通信 networks: - wp-network wordpress: depends_on: - db image: wordpress:latest # 端口映射 ports: - 8080:80 restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress_password WORDPRESS_DB_NAME: wordpress volumes: - wp_data:/var/www/html networks: - wp-network # 定義數(shù)據(jù)卷由Docker Compose管理 volumes: db_data: wp_data: # 定義網(wǎng)絡(luò)由Docker Compose管理 networks: wp-network: driver: bridge在這個文件中我們定義了兩個服務(wù)db和wordpress一個自定義網(wǎng)絡(luò)wp-network和兩個數(shù)據(jù)卷db_data,wp_data。depends_on確保了wordpress服務(wù)會在db服務(wù)啟動之后啟動?,F(xiàn)在只需要在包含docker-compose.yml的目錄下執(zhí)行一條命令# 啟動所有服務(wù)在后臺運行 docker-compose up -d # 查看運行狀態(tài) docker-compose ps # 查看服務(wù)日志可以指定服務(wù)名 docker-compose logs -f wordpress # 停止并移除所有容器、網(wǎng)絡(luò)但保留數(shù)據(jù)卷 docker-compose down # 停止并移除所有容器、網(wǎng)絡(luò)同時刪除數(shù)據(jù)卷數(shù)據(jù)會丟失 docker-compose down -vDocker Compose極大地簡化了多容器應(yīng)用的開發(fā)、測試和部署流程。它讓你可以用聲明式的方式定義整個應(yīng)用棧并通過簡單的命令控制其生命周期。對于本地開發(fā)環(huán)境搭建和簡單的生產(chǎn)部署Docker Compose是一個非常強大且實用的工具。從運行第一個hello-world到管理鏡像、容器再到理解數(shù)據(jù)持久化、網(wǎng)絡(luò)最后用Docker Compose編排復(fù)雜應(yīng)用這條路徑清晰地勾勒出了一名開發(fā)者從Docker新手到熟練用戶的成長軌跡。每個命令背后都對應(yīng)著容器技術(shù)的一個核心概念理解它們你就能真正將Docker化為己用構(gòu)建出穩(wěn)定、可移植的現(xiàn)代化應(yīng)用。