Docker 新手入門:1 小時學會把專案打包進容器的 5 個步驟
Docker 在 2025 年全球開發者使用率達 59%(「Docker 為 Stack Overflow 2024 年最受歡迎的容器化工具,使用率 59%」(來源:Stack Overflow Developer Survey 2024)),核心價值不在「打包應用程式」,而在於把「環境配置」從部署流程的最大變數變成可
Docker 在 2025 年全球開發者使用率達 59%( 「Docker 為 Stack Overflow 2024 年最受歡迎的容器化工具,使用率 59%」(來源:Stack Overflow Developer Survey 2024) ),核心價值不在「打包應用程式」,而在於把「環境配置」從部署流程的最大變數變成可版本控制的純文字檔。一份 Dockerfile 等於一份可重現的伺服器配方,這也是它取代傳統部署文件的根本原因。 Docker 是什麼:容器與虛擬機的本質差異 Docker 是一套基於 Linux 容器(LXC)技術的平台,將應用程式與其執行環境打包成「映像檔(Image)」,並以「容器(Container)」形式執行。容器與虛擬機(VM)最大的差異在於是否包含作業系統核心:VM 每台都背一個完整 OS,容器則共用宿主機核心,只隔離 process、檔案系統與網路。 這個架構差異直接反映在效能上。 「容器啟動時間以毫秒計,傳統 VM 啟動需數十秒至數分鐘」(來源:IBM Think 技術文件) 。一台 16GB 記憶體的伺服器可能只能跑 4-8 台 VM,但能同時運行數十個容器,這是 Docker 在微服務架構成為事實標準的關鍵。 三個核心概念 Image(映像檔) :唯讀的範本,包含應用程式、相依套件、環境變數、執行指令。可比喻為「類別(Class)」。 Container(容器) :Image 的執行實例,可啟動、停止、刪除。可比喻為「物件(Object)」。 Dockerfile :用來建構 Image 的純文字腳本,每一行對應一層檔案系統(layer)。 安裝與第一個容器:5 分鐘上手路徑 macOS 與 Windows 使用者直接安裝 Docker Desktop,Linux 則建議用官方腳本安裝 Docker Engine。安裝完成後,先執行 docker run hello-world 驗證引擎是否正常,再進入實際操作。 啟動一個 Nginx 網頁伺服器只需要一行指令: docker run -d -p 8080:80 --name my-web nginx 這行指令做了四件事:從 Docker Hub 拉取 nginx 映像檔、在背景啟動容器(-d)、把宿主機 8080 port 對應到容器內 80 port、命名為 my-web。打開瀏覽器輸入 http://localhost:8080 立即看到 Nginx 預設頁面。整個過程不需要在宿主機安裝任何 Nginx 相關檔案。 常用指令速查 docker ps :列出執行中的容器(加 -a 列出全部)。 docker logs [容器名] :查看容器輸出,加 -f 即時追蹤。 docker exec -it [容器名] bash :進入容器內 shell,這是除錯時最常用的指令。 docker stop / start / rm [容器名] :停止、啟動、刪除容器。 docker images :列出本機所有映像檔。 Dockerfile:把專案環境寫成程式碼 Dockerfile 是 Docker 的精髓。一份典型的 Node.js 應用 Dockerfile 結構如下: FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . EXPOSE 3000 CMD ["node", "server.js"] 這份檔案的順序刻意設計過,目的是利用 Docker 的「層快取(layer cache)」機制。每一行 RUN、COPY、ADD 都會產生一層,當該層的內容沒變動時,重新建構會直接使用快取。把不常變動的 npm ci 放在 COPY . . 之前,能讓修改原始碼時跳過漫長的套件安裝步驟,把 build 時間從數分鐘壓到數秒。 Multi-stage build:把映像檔縮小 80% 多階段建構是 2026 年仍被低估的優化技巧。建構階段使用完整的 SDK 映像(如 node:20 約 1GB),執行階段只複製 build 產物到精簡映像(如 node:20-alpine 約 180MB): FROM node:20 AS builder WORKDIR /app COPY . . RUN npm ci && npm run build FROM node:20-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules CMD ["node", "dist/s