Docker
一、為什麼需要 Docker?
在容器化之前,開發者常遇到 「在我電腦上可以跑」 的問題:
- 本機 Node 版本與 CI / 正式環境不一致
- 作業系統差異(Windows / macOS / Linux)導致原生模組編譯失敗
- 依賴 PostgreSQL、Redis 等服務,本機安裝與設定繁瑣
- 部署流程與開發環境脫節
Docker 將應用程式及其所有依賴(執行環境、函式庫、設定)打包成可移植的映像檔(Image),在任何支援 Docker 的機器上以一致的方式執行。
Docker 解決的核心問題
| 問題 | Docker 解法 |
|---|---|
| 環境不一致 | 映像檔鎖定 OS + Node 版本 |
| 依賴管理複雜 | Dockerfile 宣告所有依賴 |
| 多服務協作 | Docker Compose 一鍵啟動 |
| 部署可重複 | 同一映像檔 → dev / staging / prod |
二、核心概念
2.1 映像檔(Image)vs 容器(Container)
| 概念 | 類比 | 說明 |
|---|---|---|
| Image | 程式安裝包 / 藍圖 | 唯讀模板,由 Dockerfile 建置 |
| Container | 執行中的程式 | Image 的執行實例,可啟停、刪除 |
flowchart LR
A["Dockerfile"] --> B["docker build"]
B --> C["Image 🖼️"]
C --> D["docker run"]
D --> E["Container 📦"]2.2 其他重要名詞
- Registry:映像檔倉庫,最常用 Docker Hub
- Volume:持久化資料,容器刪除後資料仍保留
- Network:容器間通訊的虛擬網路
- Layer:映像檔由多層堆疊,共用層可快取加速建置
- Multi-stage Build:多階段建置,縮小最終映像檔體積
三、安裝 Docker
- Windows
- 下載 Docker Desktop for Windows
- 啟用 WSL 2(建議)
- 安裝後執行
docker --version驗證
- macOS
- 下載 Docker Desktop for Mac
- Apple Silicon 選 ARM64 版本
- 執行
docker --version驗證
- Linux(Ubuntu 範例)
curl -fsSL <https://get.docker.com> | sh sudo usermod -aG docker $USER newgrp docker docker --version
驗證安裝成功:執行
docker run hello-world,看到 “Hello from Docker!” 即代表正常。
四、指令
| 指令 | 用途 |
|---|---|
docker build -t 名稱:標籤 . | 從 Dockerfile 建置映像檔 |
docker run -p 3000:3000 名稱 | 啟動容器並映射 port |
docker ps | 列出執行中容器 |
docker ps -a | 列出所有容器(含已停止) |
docker images | 列出本機映像檔 |
docker logs 容器ID | 查看容器日誌 |
docker exec -it 容器ID sh | 進入容器 shell |
docker stop / rm | 停止 / 刪除容器 |
docker rmi | 刪除映像檔 |
docker compose up -d | 背景啟動 Compose 服務 |
五、Dockerfile 基礎
Dockerfile 是一系列指令,描述如何建置映像檔:
# 基底映像
FROM node:20-alpine
# 工作目錄
WORKDIR /app
# 先複製 package 檔(利用 layer cache)
COPY package*.json ./
RUN npm ci
# 複製原始碼
COPY . .
# 建置(Next.js 範例)
RUN npm run build
# 對外 port
EXPOSE 3000
# 啟動命令
CMD ["npm", "start"]
Code language: PHP (php)
常用指令說明
- FROM:基底映像(
alpine體積小,適合 production) - WORKDIR:設定容器內工作目錄
- COPY / ADD:複製檔案(一般用 COPY 即可)
- RUN:建置時執行命令
- EXPOSE:文件化 port(實際映射靠
docker run -p) - CMD / ENTRYPOINT:容器啟動時執行的命令
六、.dockerignore
避免把不必要檔案送進建置 context,加速建置並縮小映像檔:
node_modules
.next
.git
.env*.local
docker-compose*.yml
Dockerfile*
README.md
npm-debug.log*
Code language: CSS (css)
七、Redis
Redis 是一個記憶體資料庫,主要用來當作系統的「快取(Cache)」、透過將查詢的資料存在記憶體(RAM),降低傳統資料庫(如 MySQL)的負擔。
舉個栗子: 假如你是圖書館的櫃檯管理員,學生會一直來找你問問題:
- 傳統資料庫(MySQL): 就像是圖書館裡的的大書庫。裡面藏書萬卷(資料量極大、結構嚴謹),但你每次要找資料,都要親自走進密密麻麻的書架裡翻找(硬碟讀寫 I/O),速度比較慢。如果突然有 1,000 個學生同時衝進來問同一個問題,大書庫就會卡到爆炸。
- Redis: 像是你櫃檯桌面上的一張「便利貼」。把最熱門、全校學生每天都在問的問題與答案(例如:日語相關書籍在哪? 在5樓。)直接寫在便利貼上。因為就在桌面上, 0.001 秒就能直接回答,這就是記憶體讀取。
聽起來很讚,但缺點也很明顯,就是記憶體很貴,而且如果電腦突然斷電,記憶體裡的資料有可能會遺失。
