iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0

身為一個寫 Python 腳本的工程師,大家應該都有這種經驗:
你在本地端 pip install requests 跑得好好的,拍胸脯說穩了。結果程式丟到 AWS Lambda 一跑,馬上冒出一個 import error,瞬間彷彿聽到老天爺在笑你:「哼,太天真了吧。」

在 Lambda 裡面要用 Python 套件,規矩超嚴格:程式碼 + 相依套件,全部乖乖打包成一顆 ZIP,才能上台表演。更刺激的是,這包 ZIP 檔案體重還不能超過 250MB,否則 Lambda 會直接跟你說「抱歉,本場不收超重行李」。

更慘的還在後頭:你只是改了兩行小程式,結果還是得重新打包、壓縮、上傳,搞到最後,你的日常不是在跟 Bug 打仗,而是變成「壓縮大師」。一天工作八小時,有六小時都在等壓縮條跑完,人生徹底走偏。

就在你懷疑自己是不是轉職去物流業比較快時,AWS Lambda Layer 帶著聖光降臨了。它就像 Uber Eats 外送員一樣,把套件乾乾淨淨打包好,直接送到 Lambda 手上。從此以後,你不用每天揹著整家便利商店去上班,終於可以專心寫程式,而不是扛套件。

為什麼要用 Layer?(工程師的理智救星)

不想用 Layer 的理由可以千奇百怪:懶得學、嫌麻煩、覺得 zip 打包是修行的一部分……但說真的,Layer 至少有幾個好處,讓人用過就回不去。

  1. 減少重複打包
    你有十個 Lambda function,都要 requests。結果你乖乖打包了十次,硬碟爆哭、打包的空間也跟著掉眼淚,你的 CI/CD pipeline 更是一路塞車到環狀線。Layer 出來之後,直接一次打包,全場共享,乾淨俐落,工程師的背痛指數瞬間下降。
  2. 統一版本控管
    團隊裡總有一位考古學家,還堅守在 Python 2.7 的遺跡裡。用了 Layer,大家只能乖乖用同一個版本,再也沒人能拿「我本地跑得好好的啊!」這句經典台詞來搪塞。
  3. 部署速度快
    有了 Layer,你只需要更新程式,不用每次都把整個套件包進去。CI/CD pipeline 從原本 20 分鐘的「咖啡跑完還能去拉個筋」,直接縮短成 2 分鐘「剛打開 IG 還沒滑完第一張貓咪照」。老闆還可能誤以為你升級成了 10 倍速工程師(但連兩倍的薪水都絕對不會發)。
  4. 程式與套件分工清楚
    程式碼就寫邏輯,套件就乖乖放 Layer。從此檔案結構乾淨到可以拿去當房仲廣告:「這個專案乾淨到像新成屋」。不會再出現「我到底要從 2000 行程式碼裡挑哪一行才是我的業務邏輯」的絕望場景。

Layer 怎麼運作?(AWS 背後的小魔法)

說穿了,Layer 就是一個「額外的資料夾」,AWS Lambda 執行時會自動幫你把這個資料夾加到 PYTHONPATH 裡。

換句話說,只要你乖乖把套件丟進正確的資料夾(名字還要乖乖叫 python/),Lambda 執行的時候就會像在本地端一樣輕鬆 import

一句話總結:Layer 就是共用的外掛倉庫

動手建立一個 Python Layer

在開始之前,先來一個小提醒:AWS Lambda 的執行環境其實是 Linux。意思就是——如果你在 Windows 或 Mac 上面直接亂包,八成會遇到「本地跑得好好的,丟到 Lambda 就不能用」的經典災情。要避免這種「異地相依套件水土不服症候群」,乖乖找一個 Linux 環境才是王道。

問題來了:手邊有 Linux 的人少之又少(工程師筆電 80% 都是 Mac,剩下的 Windows,多半是公司發的)。那怎麼辦?方法大概有三:

  1. AWS 開一台 Linux EC2:簡單粗暴,但荷包會哭。
  2. 自己搞台 Linux 機器:不常見,除非你是開發順便當 NAS 管家的怪人。
  3. Docker:本地直接模擬環境,不用真的切系統,裝好就能用。

以正常人(懶人)的角度來看,Docker 幾乎是最方便的選擇。唯一的麻煩就是:你得先安裝 Docker。對,這件事對某些人來說比學 Kubernetes 還難。

好啦,這邊用 Docker 來示範(安裝的部分就不在我們這次的主題內了請自行處理)。

步驟 1:建立目錄 & requirements.txt

先在本機建立一個目錄來放 Layer:

mkdir -p C:\docker_spaces\docker-layer\my-layer

然後在裡面建一個 requirements.txt,內容假設我們只要 pillowrequirements.txt的內容就如下:

