ഒരു ജൂനിയർ ഡെവലപ്പർ ഒരു Python Docker ഇമേജിന്റെ വലിപ്പം 1.2 GB-യിൽ നിന്ന് 85 MB ആയി കുറച്ചു, ഇത് CI പൈപ്പ്‌ലൈൻ സമയം 11 മിനിറ്റിൽ നിന്ന് 90 സെക്കൻഡായി കുറയ്ക്കാൻ സഹായിച്ചു. ചെറിയ ഇമേജുകൾ വേഗത്തിൽ ഡൗൺലോഡ് ചെയ്യാനും, സംഭരിക്കാൻ കുറഞ്ഞ ചിലവ് മതിയാകാനും, സുരക്ഷാ പിഴവുകൾ കുറയ്ക്കാനും സഹായിക്കുന്നു.

ഇമേജ് വലിപ്പം പ്രധാനമാകുന്നത് എന്തുകൊണ്ട്

ഓരോ തവണ ഒരു കണ്ടെയ്നർ പൾ ചെയ്യുമ്പോഴും, രജിസ്ട്രി മുഴുവൻ ഇമേജും സ്ട്രീം ചെയ്യുന്നു. ഒരു 85 MB ലെയർ സെക്കൻഡുകൾക്കുള്ളിൽ ലഭിക്കും; എന്നാൽ ഒരു 1.2 GB ലെയർ സാധാരണ നെറ്റ്‌വർക്കിൽ മിനിറ്റുകൾ എടുത്തേക്കാം. ബിൽഡ് ഏജന്റുകൾ മുഴുവൻ ഇമേജും അപ്‌ലോഡ് ചെയ്യുകയും കാഷെ (cache) ചെയ്യുകയും വേണം, ഇത് CI സമയവും ക്ലൗഡ് സ്റ്റോറേജ് ബില്ലും വർദ്ധിപ്പിക്കുന്നു. ഓരോ അധിക പാക്കേജും ഒരു സുരക്ഷാ ഭീഷണിക്ക് കാരണമായേക്കാം, അതിനാൽ ബേസ് ഇമേജ് കുറയ്ക്കുന്നത് അറ്റാക്ക് സർഫസ് (attack surface) കുറയ്ക്കാൻ സഹായിക്കുന്നു.

ഇമേജ് വലിപ്പം കൂടാൻ കാരണങ്ങൾ

  • ആപ്പ് പ്രവർത്തിക്കുന്ന അതേ സ്റ്റേജിൽ ഇൻസ്റ്റാൾ ചെയ്താൽ gcc പോലുള്ള ബിൽഡ് ടൂളുകൾ ഫൈനൽ ഇമേജിൽ അവശേഷിക്കും.
  • പാക്കേജ് മാനേജർ കാഷെകൾ (ഉദാഹരണത്തിന് apt അല്ലെങ്കിൽ pip കാഷെകൾ) ഡിസ്കിൽ ഇരിക്കുകയും ഡിഫോൾട്ട് ആയി ക്ലീൻ ചെയ്യപ്പെടാതിരിക്കുകയും ചെയ്യുന്നു.
  • ഓരോ RUN ഇൻസ്ട്രക്ഷനും പുതിയൊരു റീഡ്-ഒൺലി (read-only) ലെയർ സൃഷ്ടിക്കുന്നു; ലെയറുകൾക്കിടയിലുള്ള ഡ്യൂപ്ലിക്കേറ്റ് ഫയലുകൾ വലിപ്പം കൂട്ടുന്നു.
  • ubuntu:latest പോലുള്ള വലിയ ബേസ് ഇമേജുകൾ ഒരു പൂർണ്ണമായ OS-ഉം വരുന്നു, ഇത് ഒരു മിനിമൽ Python റൺടൈമിന് ആവശ്യമുള്ളതിനേക്കാൾ വളരെ കൂടുതലാണ്.

മൂന്ന് ഘട്ടങ്ങളിലൂടെയുള്ള വലിപ്പം കുറയ്ക്കൽ

ഘട്ടം ബേസ് ഇമേജ് ബിൽഡ് രീതി ഫലം (വലിപ്പം)
1 Standard Python (full) Single stage, എല്ലാ ടൂളുകളും ഉൾപ്പെടുന്നു 1.18 GB
2 python:slim Multi-stage: gcc ഉള്ള builder, ഫൈനൽ സ്റ്റേജിൽ കംപൈൽ ചെയ്ത പാക്കേജുകൾ മാത്രം 210 MB
3 python:alpine Alpine Linux-ൽ മൾട്ടി-സ്റ്റേജ് രീതി (ഇത് വളരെ ചെറുതാണ്) 85 MB

