容器設計原則:單一職責、無狀態、設定走環境變數

主張:容器化的難點不在指令,在設計。這五條決定了你的容器能不能被隨便砍掉重開、能不能一份 image 打天下。

五條

  1. 一個容器一個職責 — 不要把 nginx + app + mysql 塞進同一個容器。要三個服務就三個容器。
  2. 無狀態、可拋棄 — 任何需要留下來的東西都放 volume 或外部服務,「隨時可以被砍掉重開」是設計目標(見 容器可拋棄,資料要靠 Volume 留在容器外)。
  3. 設定從環境變數進來 — 同一份 image 應該能靠環境變數跑在 dev / staging / prod,不要為每個環境 build 不同 image
  4. log 印到 stdout/stderr — 不要寫進容器裡的檔案,Docker 和 K8s 的日誌系統都是收 stdout 的。
  5. 處理 SIGTERM — 用 exec form 的 CMD 並在應用程式裡監聽 SIGTERM 做優雅關閉,不然 docker stop 會硬砍你的連線(見 CMD 與 ENTRYPOINT 的差別與 exec form 的 SIGTERM 陷阱)。

安全清單

  • 不要用 root 跑容器 — Dockerfile 加 USER node;容器逃逸時 root 的殺傷力完全不同
  • 密碼絕對不要寫進 DockerfileENVARG 都會留在 image metadata,docker history 就看得到。用 docker run -e、secret 服務或 BuildKit secret mount
  • 寫好 .dockerignore — 否則 .env.git、金鑰會被烤進 image,build 也會變慢變肥
  • 釘住基底版本、掃漏洞(docker scout cves / trivy)、最小化 image、不必要就不開 port

正式環境另外設 --memory / --cpus 上限,防止單一容器拖垮主機。

延伸:Image 是 CI-CD 流水線上唯一的交付物