ExplainThis 全端開發雙週報 #86 Docker 與容器是什麼? 為什麼需要?
Docker 與容器是什麼? 為什麼需要?
先前有讀者在內容許願中提到 ExplainThis 的內容中似乎沒有關於 Docker 與容器 (container) 相關的內容,對此我們接下來會陸續有一系列的文章,從 Docker 與容器的基本介紹,到實戰的運用。
在開頭的第一篇文章中,我們會先介紹 Docker 與容器到底是什麼? 為什麼現在有那麼多專案都會用? 具體來說 Docker 與容器解決了什麼問題? 此外,我們也會透過一個最簡單的案例,讓過去還沒接觸過 Docker 的人能快速開始。
我們把第一篇完整版免費公開,後續的系列文會陸續在 E+ 上架,歡迎感興趣的讀者加入閱讀 (E+ 連結看這邊)。
Docker 與容器是什麼? 為什麼要用 Docker?
相信多數人聽過 Docker 是一套用來建置與執行容器化應用程式的平台與工具,不過容器究竟是什麼? 事實上,容器這個概念與實體世界中會看到的貨櫃很相似,都是像箱子一樣 (在英文上,貨櫃的英文跟容器的英文都是 container,所以很常看到實體貨櫃會出現在 Docker 相關的圖上)。但不同的地方在於,在軟體世界的容器,是裝著應用程式。
在這個箱子中,應用程式會有一套相對獨立的執行環境,包含主機名稱、IP 位址、磁碟機等等。不過這些其實都是由 Docker 創建出來的虛擬資源;透過 Docker 的管理,這些資源能夠被組合成一個讓應用程式得以被執行的環境。
在一台電腦中,多個容器會使用同一個 CPU 與記憶體等硬體資源,並共享底層的作業系統核心。不過,每個容器仍有自己的程序、檔案系統與網路環境,因此容器中的應用程式可以彼此隔離。
Docker 解決了什麼問題?
在看完上面 Docker 實際做的事情後,可能還沒辦法很直觀感受到其價值所在,或者 Docker 這項技術解決了什麼問題,讓我們在這個段落進一步說明。
在上面對於 Docker 的介紹中,有提到容器提供一個讓應用程式得以被執行的環境,這邊的環境是個關鍵。在做軟體開發時,寫程式只是其中一環,要讓程式碼跑起來,會需要有相對應的執行環境。由於使用的機器、安裝套件的版本,以及各種因素的不同,很可能某個專案能在你同事用的電腦跑起來,但是在你的電腦上跑不起來。
過去在沒有使用 Docker 的狀況下,有些人入職新團隊後,光是要讓專案能夠跑起來,就得花很多時間。在安裝環境時遇到問題,去找同事協助解決時,很常會聽到類似以下的話「這個專案的 Node.js 版本要 18,但你裝到 Node.js 22 所以跑不起來」,或是「這個的 Postgres 版本不同,才導致行為的不一致」。
透過容器,我們能把一個應用程式需要的執行環境包起來,讓它可以用相對一致的方式,在不同機器上跑。因此,在使用 Docker 的狀況下,當團隊有新成員加入,要建置、部署、管理專案時,不管用哪一台機器,機器裡的某個依賴是哪個版本,只要透過 Docker,新成員抓下原始碼後,執行一個指令,就能在本機把所有東西建置並跑起來,從此不再擔心要花很多時間建置環境 (備註:前提是團隊已經妥善準備好 Dockerfile、Compose 設定與必要的初始化流程,這些概念我們在後面的文章會談)。
因為這個特性,讓現代的應用程式,可以很輕易地跑在雲端、跑在資料中心,甚至是無伺服器函式 (serverless function) 中。不管應用背後選擇什麼架構或技術棧,都能夠透過 Docker 來建置、部署與管理。
為什麼 Docker 出現前的解決方案會被 Docker 取代?
Docker 容器創建出的執行環境,讓多個應用程式即使背後用的依賴版本不同,也不會有衝突、能同時運行,不會因為兩個應用程式用的 Node.js 版本不同,就無法和平共處。這件事在 Docker 出現前,業界其實已經有技術在解決了。
在 Docker 之前比較廣泛被使用的方法,是透過虛擬機器 (VM)。在概念上,虛擬機器跟容器其實很類似,都是提供一個箱子,讓應用程式能在裡頭執行。不過兩者的差異在於,虛擬機器的箱子中包含作業系統,所以兩個虛擬機器彼此不會共享主機的作業系統。
由於一套作業系統可能就會佔用好幾 GB 的記憶體,也會消耗大量 CPU 時間,不共享作業系統就代表原本能給應用程式使用的資源,被作業系統占據。這就導致同樣的資源,在使用虛擬機器的狀況下,能同時跑的應用程式數量下降。
對比之下,同樣提供隔離環境,由於 Docker 容器會共享執行容器的機器上的作業系統,所以容器本身相對輕量。給定同樣的硬體,能夠執行的應用系統,會比用虛擬機器多不少。
從一個最簡單的案例開始用 Docker
在了解完 Docker 的概念後,接著讓我們一起動手開始使用 Docker。我們會以一個最簡單的案例,帶著還沒有用過 Docker 的讀者入手。完整的講解可以看這篇文章的完整版本 (連結)。
如果對完整的 Docker 入門到實戰系列文感興趣,我們未來會持續在 E+ 中更新後續的內容,歡迎感興趣的讀者加入閱讀 (E+ 連結看這邊)。
備註:許多 E+ 會員透過所任職公司的教育訓練補助 (E+ 會開立有統編的發票),不用花自己的錢,也能每週透過深度主題文與社群交流,用穩扎穩打的方式拓展技術視野、在職涯持續成長。
本期推薦
Coinbase 工程團隊分享的《Interviewing Engineers in the AI Era: Lessons from a Year of Rebuilding》。該文談了在 AI 時代下,Coinbase 工程團隊如何重新打造面試流程。推薦給想了解近期求職市場在面試上有什麼變化的人一讀 (連結)
《Choose Boring Technology》一文談到一個軟體團隊能承擔的新技術其實有限,不需要每個問題都選最新、最特別的工具 (連結)。 文章從維運成本、認知負擔到技術選型談得很完整,如果你正在決定要不要引進新框架、資料庫或服務,這篇提供了一套很不錯用的思考方式
《Build Wide, Ship Narrow》的作者分享他的 AI 驅動開發流程,先把功能完整做出來、實際展示與修正,再回頭拆成容易審查的小型 PR (連結),特別適合平常工作會接觸跨前後端功能或大型重構的人一讀
Google 在《Why Go is an Ideal Language for AI-Assisted Software Engineering》中談到 AI 程式實作讓產生程式碼變快,審查與驗證反而成為瓶頸,以及在這個新瓶頸下,為什麼 Go 語言有優勢 (連結)。 文章從 Go 一致的格式、簡單明確的語法、型別檢查與內建工具,來解析為何 Go AI 更容易閱讀、測試與修正產生出來的程式碼
寫了十年 Go 的 Paul Hinze 在《A Gopher Meets a Crab》中,讓 Claude 幫他用 Rust 與 Tokio 寫一個聊天伺服器,再一邊追問 AI、一邊真正把 Rust 學起來 (連結)
文章從一位初入門 Rust 的工程師角度,談 Rust 的錯誤處理、型別到非同步執行模型與 Go 有什麼不同、《Your JSON Is Lying to You》一文整理了 JavaScript 資料經過 JSON 序列化後可能悄悄改變的情況,包括大整數失去精度、
undefined消失、Date變成字串,以及NaN變成null(連結)。如果平常會設計 API、處理資料庫 ID 或做前後端資料交換,這篇文章能協助釐清「JavaScript 物件」和「送上網路的 JSON」之間到底會遺失哪些資訊《Shopify Speed Optimization: Fixing The Real Bottlenecks》一文拆解 Shopify 商店容易拖慢體感速度的地方 (連結)。從首頁大圖與輪播、第三方 App 腳本,到 JavaScript 延後與條件載入、CSS 與字型都有實例




