env docker container

[Docker] 容器化技術

容器是什麼

「我電腦上跑得好好的,怎麼上了 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.0latest

和雲端的關係

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