「在我的電腦上明明可以跑啊!」——這句話是每個開發者的噩夢。Docker 的出現,就是為了終結這個問題。
這篇文章會帶你從零開始理解 Docker,不講太深的原理,專注在「這東西到底在幹嘛」和「我該怎麼開始用」。
Docker 解決什麼問題?
環境不一致的痛苦
想像這個場景:
- 你用 Python 3.11 開發
- 同事用 Python 3.9
- 正式環境是 Python 3.8
- 資料庫版本也不一樣
- 作業系統一個 Mac、一個 Windows、伺服器是 Linux
結果:你的程式在本機跑得好好的,部署上去就爆炸。
Docker 的解法
Docker 把你的應用程式連同它需要的所有環境(Python 版本、套件、設定檔...)打包成一個「容器」(Container)。
這個容器可以在任何有裝 Docker 的機器上運行,而且行為完全一致。
「在我電腦上可以跑」變成「在任何地方都可以跑」。
Docker 基本概念
Image(映像檔)
Image 就像是一個「模板」或「藍圖」。它包含了執行應用程式所需的一切:程式碼、執行環境、函式庫、設定檔。
Image 是唯讀的,你不能修改一個已經建立的 Image。
Container(容器)
Container 是 Image 的「執行實例」。就像類別(Class)和物件(Object)的關係:
- Image = 類別定義
- Container = 根據類別建立的物件
同一個 Image 可以建立多個 Container,它們各自獨立運行。
Dockerfile
Dockerfile 是一個文字檔,描述如何建立 Image。就像食譜一樣,一步一步說明要做什麼。
Docker Hub
Docker Hub 是一個公開的 Image 倉庫,你可以下載別人做好的 Image(例如 Python、MySQL、Redis),也可以上傳自己的。
動手實作
安裝 Docker
去 Docker 官網 下載 Docker Desktop,支援 Windows、Mac、Linux。
安裝完成後,打開終端機輸入:
docker --version如果看到版本號,就表示安裝成功了。
第一個容器
來跑一個最簡單的容器:
docker run hello-worldDocker 會:
- 在本機找 hello-world 這個 Image
- 找不到,從 Docker Hub 下載
- 用這個 Image 建立並執行一個 Container
- 印出一段歡迎訊息
恭喜,你已經跑了第一個 Docker 容器!
跑一個真正的應用
讓我們跑一個 Nginx 網頁伺服器:
docker run -d -p 8080:80 nginx參數說明:
-d:背景執行(detached mode)-p 8080:80:把本機的 8080 port 對應到容器的 80 portnginx:要使用的 Image 名稱
現在打開瀏覽器,訪問 http://localhost:8080,你會看到 Nginx 的歡迎頁面。
常用指令
# 列出正在執行的容器
docker ps
# 列出所有容器(包含停止的)
docker ps -a
# 停止容器
docker stop [容器ID或名稱]
# 刪除容器
docker rm [容器ID或名稱]
# 列出所有 Image
docker images
# 刪除 Image
docker rmi [Image名稱]
# 進入容器內部
docker exec -it [容器ID] bash寫你的第一個 Dockerfile
假設你有一個 Python 應用程式,檔案結構如下:
my-app/
├── app.py
├── requirements.txt
└── Dockerfileapp.py:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello from Docker!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)requirements.txt:
flask==3.0.0Dockerfile:
# 使用 Python 3.11 作為基底
FROM python:3.11-slim
# 設定工作目錄
WORKDIR /app
# 複製 requirements.txt 並安裝套件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 複製應用程式碼
COPY app.py .
# 開放 port 5000
EXPOSE 5000
# 執行應用程式
CMD ["python", "app.py"]建立並執行
# 建立 Image(別忘了最後的點!)
docker build -t my-python-app .
# 執行 Container
docker run -d -p 5000:5000 my-python-app打開 http://localhost:5000,你會看到「Hello from Docker!」。
Docker Compose:管理多個容器
真實的應用通常不只一個容器。例如:
- Web 應用程式
- 資料庫(MySQL/PostgreSQL)
- 快取(Redis)
- 反向代理(Nginx)
Docker Compose 讓你用一個 YAML 檔案定義和管理多個容器。
docker-compose.yml 範例
version: "3.8"
services:
web:
build: .
ports:
- "5000:5000"
depends_on:
- db
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:使用 Docker Compose
# 啟動所有服務
docker compose up -d
# 查看狀態
docker compose ps
# 查看 log
docker compose logs -f
# 停止所有服務
docker compose down最佳實踐
1. 使用 .dockerignore
就像 .gitignore,排除不需要的檔案:
node_modules
.git
*.log
.env2. 多階段建構
減少最終 Image 的大小:
# 建構階段
FROM node:18 AS builder
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
RUN npm run build
# 執行階段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html3. 不要用 root 執行
RUN useradd -m appuser
USER appuser4. 善用快取
把不常變動的指令放前面(例如安裝套件),常變動的放後面(例如複製程式碼)。
Docker vs 虛擬機
| 比較 | Docker | 虛擬機 |
|---|---|---|
| 啟動時間 | 秒級 | 分鐘級 |
| 資源消耗 | 低 | 高 |
| 隔離程度 | 程序級 | 系統級 |
| Image 大小 | MB 級 | GB 級 |
| 適用場景 | 微服務、CI/CD | 完整隔離、多 OS |
結語
Docker 已經是現代開發的標配。不管你是前端、後端、還是 DevOps,遲早都會碰到它。
學習建議:
- 先理解概念(Image、Container、Dockerfile)
- 動手跑幾個現成的 Image
- 把自己的小專案容器化
- 學習 Docker Compose 管理多容器
- 了解 CI/CD 和 Kubernetes(進階)
從今天開始,讓「在我電腦上可以跑」成為過去式。