當我開始使用Docker時,我很快意識到它有多強大。想像一下,在幾分鐘內設置開發環境,而不是幾小時,或者在不同機器上運行應用程序而不出現經典的“在我的機器上運行正常”的問題。
Docker通過將應用程序打包成輕量級、可移植的容器,簡化了我們構建、交付和運行應用程序的過程。無論您是開發人員、數據科學家還是系統管理員,掌握Docker都可以幫助您避免麻煩,讓您的工作流程更加高效。
在本教程中,我將帶您了解基礎知識——安裝Docker、理解關鍵概念以及運行第一個容器化應用程序。最終,您將不僅了解Docker的工作原理,還將親自使用它,為更高級的主題打下堅實基礎。讓我們開始吧!
什麼是Docker?
Docker是一個開源的容器化平台,通過將軟件及其依賴項打包成一個稱為容器的標準化單元,簡化了應用程序部署。與傳統虛擬機不同,Docker容器共享主機操作系統內核,使其更高效和輕量級。 Unlike traditional virtual machines 。
容器確保應用程式在開發、測試和生產環境中以相同方式運行。這減少了相容性問題,並增強了在各種平台之間的可攜性。由於其靈活性和可擴展性,Docker已成為現代DevOps和雲原生開發工作流程中的關鍵工具。
Docker官方標誌。
安裝Docker
Docker可以安裝在各種操作系統上,包括Windows、macOS和Linux。雖然核心功能在所有平台上保持一致,但安裝過程根據系統的不同略有差異。以下是您所選擇的操作系統上安裝Docker的逐步說明。
在Windows上安裝Docker
下載Windows的Docker Desktop安裝程式
- 運行安裝程序並按照設置說明操作。
安裝 Docker Desktop for Windows
- 如果提示,啟用 WSL 2 整合。
- 在 PowerShell 中運行
docker –version
來驗證安裝。
通過 Powershell 檢查安裝後的 Docker 版本
5. 從運行菜單中啟動 Docker Desktop 應用程式。
在 Windows 上啟動 Docker Desktop 應用程式
在 macOS 上安裝 Docker
下載 Mac 版 Docker Desktop 安裝程式
- 打開下載的
.dmg
檔案並將 Docker 拖曳到應用程式文件夾中。 - 啟動 Docker 並完成設置。
- 在終端機中使用
docker –version
來驗證安裝。
在Linux(Ubuntu)上安裝Docker
- 更新軟件包列表:
sudo apt update
- 安裝依賴項:
sudo apt install apt-transport-https ca-certificates curl software-properties-common
- 添加Docker的官方GPG金鑰:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- 添加Docker的存儲庫:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- 安裝Docker:
sudo apt install docker-ce
- 驗證安裝:
docker –version
基本Docker概念
現在您已經安裝了Docker,您可能急於開始運行容器。但在我們開始之前,了解幾個形成Docker工作基礎的關鍵概念很重要。這些概念將幫助您更有效地使用Docker並避免常見的初學者陷阱。
Docker 的核心是 映像,它們作為容器的藍圖; 容器,是這些映像的運行實例;以及 Docker Hub,一個集中式的存儲庫,用於共享和管理映像。
讓我們更詳細地探討這些概念。
Docker 映像
Docker 映像是容器的基本構建塊。它們是不可變的、唯讀的模板,包含運行應用程序所需的一切,包括操作系統、應用程序代碼、運行時和依賴項。
映像是使用 Dockerfile
構建的,該文件定義了逐層創建映像的指令。
映像可以儲存在容器註冊表中,並從中檢索,例如 Docker Hub。
以下是一些用於處理映像的示例命令:
docker pull nginx
:從 Docker Hub 獲取最新的 Nginx 映像。docker images
:列出本地機器上所有可用的映像。docker rmi nginx
:從本地機器中刪除映像。
Docker 容器
Docker 容器是 Docker 映像的運行實例。容器提供了一個隔離的運行時環境,應用程序可以在其中運行,而不會相互干擾或影響主機系統。每個容器都有自己的文件系統、網絡和進程空間,但共享主機內核。
容器遵循一個簡單的生命週期,包括創建、啟動、停止和刪除。以下是常見容器管理命令的細分:
- 創建容器:
docker create
或docker run
- 啟動容器:
docker start
- 停止容器:
docker stop
- 重新啟動容器:
docker restart
- 刪除容器:
docker rm
讓我們看一個實際的例子。以下命令在脫離模式(在背景中運行)下運行一個 Nginx 容器,並將容器內的 80 端口映射到主機的 8080 端口:
docker run -d -p 8080:80 nginx
執行此命令後,Docker 將拉取 Nginx 映像(如果尚未可用),創建一個容器並啟動它。
要檢查所有正在運行和已停止的容器:
docker ps -a
這將顯示所有容器的列表以及其狀態和分配的端口等詳細信息。
Docker Hub
Docker Hub是一個基於雲的註冊服務,用於查找、存儲和分發容器映像。用戶可以將自定義映像推送到Docker Hub 並公開或私下共享。
以下是與Docker Hub 互動的一些命令:
docker login
: 與Docker Hub 進行身份驗證。docker push my-image
: 將自定義構建的映像上傳到Docker Hub。docker search ubuntu
: 搜索官方和社區映像。docker pull ubuntu
: 從Docker Hub 下載Ubuntu映像。
初次接觸容器化嗎?通過容器化和虛擬化概念課程建立堅實基礎。
運行您的第一個Docker容器
現在我們已經介紹了Docker的核心概念,是時候將它們付諸行動了!讓我們從運行我們的第一個容器開始,以確保Docker已正確安裝並按預期運行。
要測試您的Docker安裝,打開PowerShell(Windows)或Terminal(Mac和Linux)並運行:
docker run hello-world
這將從DockerHub 下載hello-world
映像並在容器中運行。
Docker hello-world映像示例
現在,讓我們更進一步,運行一個真實應用程序 – 一個 Nginx web 伺服器。執行以下命令:
docker run -d -p 8080:80 nginx
上述命令執行以下操作:
- 參數
-d
以分離模式運行容器,表示它在後台運行。 - 參數
-p 8080:80
將容器內部的端口 80 映射到本地機器的端口 8080,允許您訪問 Web 伺服器。
一旦命令成功運行,打開瀏覽器訪問:http://localhost:8080
訪問本機的 Web 伺服器:localhost:8080
您應該看到預設的 Nginx 歡迎頁面,確認您的 Web 伺服器正在容器內運行!
您還將在 Docker Desktop 中看到正在運行的容器:
Nginx 容器運行在端口 8080
建立您的第一個 Docker 映像
到目前为止,我们一直在运行来自Docker Hub的预构建映像。但是如果您需要针对您的应用程序量身定制的自定义环境呢?这就是构建自己的Docker映像的用武之地。。
创建Docker映像涉及编写一个Dockerfile
,这是一个自动化构建映像的脚本。这确保了在不同环境中的一致性和可移植性。构建完成映像后,它可以作为容器运行,以在隔离环境中执行应用程序。
在本节中,我们将学习编写Dockerfile、构建自定义映像并将其作为容器运行的基础知识。
Dockerfile基础
一個 Dockerfile
是包含一系列指令的腳本,用於定義如何建構 Docker 映像。它自動化了映像創建過程,確保在不同環境中保持一致性。每個 Dockerfile
中的指令都會在映像中創建一個新的層。以下是一個簡單的 Python Flask 應用程序的 Dockerfile 範例:
# 包含 Python 運行時的基本映像 FROM python:3.9 # 在容器內設置工作目錄 WORKDIR /app # 將應用程序文件從主機複製到容器中 COPY . /app # 安裝 requirements.txt 中列出的依賴項 RUN pip install -r requirements.txt # 定義當容器啟動時運行 Flask 應用程序的命令 CMD ["python", "app.py"]
在上述命令中:
-v my-volume:/app/data
將my-volume
存儲掛載到容器內的/app/data
目錄。- 即使容器停止或被刪除,存儲在
/app/data
中的任何數據都將持久存在。
對上面的 Dockerfile 進行分解:
FROM python:3.9
: 指定具有預安裝 Python 3.9 的基本映像。WORKDIR /app
: 將/app
設置為容器內的工作目錄。COPY . /app
: 將所有文件從主機當前目錄複製到容器中的/app
。RUN pip install -r requirements.txt
: 在容器內安裝所有必需的依賴項。CMD ["python", "app.py"]
: 定義容器啟動時要執行的命令。
構建和運行映像
一旦定義了 Dockerfile,您可以使用以下命令來構建和運行映像:
步驟 1: 構建映像
docker build -t my-flask-app .
上述命令:
- 使用當前目錄(
。
)作為構建上下文。 - 讀取
Dockerfile
並執行其指令。 - 將生成的映像標記(
-t
)為my-flask-app
。
步驟 2: 將映像作為容器運行
docker run -d -p 5000:5000 my-flask-app
上述命令:
- 以脫離模式運行容器(
-d
)。 - 將容器內的5000端口映射到主機的5000端口(
-p 5000:5000
)。
運行後,您可以通過在瀏覽器中導航到http://localhost:5000
來訪問Flask應用程序。
Docker 卷與持久性
默認情況下,Docker容器內的數據是臨時的—一旦容器停止或被移除,數據就會消失。為了在容器重啟之間持久化數據並在多個容器之間共享,Docker提供了卷,這是一種內置機制,用於有效管理持久存儲。
與將數據存儲在容器的文件系統內不同,Docker 通過單獨管理卷使其更高效、靈活且更易於備份。
在接下來的部分中,我們將探討如何創建和使用 Docker 卷來確保容器中的數據持久性。
創建和使用 Docker 卷
步驟 1:創建卷
在使用卷之前,我們需要創建一個。運行以下命令:
docker volume create my-volume
這將創建一個名為my-volume
的命名卷,Docker 將單獨管理它,與任何特定容器分開。步驟 2:在容器中使用這個卷
現在,讓我們開始一個容器並將卷掛載到其中:
docker run -d -v my-volume:/app/data my-app
在上述命令中:
-v my-volume:/app/data
將my-volume
存儲掛載到容器內部的/app/data
目錄。- 存儲在
/app/data
中的任何數據將在容器停止或刪除時保留。
用於多容器應用程序的Docker Compose
到目前為止,我們一直在處理單容器應用程序,但許多現實世界的應用程序需要多個容器一起運行。例如,網絡應用程序可能需要後端伺服器、數據庫和快取層,每個都在自己的容器中運行。使用獨立的 docker run
命令手動管理這些容器可能很快變得乏味。
這就是Docker Compose的用途。
Docker Compose是什麼?
Docker Compose是一個簡化多容器應用程序管理的工具。您可以使用一個docker-compose.yml
文件定義整個應用程序堆棧,並通過一個命令部署它,而不是運行多個docker run
命令。
撰寫Docker Compose文件
現在,讓我們創建一個現實世界的示例——一個簡單的連接到MongoDB數據庫的Node.js應用程序。我們將它們定義在一個docker-compose.yml
文件中,而不是分別管理這兩個容器。
以下是我們如何在Docker Compose中定義多容器設置:
version: '3' services: web: build: . ports: - "3000:3000" depends_on: - database database: image: mongo volumes: - db-data:/data/db volumes: db-data:
分解上面的文件:
version: '3'
:指定Docker Compose版本。services:
:定義單個服務(容器)。web:
:定義Node.js Web應用程序。database:
:定義MongoDB數據庫容器。volumes:
:為MongoDB數據持久性創建一個命名卷(db-data
)。
運行多容器應用程序
一旦docker-compose.yml
文件準備就緒,我們可以使用一個命令啟動整個應用程序堆棧:
docker-compose up -d
上述命令以分離模式(-d
)啟動Web和數據庫容器。
要停止所有服務,請使用:
docker-compose down
這會停止並刪除所有容器,同時保留卷和網絡設置。
Docker網絡基礎知識
到目前為止,我們專注於運行容器和管理存儲,但當容器需要彼此通信時會發生什麼?在大多數現實應用中,容器並不是獨立運行的,它們需要交換數據,無論是網絡伺服器與數據庫交互還是微服務彼此交互。
Docker提供了一系列網絡選項,以滿足不同的使用情況,從隔離的內部網絡到外部可訪問的配置。
準備好提升您的Docker技能了嗎?參加 中級Docker,探索多階段構建、高級網絡等內容!
什麼是Docker網絡?
Docker網絡是一個內置功能,允許容器彼此通信,無論是在同一主機上還是在分佈式環境中跨多個主機。它提供了適用於不同部署場景的網絡隔離、分割和連接選項。
Docker支持多種網絡類型,每種類型滿足不同的使用情況:
- Bridge(默認):同一主機上的容器通過內部虛擬網絡通信。每個容器在橋接網絡中獲得自己的私有IP地址,它們可以通過容器名稱相互訪問。
- 示例:
docker network create my-bridge-network
- 理想於在單一主機上運行多個容器,這些容器需要安全地進行通訊,而不將服務暴露於外部。
- 主機: 容器共享主機的網絡堆疊,並直接使用主機的 IP 地址和端口。
- 範例:
docker run --network host nginx
- 當您需要高性能且不需要網絡隔離時,此方法很有用,例如運行監控代理或低延遲應用程式。
- 覆蓋:通過創建分佈式網絡,在不同主機上實現容器通信。
- 示例:
docker network create --driver overlay my-overlay-network
- 設計用於像Docker Swarm這樣的編排部署,其中服務跨越多個節點。
- Macvlan:為每個容器分配唯一的MAC地址,使其在網絡上顯示為物理設備。
- 範例:
docker network create -d macvlan --subnet=192.168.1.0/24 my-macvlan
- 當容器需要直接網路訪問時使用,例如整合舊系統或與實體網路互動。
在自定義網路上運行容器
讓我們一起看看如何設置和使用自定義橋接網路 來進行容器通訊。
步驟 1:建立自定義網路
在運行容器之前,我們首先需要創建一個專用網路:
docker network create my-custom-network
此命令創建一個隔離的網路,容器可以加入以進行容器間通信。
步驟2:在網路上運行容器
現在,讓我們啟動兩個容器並將它們連接到我們新建的網路:
docker run -d --network my-custom-network --name app1 my-app docker run -d --network my-custom-network --name app2 my-app
- 使用
--network my-custom-network
標誌將容器連接到指定的網路。 - 使用
--name
標誌分配一個唯一的容器名稱,這樣更容易引用。
現在app11和
app2可以使用它們的容器名稱進行通信。您可以在其中一個容器內使用
ping`命令來測試連接性:
docker exec -it app1 ping app2
如果一切設定正確,您將看到一個確認回應,表示容器可以互相通信。
檢查 Docker 網路
要驗證網路配置和連接的容器,請使用:
docker network inspect my-custom-network
此命令提供有關網路的詳細資訊,包括 IP 範圍、連接的容器和配置。
暴露和發布端口
當運行需要外部可訪問的容器時,您可以暴露特定端口。
例如,要運行一個 Nginx 網頁伺服器並在您本地機器的端口 8080 上暴露它,請使用:
docker run -d -p 8080:80 nginx
這將容器內的端口80映射到主機上的端口8080,使服務可以通過http://localhost:8080進行訪問。
最佳的Docker網絡實踐
- 使用自定義網絡:在生產部署中避免使用默認的橋接網絡,以減少容器之間的意外訪問。
- 利用基於DNS的發現:使用容器名稱而非硬編碼IP地址,以實現動態服務發現。
- 限制外部暴露:使用防火牆或網絡策略來控制服務訪問。
- 監控流量:使用像
docker network inspect
、Wireshark或Prometheus等工具來分析網絡流量並檢測異常。 - 優化覆蓋網絡:如果在分佈式設置中部署,請調整覆蓋網絡以減少延遲,利用主機本地路由選項。
Docker最佳實踐和下一步
現在您已經學會了Docker的基礎知識,是時候提升您的技能,採用最佳實踐,幫助您構建安全、高效和可維護的容器化應用程序。
以下最佳實踐將幫助您優化Docker工作流程,避免常見陷阱。
- 使用官方基本映像:始終優先使用官方且維護良好的基本映像,以確保安全性和穩定性。官方映像經過優化,定期更新,且不太可能包含漏洞。
- 保持映像小巧:通過選擇精簡的基本映像(例如
python:3.9-slim
而不是python:3.9
)來減小映像大小。刪除不必要的依賴和文件以優化存儲和拉取時間。 - 使用多階段構建:通過分離構建和運行時依賴關係來優化 Dockerfile。多階段構建確保最終映像只包含必要的部件,從而減小大小和攻擊面。
- 標記圖像:始終使用帶有版本號的標記(例如
my-app:v1.0.0
),而不是使用latest
,以避免在拉取圖像時出現意外更新。 - 掃描圖像以查找漏洞:在部署前使用安全掃描工具如
docker scan
、Trivy
或Clair
來識別和修復圖像中的安全漏洞。 - 安全管理環境變數:避免將敏感憑證存儲在圖像內。使用Docker secrets、環境變數或像AWS Secrets Manager或HashiCorp Vault這樣的外部秘密管理工具。
- 使用 .dockerignore 文件:排除不必要的文件(例如
.git, node_modules
,venv
),以减少构建上下文大小,并防止意外包含敏感文件在镜像中。 - 启用日志记录和监控:利用诸如 Prometheus、Grafana 和 Fluentd 等工具进行容器日志和监控。使用
docker logs
检查日志,并启用结构化日志以获得更好的可观察性。
一旦掌握了 Docker 的基础知识,就有很多高级主题可以探讨。以下是一些值得探索的领域:
- Docker Swarm 與 Kubernetes:探索 Docker Swarm(內建集群)以及 Kubernetes(企業級的編排,具備自動擴展和服務發現功能),以實現生產級的編排。
- 容器安全最佳實踐:為了保護容器化應用程序,遵循 CIS Docker 基準指南並實施基於角色的訪問控制(RBAC)。
- 使用 Docker 的 CI/CD 管道: 通過 GitHub Actions、GitLab CI 或 Jenkins 自動化映像構建、安全掃描和部署。
- 雲原生開發: 利用 Docker 與 AWS ECS、Azure 容器實例和 Google Cloud Run 等雲平台進行可擴展和管理的部署。
- 數據持久化策略: 為了最佳的存儲管理,了解 Docker 卷、綁定掛載和 tmpfs 之間的區別。
結論
Docker 已經革新了開發人員建立、打包和運行應用程式的方式,使其成為現代軟體開發中不可或缺的工具。
在本教程中,我們涵蓋了:
- Docker 是什麼以及為什麼它如此重要
- 如何安裝和運行您的第一個容器
- 重要概念,如映像、容器和網路
- 使用 Docker 卷進行持久性儲存
- 使用 Docker Compose 的多容器應用程式
- 安全性、性能和可擴展性的最佳實踐
但這僅僅是個開始!如果您想深入了解 Docker 專業知識,可以參加一個 初學者級別 Docker 入門課程。如需更深入的知識,您可以參加一個 中級 Docker 課程,該課程涵蓋多階段構建、Docker 網路工具和 Docker Compose。最後,您還可以追求 Docker 認證,有興趣的話可以查看 2025 完整 Docker 認證 (DCA) 指南!