ഘട്ടം 1 – അടിസ്ഥാന നില (baseline)

ഡിഫോൾട്ട് Python ഇമേജിൽ നിന്ന് തുടങ്ങിയപ്പോൾ, ഡെവലപ്പർക്ക് 1.18 GB വലിപ്പമുള്ള ഒരു ആർട്ടീഫാക്റ്റ് ലഭിച്ചു. ഈ ഇമേജിൽ മുഴുവൻ Debian സ്റ്റാക്കും, ഡെവലപ്‌മെന്റ് ഹെഡറുകളും, pip കാഷെയും അടങ്ങിയിരുന്നു.

ഘട്ടം 2 – ബിൽഡർ ഉപയോഗിച്ചുള്ള slim രീതി

python:slim-ലേക്ക് മാറിയപ്പോൾ OS-ന്റെ വലിപ്പം കുറഞ്ഞെങ്കിലും ബിൽഡ് ടൂളുകൾ അവിടെത്തന്നെ ഉണ്ടായിരുന്നു. ഒരു builder സ്റ്റേജ് ഉപയോഗിച്ചതിലൂടെ gcc, make, മറ്റ് കംപൈൽ ടൈം ഡിപെൻഡൻസികൾ എന്നിവ ഇൻസ്റ്റാൾ ചെയ്യാനും കംപൈൽ ചെയ്യാനും, അതിനുശേഷം അവ നീക്കം ചെയ്യാനും സാധിച്ചു. ഫൈനൽ സ്റ്റേജിൽ COPY --from=builder ഉപയോഗിച്ച് കംപൈൽ ചെയ്ത വീൽസുകളും (wheels) റൺടൈം ഫയലുകളും മാത്രം എടുത്തതോടെ വലിപ്പം 210 MB ആയി കുറഞ്ഞു.

ഘട്ടം 3 – Alpine മികച്ചതാണ്

musl libc, busybox എന്നിവയിലാണ് Alpine Linux നിർമ്മിച്ചിരിക്കുന്നത്. Alpine-ൽ മൾട്ടി-സ്റ്റേജ് രീതി ആവർത്തിച്ചപ്പോൾ 85 MB വലിപ്പമുള്ള ഒരു ഇമേജ് ലഭിച്ചു—ഇത് യഥാർത്ഥ വലിപ്പത്തേക്കാൾ 93% കുറവാണ്. Kubernetes സെക്കൻഡുകൾക്കുള്ളിൽ ഇമേജ് പൾ ചെയ്തതായും CI ജോബ് 90 സെക്കൻഡിൽ പൂർത്തിയായതായും ഡെവലപ്പർ നിരീക്ഷിച്ചു.

പ്രായോഗികമായ സ്വാധീനം

  • കുറഞ്ഞ സ്റ്റോറേജ് ചിലവ് – രജിസ്ട്രി സ്റ്റോറേജ് കുറയുന്നു.
  • മെച്ചപ്പെട്ട സുരക്ഷ – പാക്കേജുകൾ കുറയുന്നത് ട്രാക്ക് ചെയ്യേണ്ട CVE-കളുടെ എണ്ണം കുറയ്ക്കുന്നു. Alpine ഇമേജിൽ Python റൺടൈമും ആപ്ലിക്കേഷൻ കോഡും മാത്രമേ അടങ്ങിയിട്ടുള്ളൂ.
  • വേഗത്തിലുള്ള CI – പൈപ്പ്‌ലൈൻ സമയം 11 മിനിറ്റിൽ നിന്ന് 90 സെക്കൻഡായി കുറഞ്ഞു.

