入門級開發者常面臨程式碼更新、發佈與部署效率低下的痛點,以及維護環境一致性的挑戰。在開發環境中運作順暢的程式碼,到另一台機器上可能出現錯誤。在雲端運算時代,使用傳統方法部署程式碼已顯得過時。本文將為你介紹 Docker。
Docker 基於 Go 語言開發,並遵循 Apache 2.0 授權開源,是一款應用程式容器引擎。這項容器化技術讓開發者能將應用程式及其依賴封裝成輕量、可移植的容器。這些容器可部署在任何主流 Linux 機器上,無需擔心環境差異。

Docker 與虛擬機器(VMs)的比較
如前述,Docker 使用了虛擬化技術。談到虛擬化,就不得不提虛擬機器(VM)。由於兩者都依賴虛擬化,自然會好奇它們的差異。讓我們深入探討。
首先,來看典型的 VM 架構圖。在基礎設施(代表底層硬體)之上,有 hypervisor(虛擬機監視器)。它作為實體伺服器與作業系統之間的中介,允許多個作業系統與應用程式共享底層硬體。虛擬機器在主機作業系統之上運行多個不同的作業系統,並透過 hypervisor 存取底層硬體。
如果你需要執行三個隔離的應用程式,就會建立三個虛擬機器。這意味著 hypervisor 上將運行三個作業系統,導致大量的資源開銷。

