如果你是開發者,一定聽過 Docker,也一定遇過這句經典台詞:「在我的電腦上明明可以跑啊!」——環境不一致、版本衝突、部署繁瑣,是每個團隊都繞不過去的痛。Docker 用「容器」把應用程式連同執行環境一起打包,從開發到上線全程一致,是當今前後端工程師都該掌握的基礎技能。今天就帶你從核心概念開始,實戰跑通容器化部署。
一、為什麼每個開發者都該學 Docker?
想像你寫了一個 Node.js 服務,本機跑得好好的,丟到伺服器上卻因為 Node 版本不同直接掛掉。Docker 解決的正是這個問題:把 程式碼 + 執行環境 + 相依套件 全部封裝成一個「映像(Image)」,任何機器上用同一個映像啟動,行為就完全一致。它帶來的三個核心好處:
- 環境一致:開發、測試、上線用同一個映像,告別「在我電腦上可以跑」
- 輕量隔離:容器共用宿主機核心,啟動只要秒級,比虛擬機器省資源得多
- 快速交付:一條指令就能部署,配上 CI/CD 直接自動化發布
重點:Docker 不是虛擬機器。虛擬機器模擬整台電腦(好幾 GB),容器只是把應用程式「裝進」宿主機的核心裡(幾十 MB),所以又快又輕。
二、三個核心概念:映像、容器、Dockerfile
學 Docker 只要搞懂三件事:
- 映像(Image):唯讀的「打包檔」,像是程式的光碟,由一層層指令堆疊而成
- 容器(Container):映像「跑起來」的實例,像是用光碟燒出來的一台機器,可以啟動、停止、刪除
- Dockerfile:描述「如何建映像」的食譜,一行行指令告訴 Docker 要裝什麼、怎麼跑
用一句話串起來:Dockerfile 建映像,映像啟動成容器。
三、步驟 1:跑起第一個容器
安裝 Docker Desktop 或伺服器上的 Docker Engine 後,先驗證環境:
docker --version
docker run hello-world
看到 Hello from Docker! 就代表環境正常。接著實際跑一個網頁伺服器:
docker run -d -p 8080:80 --name my-web nginx
特別注意:-p 8080:80 是「埠號對映」——把宿主機的 8080 埠接到容器內的 80 埠。少了這一步,外部就存取不到容器裡的服務。現在打開瀏覽器輸入 http://localhost:8080,就能看到 nginx 的歡迎頁。
四、步驟 2:用 Dockerfile 打包自己的程式
以一個簡單的 Node.js 服務為例,專案目錄裡放一支 server.js,再加一個 Dockerfile:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
FROM 指定基底映像、COPY 拷貝檔案、RUN 執行安裝、CMD 定義啟動指令。接著建映像並啟動:
docker build -t my-app .
docker run -d -p 3000:3000 my-app
重點:把 COPY package*.json 和 npm install 放在拷貝全部程式碼「之前」,是 Docker 經典的「利用快取」技巧——只要相依套件沒變,重新 build 就不用重裝,速度飛快。
五、步驟 3:用 Docker Compose 一次啟動多個服務
真實專案很少只有一個服務。用 docker-compose.yml 可以一次定義並啟動多個容器:
version: "3.8"
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secret
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
然後一條指令搞定:
docker compose up -d
docker compose ps
docker compose down
特別注意:容器是「無狀態」的,容器一刪,裡面寫入的檔案就沒了。所以資料庫這種要保存資料的服務,一定要用 volumes 掛載磁碟空間,否則資料會跟著容器一起消失。
六、常用指令速查
docker ps # 查看執行中的容器
docker images # 查看本機映像
docker logs my-web # 查看容器日誌
docker exec -it my-web sh # 進入容器內部除錯
docker stop my-web # 停止容器
docker rmi my-app # 刪除映像
互動話題:你部署過 Docker 嗎?最常卡關的環節是哪一步——是 Dockerfile 寫不好、埠號對映搞錯,還是跟資料持久化搏鬥?歡迎留言分享你的踩坑經驗,一起交流容器化的實戰心得!