Dockerfile വലിപ്പം കുറയ്ക്കാൻ ചില പ്രായോഗിക നിർദ്ദേശങ്ങൾ

  • :latest ടാഗുകൾ ഒഴിവാക്കുക; നിങ്ങളുടെ ആവശ്യങ്ങൾക്കനുസരിച്ചുള്ള :slim അല്ലെങ്കിൽ :alpine വേരിയന്റുകൾ തിരഞ്ഞെടുക്കുക.
  • മൾട്ടി-സ്റ്റേജ് ബിൽഡുകൾ ഉപയോഗിക്കുക: കംപൈലേഷനായി ഒരു പ്രത്യേക builder സ്റ്റേജും, നിങ്ങൾക്ക് ആവശ്യമുള്ള ആർട്ടീഫാക്റ്റുകൾ മാത്രം സ്വീകരിക്കുന്ന ഒരു runtime സ്റ്റേജും ഉപയോഗിക്കുക.
  • COPY --from=builder /path/to/installed /path/in/final ഉപയോഗിച്ച് ആവശ്യമായവ മാത്രം കോപ്പി ചെയ്യുക.
  • ഡിപെൻഡൻസി ഇൻസ്റ്റാളേഷൻ സോഴ്സ് കോഡ് കോപ്പി ചെയ്യുന്നതിന് മുമ്പ് നടത്തുന്ന രീതിയിൽ കമാൻഡുകൾ ക്രമീകരിക്കുക; ഇത് ലെയർ കാഷിംഗ് (layer caching) പരമാവധി പ്രയോജനപ്പെടുത്താൻ സഹായിക്കും.
  • കാഷെകൾ വ്യക്തമായി ക്ലീൻ ചെയ്യുക, ഉദാഹരണത്തിന്: rm -rf /var/lib/apt/lists/* ~/.cache/pip.

നിങ്ങൾ Alpine ഉപയോഗിക്കുകയാണെങ്കിൽ, ആപ്പിന് DNS റെസല്യൂഷൻ പ്രശ്നങ്ങൾ ഉണ്ടാകുമ്പോൾ nss പാക്കേജ് ചേർക്കുക. pip ഉപയോഗിച്ച് ഇൻസ്റ്റാൾ ചെയ്യുമ്പോൾ, ലോക്കലായി ഇൻസ്റ്റാൾ ചെയ്ത സ്ക്രിപ്റ്റുകൾ റൺടൈമിൽ കണ്ടെത്താൻ PATH-ൽ /root/.local/bin ചേർക്കുക.

ശ്രദ്ധിക്കേണ്ട കാര്യങ്ങൾ

glibc-ന് വേണ്ടി കംപൈൽ ചെയ്ത ബൈനറി വീൽസുകളുമായി (binary wheels) Alpine-ന്റെ musl libc ഏറ്റുമുട്ടാൻ സാധ്യതയുണ്ട്, ഇത് റൺടൈം എററുകൾക്ക് കാരണമായേക്കാം. അത്തരം സാഹചര്യങ്ങളിൽ Alpine ബിൽഡറിനുള്ളിൽ തന്നെ വീൽസുകൾ റീബിൽഡ് ചെയ്യുകയോ അല്ലെങ്കിൽ slim ബേസിലേക്ക് മാറുന്നതോ ആണ് നല്ലത്. DNS വിശ്വാസ്യതയ്ക്കായി nss പാക്കേജ് ഉപയോഗിക്കുന്നത് ചെറിയൊരു ചിലവ് മാത്രമാണ്.

അടുത്തതായി ശ്രദ്ധിക്കേണ്ടവ

  • മൾട്ടി-സ്റ്റേജ് റീറൈറ്റിംഗിന് അനുയോജ്യമായ വലിയ ലെയറുകൾക്കായി നിങ്ങളുടെ നിലവിലുള്ള ഇമേജുകൾ പരിശോധിക്കുക.
  • ഇമേജ് വലിപ്പം തിരിച്ചറിയാൻ അപ്‌ലോഡ്, ഡൗൺലോഡ് സമയങ്ങൾക്കായി CI ലോഗുകൾ നിരീക്ഷിക്കുക.
  • നിങ്ങൾ തിരഞ്ഞെടുക്കുന്ന ബേസ് ഡിസ്ട്രിബ്യൂഷന്റെ സുരക്ഷാ റിപ്പോർട്ടുകൾ ശ്രദ്ധിക്കുക.

പാഠം വ്യക്തമാണ്: കൃത്യമായ ഒരു Dockerfile, ഭാരം കുറഞ്ഞ ഒരു ബേസ്, ഒരു ബിൽഡർ സ്റ്റേജ് എന്നിവ ഉപയോഗിച്ച് ഒരു Python ഇമേജിന്റെ വലിപ്പം ഗണ്യമായി കുറയ്ക്കാൻ സാധിക്കും. ഇത് പ്രവർത്തനക്ഷമതയിൽ മാറ്റം വരുത്താതെ തന്നെ വേഗതയും ചിലവ് കുറയ്ക്കാനും സഹായിക്കുന്നു.