典型的 VM 架構圖
(注意:圖中 Hypervisor 上方應有 Host Operating System)
相比之下,Docker 非常輕量。它的守護行程(Docker Daemon)取代了 hypervisor,直接運行在作業系統上。應用程式的原始碼與依賴項被封裝成 Docker 映像檔(Image)。Docker 引擎再用此映像檔建立容器(Container)。不同的應用程式在隔離的容器中運行。
此外,Docker 守護行程直接與作業系統通訊,為 Docker 容器分配資源。由於沒有完整作業系統的開銷,容器啟動時間從虛擬機器的數分鐘縮短至 Docker 容器的毫秒等級,大幅提升效率,並節省大量磁碟空間與其他系統資源。
雖然 Docker 有顯著優勢,但它並非完全取代虛擬機器。每種技術各有擅長。虛擬機器擅長隔離整個執行環境,雲端服務供應商常用 VM 來隔離不同用戶。而 Docker 通常用於隔離不同的應用程式。
如何使用 Docker
Docker 安裝(以 CentOS 7 為例)
- 安裝必要的系統工具:
yum install -y yum-utils device-mapper-persistent-data lvm2
- 更新系統核心與 yum 快取:
yum update
yum makecache fast
- 安裝 Docker 並啟動:
yum -y install docker-ce
systemctl start docker
- 測試 Docker 是否安裝成功:
docker run hello-world
若畫面上出現 “Hello from Docker”,恭喜你!安裝完成。
概念
在深入 Docker 之前,先了解幾個關鍵概念,讓學習過程更順利。
- Docker 映像檔(Image):Docker 映像檔是用來建立 Docker 容器的範本。
- Docker 容器(Container):Docker 透過映像檔建立容器,用於執行一組獨立的應用程式。
- Docker 倉儲(Registry):儲存映像檔的程式碼倉庫。
通常,我們從 Docker 倉儲下載合適的映像檔,再用它建立容器來執行應用程式。
範例
透過兩個常見範例來串聯這些概念,說明如何使用 Docker。
用 Docker 安裝 Python
如前所述,使用 Docker 容器的第一步是從倉儲下載對應的映像檔。這就引出了本教學的第一個指令:
docker search
- 用途: 在映像檔倉儲中搜尋特定的映像檔。
- 語法:
docker search [OPTIONS] TERM - 範例:
docker search python - 說明: 在倉儲中搜尋與 Python 相關的映像檔。
[root@novita ~]# docker search pythonINDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/python Python is an interpreted, interactive, obj... 4356 [OK]
docker.io docker.io/django Django is a free web application framework... 856 [OK]
docker.io docker.io/pypy PyPy is a fast, compliant alternative impl... 196 [OK]
docker.io docker.io/kaggle/python Docker image for Python scripts run on Kaggle 125 [OK]
docker.io docker.io/arm32v7/python Python is an interpreted, interactive, obj... 38
docker.io docker.io/centos/python-35-centos7 Platform for building and running Python 3... 36
我們選擇標籤(版本)為 3.7 的官方映像檔。
docker pull
- 用途: 從映像檔倉儲拉取或更新指定的映像檔。
- 語法:
docker pull [OPTIONS] NAME:TAG - 範例:
docker pull python:3.7 - 說明: 從倉儲下載標籤為 3.7 的 Python 映像檔。
[root@novita ~]# docker pull python:3.7
Trying to pull repository docker.io/library/python ...3.7: Pulling from docker.io/library/python
5ae19949497e: Downloading [=============> ] 13.72 MB/50.38 MB
ed3d96a2798e: Download complete
f12136850781: Downloading [============================================> ] 8.789 MB/9.978 MB
1a9ad5d5550b: Downloading [==> ] 2.628 MB/51.77 MB
6f18049a0455: Waiting
ce39fa9d79d1: Waiting
Digest: sha256:d8718f4c8f28360c88d2d8b53681edb3c95e6a7bacedabd32eb5b1d120a75dc5
Status: Downloaded newer image for docker.io/python:3.7
現在 Docker 已下載指定的映像檔。若要查看現有的 Docker 映像檔:
docker images
- 用途: 列出本機的映像檔。
- 語法:
docker images [OPTIONS] [REPOSITORY[:TAG]] - 範例:
docker images - 說明: 查看所有本機的 Docker 映像檔。
[root@novita ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/python 3.7 42d620af35be 6 days ago 918 MB
docker.io/rabbitmq 3-management 7aae48fa6ef6 7 days ago 179 MB
docker.io/golang latest f50db16df5da 9 days ago 774 MB
python3.7 映像檔已存在。接下來用此映像檔建立容器。
docker run
建立容器前,先簡單介紹 ID。在 Docker 中,ID 用於唯一識別映像檔或容器。我們透過「指令 + ID」來操作。例如,上方 python3.7 的 Image ID 是 42d620af35be。
- 用途: 建立一個新容器。
- 語法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
為了測試 Python 環境,先在本機建立一個 hello.py 檔案:
#!/usr/bin/python
import sys
print("Hello, Docker!")
print(sys.version) # 輸出 Python 版本號
假設此程式碼儲存在 /root/code/python:
[root@novita python]# docker run -v $PWD:/usr/src/code -w /usr/src/code python:3.7 python hello.py
Hello, Docker!
3.7.4 (default, Jul 13 2019, 14:04:11) [GCC 8.3.0]
讓我們拆解這個指令:
docker run:建立容器。-v $PWD:/usr/src/code:將本機目錄掛載到 Docker 容器內。此處將執行指令的目錄掛載到容器內的 /usr/src/code。冒號分隔本機路徑與容器路徑。你也可以使用絕對路徑取代$PWD。-w /usr/src/code:設定容器的工作目錄。由於 Python 程式碼目錄已掛載到 /usr/src/code,因此將它設為工作目錄。python:3.7:指定映像檔。你也可以使用 Image ID 取代。python hello.py:在容器內執行此指令。
想想看: 如果你有一個 hello.go 檔案在 /root/data/,想要使用 Image ID 為 f50db16df5da 的 Golang 容器來執行它,指令應該是什麼?(提示:執行 Go 程式碼的指令是 go run FILENAME)
用 Docker 安裝 MariaDB
假設你現在能夠搜尋並下載 MariaDB 的映像檔,接下來重點在於啟動它。資料庫之類的服務需要對應的連接埠在主機上開啟。如何用 Docker 實現呢?我們使用連接埠對應,類似於掛載目錄的方式。
[root@novita python]# docker run -d -v /data/mysql/:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --restart unless-stopped 3a2ef06682ac
-d:讓容器在背景執行。-p 3306:3306:將容器內的 3306 連接埠對應到主機的 3306 連接埠。-e MYSQL_ROOT_PASSWORD=123456:設定 MariaDB 的 root 密碼為 123456。--restart unless-stopped:若容器意外停止,自動重新啟動。3a2ef06682ac:用於建立容器的映像檔 ID。
現在,驗證資料庫服務是否正在執行:
docker ps
- 用途: 列出容器。
- 語法:
docker ps [OPTIONS]
[root@novita ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
107b52416c13 3a2ef06682ac "docker-entrypoint..." 5 minutes ago Up 5 minutes 0.0.0.0:3306->3306/tcp quizzical_mcnulty
接下來,進入容器內部環境。
docker exec
- 用途: 在執行中的容器內部執行指令。
- 語法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...] - 範例:
docker exec -it 107b52416c13 bash - 說明: 存取容器 ID 為 107b52416c13 的容器,並執行
bash指令。
進入容器後,可以像一般 Linux 環境一樣與之互動。使用先前設定的憑證即可存取 MariaDB。
[root@novita ~]# docker exec -it 107b52416c13 bash
root@107b52416c13:/# mysql -u root -p123456
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.4.6-MariaDB-1:10.4.6+maria~bionic mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
到目前為止,你已經學會了 Docker 的基礎。試著探索更多吧。
Novita AI 是滿足您 AI 願景的一站式雲端平台。透過無縫整合的 API、無伺服器運算與 GPU 加速,我們提供經濟實惠的工具,幫助您快速建置與擴展 AI 驅動的業務。告別基礎設施的麻煩,免費開始使用——Novita AI 讓您的 AI 夢想成真。