pillow

目錄結構長這樣:

└─my-layer
        requirements.txt

步驟 2:用 Docker 打包

接著開啟 Windows 的 CMD,cd 到這個目錄:

cd C:\docker_spaces\docker-layer\my-layer

然後執行 Docker 指令,模擬一個跟 Lambda 一樣的 Python 環境來安裝套件。
檔案路徑: C:\docker_spaces\docker-layer\my-layer
Python: 3.13 (這裡要跟 Lambda 的 Runtime 版本一致)

docker run -v C:\docker_spaces\docker-layer\my-layer:/var/task "public.ecr.aws/sam/build-python3.13" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.13/site-packages/; zip -r layer.zip python; exit"

執行過程,大概就像以下這樣:

c:\docker_spaces\docker-layer\my-layer>docker run -v C:\docker_spaces\docker-layer\my-layer:/var/task "public.ecr.aws/sam/build-python3.13" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.13/site-packages/; zip -r layer.zip python; exit"
Collecting pillow (from -r requirements.txt (line 1))
  Downloading pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (9.0 kB)
Downloading pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (6.6 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.6/6.6 MB 17.6 MB/s eta 0:00:00
Installing collected packages: pillow
Successfully installed pillow-11.3.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.

[notice] A new release of pip is available: 25.1.1 -> 25.2
[notice] To update, run: pip install --upgrade pip
  adding: python/ (stored 0%)
  adding: python/lib/ (stored 0%)
  adding: python/lib/python3.13/ (stored 0%)
  adding: python/lib/python3.13/site-packages/ (stored 0%)
  adding: python/lib/python3.13/site-packages/PIL/ (stored 0%)
  adding: python/lib/python3.13/site-packages/PIL/AvifImagePlugin.py (deflated 68%)
  adding: python/lib/python3.13/site-packages/PIL/BdfFontFile.py (deflated 59%)
  adding: python/lib/python3.13/site-packages/PIL/BlpImagePlugin.py (deflated 76%)
  ....
  ....
  ....
c:\docker_spaces\docker-layer\my-layer>

跑完之後,如果沒有紅字 error,你會在目錄下看到一個 layer.zip。如果你想換檔名,只要在上面指令改掉 layer.zip 就行。

步驟 3:確認檔案結構

別急著喝咖啡,先解開 ZIP 看看裡面的結構有沒有長對:

└─python
    └─lib
        └─python3.13
            └─site-packages
                ├─PIL
                │  └─__pycache__
                ├─pillow-11.3.0.dist-info
                │  └─licenses
                └─pillow.libs

如果跟上面差不多,恭喜你,Layer 已經打包成功。

上傳 Layer 到 Lambda

接下來就要把剛剛的成果獻祭給 AWS Lambda。

進 Lambda Console → 點 LayersCreate Layer
https://ithelp.ithome.com.tw/upload/images/20251003/201410719SSjTaB1iw.png

相關資訊的補充

  1. 幫 Layer 取名字,建議加上 Python 版本跟套件名稱,例如 py313-pillow。注意:名稱裡不能有 .,UI 會兇你。
  2. 選擇upload zip file,點選 Choose file 上傳剛剛的 layer.zip
  3. Compatible architectures → 選 x86_64(除非你真的在玩 ARM)。
  4. Compatible Runtimes → 勾上 python3.13。這兩項資訊的填入,有助於我們之後在選擇套件時,可以更快速地找到可用的套件。
  5. 最後按下右下角的 Create
    https://ithelp.ithome.com.tw/upload/images/20251003/20141071dPMXV9u1AK.png

完成後你會看到 Layer 的資訊,包含名稱、版本、支援架構跟 runtime,這就代表你正式成功了。
https://ithelp.ithome.com.tw/upload/images/20251003/20141071mgHKFepKPq.png

到這裡就整個完成了一個layer的建立,有成功的建立嗎?因為下一篇教學會用到哦!如果不成功的話,多試幾次就成功了。

使用 Layer 的小眉角

最後補幾個「過來人血淚」:

  • 版本控管:每次更新 Layer 都是新版本 → Lambda function 必須重新指定,否則還會繼續吃舊的。
  • 大小限制:單一 Layer 不能超過 250MB。千萬不要腦衝把整個 node_modules 丟進 Python Layer,AWS 會直接打槍。
  • 分工合作:建議一個 Layer 放一類套件(像 ML 套件 / Web 套件),比較好管理,也不會變成一坨肥 Layer。

參考資料:


上一篇
Day 22 - 讓 EC2 準時上下班,不再加班爆肝:EventBridge + Lambda 自動開關機指南
下一篇
Day 24 - 打造自動影像縮圖工廠
系列文
最適合小型工作室精打細算的服務使用法25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言