容器是什麼
「我電腦上跑得好好的,怎麼上了 server 就掛了?」——作業系統不同、語言版本不同、系統函式庫不同,傳統部署的災難大多從這裡來。
容器(Container) 的解法是:把應用程式和它需要的一切(執行環境、套件、設定檔)打包成一個獨立單元。不管搬到哪台機器,跑起來的行為都一樣。
而且這個打包是輕量級的隔離——只帶程式執行需要的東西,不用模擬一整個作業系統。
容器 vs 虛擬機
| 虛擬機 (VM) | 容器 (Container) | |
|---|---|---|
| 隔離層級 | 完整模擬硬體,跑獨立的 OS | 共用 Host OS 核心,只隔離應用程式 |
| 啟動速度 | 分鐘級 | 秒級至毫秒級 |
| 大小 | GB 等級 | MB 等級 |
| 用途 | 需要完全隔離的環境 | 應用程式部署與開發環境 |
差別的根源就一句話:虛擬機模擬完整硬體、跑一個獨立 OS;容器直接共用 Host OS 的核心,只隔離應用層。所以容器才能那麼小、那麼快。
Docker 的核心概念
Image(映像檔)
Image 是容器的唯讀模板,定義了容器裡有什麼、怎麼啟動。來源有兩種:自己從 Dockerfile 建構,或直接從 Docker Hub 下載現成的(Node.js、PostgreSQL、Nginx 都有官方 image)。
Container(容器)
Container 是 Image 的執行實例。同一個 Image 可以同時跑出多個 Container,彼此隔離互不干擾。
要注意 Container 是暫時性的——刪掉之後裡面的資料就沒了。需要保留的資料(像資料庫檔案)要掛 Volume 才能持久化。
Dockerfile
描述「怎麼建構這個 Image」的腳本,每一行指令都會在 Image 上疊一層:
# 從官方 Node.js 20 image 開始
FROM node:20-alpine
# 設定工作目錄
WORKDIR /app
# 複製 package.json 並安裝依賴
COPY package.json .
RUN npm install
# 複製其餘程式碼
COPY . .
# 啟動指令
CMD ["node", "index.js"]
Docker Compose
實際專案很少只有一個容器——通常是 Web Server + 資料庫 + Cache 這種組合。Docker Compose 讓你用一份 compose.yml 定義所有服務,一個指令全部啟動。
services:
web:
image: nginx
ports:
- "80:80"
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
Docker 解決了什麼
- 開發環境一致性:新人 onboarding 不用照著文件一個一個裝工具,
docker compose up跑下去,環境就跟大家一樣 - 應用程式隔離:不同專案各跑各的容器,語言版本、套件版本互不打架
- 部署一致性:本機測過的 Image 跟 production 跑的是同一份,「環境不一樣」這類問題少掉一大半
Registry:Image 的倉庫
Image 建好之後要怎麼帶到別台機器?答案是推到 Registry——存放 Image 的遠端儲存庫,概念上就像程式碼的 GitHub。
- Docker Hub:最常用的公開 Registry,大多數官方 image 都放在這
- GitHub Container Registry (GHCR):跟 GitHub 整合,適合開源專案
- Amazon ECR / Google Artifact Registry / Azure Container Registry:各雲端平台自家的私有 Registry
推送與拉取流程
以推到 GHCR 為例:
# 1. 登入(使用 GitHub personal access token)
echo $GHCR_TOKEN | docker login ghcr.io -u <username> --password-stdin
# 2. 把本機 image 打上遠端 tag
docker tag my-app:latest ghcr.io/<username>/my-app:1.0.0
# 3. 推到 Registry
docker push ghcr.io/<username>/my-app:1.0.0
# 4. 在另一台機器拉下來直接跑
docker pull ghcr.io/<username>/my-app:1.0.0
docker run ghcr.io/<username>/my-app:1.0.0
幾個關於 tag 的細節:
- Tag 格式是
<registry>/<namespace>/<image>:<version> - 省略
<registry>的話,預設就是 Docker Hub - 同一個 image 可以打多個 tag 同時推送(例如
1.0.0和latest)
和雲端的關係
Docker 負責在一台機器上跑容器。但當規模大到要自動擴縮容、要顧高可用性,就需要容器編排工具來管理一整群容器,主流是 Kubernetes(K8s)。
各雲端平台也都有託管的容器服務:
- AWS ECS / EKS:Amazon 的容器服務
- Google Cloud Run / GKE:Google 的容器服務
- Azure Container Apps / AKS:Microsoft 的容器服務
這些服務吃的都是 Docker Image——你把 Image 推上去,部署和維運交給平台處理。
Latest Updates
- 2026.06.11 Content updated
