AWS國際帳號認證 AWS Lambda 打包依賴庫(Layer)超出 250MB 限制?輕量化與 Docker 部署方案
先看懂 250MB 限制到底限制什麼
AWS Lambda 最常讓人卡關的,不是程式碼本身,而是依賴庫一大,整個打包就超線。很多人第一次遇到這個問題時,直覺是把套件搬到 Layer,結果只是把壓力從主程式轉到 Layer,最後還是撞上 250MB。真正要先釐清的,是 Lambda 的限制不是在看你壓縮檔下載有多小,而是看解壓後的總體積。也就是說,函式程式、所有 Layer、原生動態庫與相關檔案,加起來一旦超過上限,就不能再靠 ZIP 硬上。
不是壓縮後大小,而是解壓後總和
這個差異很重要。你在本機看 ZIP 可能只有幾十 MB,但一旦部署到 Lambda,套件會被解壓到執行環境中,實際占用空間會大很多。尤其是 Python、Node.js、Java 這類常見語言,只要碰到科學計算、影像處理、瀏覽器自動化、資料庫驅動、加密套件,體積就很容易暴增。更麻煩的是,有些套件本身不大,但它依賴的二進位檔、字型、模型檔、共用函式庫才是真正吃空間的主因。
如果你把 Layer 當成萬能收納箱,問題只會越積越多。Layer 的本意是把多個函式共用的依賴抽出來,減少重複打包與維護成本,不是拿來無限制堆肥。當你開始把不相關、不同版本、甚至只有某個功能才會用到的套件都放進 Layer,最後通常會得到一個很難升級、很難追蹤、也很難除錯的部署結構。
為什麼很容易爆掉
會爆的原因其實很現實。第一,第三方套件本來就不輕,像是 pandas、numpy、opencv、scikit-learn、Playwright 這類工具,連同相依檔案一起算,很容易把體積拉高。第二,很多人直接在自己的開發環境打包,忽略了 Linux、x86_64、arm64、glibc 版本差異,最後把不需要的檔案也一併塞進去。第三,專案常常長期演進,功能越加越多,舊依賴卻沒清,半年後回頭看,連自己都不知道哪些套件還在被使用。
AWS國際帳號認證 所以,遇到 250MB 問題時,不要先問「能不能再加一個 Layer」。正確的問題應該是:這些依賴真的都需要嗎?它們是否一定要和函式一起部署?是否有更小的替代方案?有沒有可能把某些重量級工作移到其他服務?只要問題問對,解法通常會清楚很多。
第一步:先做輕量化,不要一開始就換架構
很多團隊一遇到限制,就急著換成容器或其他平台,但其實多數案例先做輕量化,就已經能解掉一大半問題。原因很簡單:真正超重的,往往不是業務邏輯,而是依賴清單太髒、打包方式太鬆、以及開發和部署流程沒有分開。
把真正沒用的東西清掉
先檢查依賴清單,這一步最值錢。很多專案在安裝時把測試工具、開發工具、文件、範例、語言包、除錯工具一起打包進去,這些東西在本機有用,上線卻完全不需要。對 Python 來說,常見做法是把正式環境與開發環境分開,部署時只保留 production 需要的套件。對 Node.js 來說,則要確保 devDependencies 沒被帶上去,並且在建置階段先做 tree shaking、bundle size 分析,把沒用到的程式碼砍掉。
- 移除測試套件、lint 工具與開發相依。
- 檢查是否有重複套件或舊版本殘留。
- AWS國際帳號認證 刪掉文件、範例、快取、暫存檔與無關資源。
- AWS國際帳號認證 只保留實際會在 Lambda 執行時用到的檔案。
這一步看起來很普通,但常常最有效。很多時候,你不是缺少部署方案,而是缺少一次認真整理專案的機會。
用更小的安裝方式
如果是 Python,安裝依賴時盡量避免把快取和多餘資訊一起裝進去。能用二進位輪子就不要現場編譯,能指定平台就不要用本機雜湊版本。若你是從 Mac 或 Windows 打包到 Linux Lambda,更要確認安裝目標環境一致,不然不只體積變大,還可能直接無法執行。
pip install --no-cache-dir -r requirements.txt -t python
這類做法的重點,不是只看指令漂亮,而是確保安裝結果真的乾淨。對於有原生模組的套件,還可以進一步考慮使用更輕的替代品,或改成只安裝必要功能,不要把整包完整套件帶上去。很多專案其實只用到影像讀寫、CSV 處理、簡單數學運算,卻把整個大而全的庫全裝了,這很容易超標。
如果是 Node.js,除了減少依賴,還應該把程式入口打包成單一檔案,讓 bundler 幫你裁掉沒用到的模組。再配合壓縮與 source map 控制,就能把很多原本看起來很大的專案,壓到可接受範圍內。Java 則可以從瘦身 JAR、移除不必要的 framework、減少資源檔與測試依賴著手。原則都一樣:只帶執行所需的最小集合。
把共享依賴和功能程式分開
如果多個 Lambda 會共用某些基礎庫,可以把這些共用部分放到 Layer,讓主程式只留下業務邏輯。這樣不但能減少每個函式的重複體積,更新時也比較有秩序。只是要記住,Layer 適合放穩定、共通、版本相對固定的內容,不適合放常變、常實驗、常增長的內容。因為一旦 Layer 改動,所有依賴它的函式都會被牽動,部署風險反而上升。
Layer 的正確用法:共享,而不是堆砌
Layer 的優點是清楚。它可以把共同依賴抽離,讓函式本體更專注,也能縮短某些函式的重複部署時間。但 Layer 的缺點也很明白:數量有限、版本管理需要紀律、內容一大就難以維護。當你把 Layer 用成第二個倉庫,問題就開始了。
什麼適合放 Layer
- 多個函式共同使用、版本穩定的工具庫。
- 程式語言執行環境需要的輔助套件。
- 跨專案一致的內部通用模組。
- 變動頻率低、但每個函式都會用到的基礎功能。
什麼不適合放 Layer
- 某個功能才會用到的大型套件。
- 快速迭代、版本常改的第三方工具。
- 含大量靜態檔、模型檔、字型或資源檔的內容。
- 只為了省事而硬塞進去的臨時依賴。
如果你的 Layer 已經接近上限,或每次更新都要重新整理一堆不相關的內容,那就代表 Layer 的使用方式出了問題。正確做法不是再多加一層,而是回頭檢查職責是否劃分清楚。每個 Layer 都應該有明確用途,最好能用一句話說明它的存在理由。說不清楚的 Layer,通常也很難維護。
什麼時候該改用 Docker 容器
當你的依賴已經不是靠瘦身可以解決,而是本身就很大、很雜、而且編譯環境又複雜時,Docker 容器部署就會是比較務實的選擇。AWS Lambda 的容器映像支援更大的容量,適合那些需要大量原生庫、瀏覽器執行環境、機器學習模型、或特殊系統工具的工作負載。這時候你不必再和 ZIP 與 Layer 的體積限制硬碰硬,而是直接把運行環境封裝成鏡像。
適合容器的場景
- 需要大型原生依賴,例如影像處理、音訊轉碼、PDF 處理。
- 需要安裝系統套件、字型、瀏覽器或底層工具。
- 需要固定 Linux 環境,避免本機與線上差異。
- 應用依賴複雜,傳統 ZIP 打包已經難以維持。
容器最大的好處,是你可以把整個執行環境寫成可重複建置的流程。只要 Dockerfile 一樣,任何人都能在本機或 CI 中重建同樣的環境,這對團隊合作非常有幫助。以前那種「我本機可以、你那邊不行」的問題,也會少很多。
AWS國際帳號認證 容器不代表可以隨便塞
不過,改成 Docker 不代表就能不做整理。很多人一轉到容器,就覺得反正有 10GB 可用,於是開始把所有東西全裝進去,最後得到一個巨大、更新慢、啟動慢的映像。這種做法只是在換地方放垃圾,問題沒有消失,只是改了容器而已。
容器部署真正的重點,是把建置階段和執行階段分開。建置階段可以用較完整的環境編譯、安裝、打包;執行階段則只放最終需要的檔案。這樣可以大幅縮小映像體積,也能降低攻擊面。再搭配 .dockerignore 排除不必要的檔案,通常就能把映像縮到很合理的大小。
一個實用的容器思路
如果你用的是 Lambda 容器映像,可以把流程想成三件事:先在 builder 階段安裝依賴並完成編譯,再把產物複製到乾淨的 runtime 映像,最後只保留入口程式與必要資源。這樣做的目的不是炫技,而是讓部署內容可控、可預測、可維護。
builder 階段:安裝依賴、編譯原生模組、產出執行檔
runtime 階段:只保留實際需要的執行內容
部署階段:推送映像到託管倉庫,再由 Lambda 取用
如果團隊還在用傳統 ZIP,常常會遇到「本機裝得過去,CI 失敗;CI 過了,上線又爆掉」的情況。容器化後,至少可以把這些不確定性降到很低。對需要多人協作的專案來說,這種穩定性本身就很有價值。
ZIP、Layer、Docker,怎麼選才合理
沒有一種方案永遠最強,只有最適合當下情境的方案。你要看的不是流行什麼,而是你的依賴有多重、團隊能否維護、部署頻率多高、以及未來是否容易擴充。
- 如果應用很小,依賴少,直接 ZIP 就夠了。
- 如果多個函式共用一組穩定依賴,Layer 最方便。
- 如果依賴庫已經逼近或超過 250MB,Docker 容器通常更實際。
- 如果是瀏覽器自動化、ML 推論、影像與音訊處理,容器幾乎是首選。
- 如果工作本身已經不像短任務,可能要考慮 ECS、Fargate、EC2 或其他服務。
很多團隊會卡在一個誤區:覺得一定要把所有事情都塞在 Lambda 裡。其實 Lambda 很適合事件驅動、短時間、彈性高的任務,但它不是萬能。當你的需求開始偏向長時間運算、重依賴環境、或大量系統級工具時,硬留在 Lambda,維護成本通常比直接換方案還高。
上線前一定要做的檢查清單
不管你最後選的是 Layer 還是 Docker,上線前都應該做一輪完整檢查。這些看似瑣碎的步驟,往往能幫你避免最常見的事故。
- 確認部署後的實際解壓大小,而不是只看壓縮檔大小。
- 檢查是否有多餘的測試檔、文件、快取與編譯殘留。
- 確認依賴版本一致,沒有把本機環境的東西誤帶上去。
- 觀察冷啟動時間,避免體積變小但啟動反而變慢。
- 定期更新依賴,避免舊版庫越堆越多。
- 如果使用容器,記得同步檢查映像安全性與重建流程。
最後要記住一件事:打包超過 250MB,通常不是單一技術問題,而是設計、依賴管理和部署習慣一起造成的。真正成熟的做法,不是找一個更大的袋子把東西裝起來,而是先把不需要的東西拿掉,再決定剩下的內容要放在哪裡。先輕量化,再判斷是否改用容器,這樣你會更快找到穩定又長久的解法。
如果你現在正被 Lambda 的 Layer 卡住,建議不要急著改架構。先看依賴清單、再看打包流程、接著評估 Layer 是否真的有價值。當你把專案整理到一定程度後,很多看似無解的 250MB 限制,其實會自動縮小成一個很可控的工程問題。到那時候,不論你最後選 ZIP、Layer,還是 Docker,都會更清楚自己在做什麼,也更能掌握上線風險。

