એક જુનિયર ડેવલપરે Python Docker ઇમેજને 1.2 GB થી ઘટાડીને 85 MB કરી દીધી, જેનાથી CI પાઇપલાઇનનો સમય 11 મિનિટથી ઘટીને 90 સેકન્ડ થઈ ગયો. નાની ઇમેજ ઝડપથી ડાઉનલોડ થાય છે, સ્ટોરેજ ખર્ચ ઓછો કરે છે અને સુરક્ષાની ખામીઓ (security flaws) પણ ઓછી દર્શાવે છે.

ઇમેજ સાઈઝ શા માટે મહત્વની છે

જ્યારે પણ કન્ટેનર પુલ (pull) કરવામાં આવે છે, ત્યારે રજિસ્ટ્રી આખી ઇમેજ સ્ટ્રીમ કરે છે. 85 MB લેયર સેકન્ડોમાં આવી જાય છે; જ્યારે 1.2 GB લેયરને સામાન્ય નેટવર્ક પર આવતા મિનિટો લાગી શકે છે. બિલ્ડ એજન્ટ્સને આખી ઇમેજ અપલોડ અને કેશ (cache) પણ કરવી પડે છે, જેનાથી CI સમય અને ક્લાઉડ-સ્ટોરેજ બિલ વધે છે. દરેક વધારાનું પેકેજ એક સંભવિત નબળાઈ (vulnerability) હોઈ શકે છે, તેથી બેઝ (base) ને ટ્રીમ કરવાથી એટેક સરફેસ (attack surface) ઘટે છે.

વધારાનો કચરો (bloat) ક્યાંથી આવે છે

  • gcc જેવા બિલ્ડ ટૂલ્સ ફાઈનલ ઇમેજમાં રહી જાય છે જો તેઓ તે જ સ્ટેજમાં ઇન્સ્ટોલ કરવામાં આવ્યા હોય જેમાં એપ ચાલે છે.
  • પેકેજ-મેનેજર કેશ (દા.ત., apt અથવા pip કેશ) ડિસ્ક પર રહે છે અને ડિફોલ્ટ રીતે ક્યારેય સાફ કરવામાં આવતી નથી.
  • દરેક RUN ઇન્સ્ટ્રક્શન એક નવું રીડ-ઓન્લી (read-only) લેયર બનાવે છે; લેયર્સ વચ્ચે ડુપ્લીકેટ ફાઇલોનો જથ્થો વધી જાય છે.
  • ubuntu:latest જેવી મોટી બેઝ ઇમેજ સાથે આખું OS આવે છે, જે મિનિમલ Python રનટાઇમની જરૂરિયાત કરતા ઘણું વધારે છે.

ત્રણ-સ્ટેપમાં ઘટાડો

સ્ટેપ બેઝ ઇમેજ બિલ્ડ એપ્રોચ પરિણામી સાઈઝ
1 સ્ટાન્ડર્ડ Python (ફુલ) સિંગલ સ્ટેજ, બધા ટૂલ્સ હાજર 1.18 GB
2 python:slim મલ્ટી-સ્ટેજ: gcc સાથે બિલ્ડર, ફાઈનલ સ્ટેજ ફક્ત કમ્પાઈલ કરેલા પેકેજ કોપી કરે છે 210 MB
3 python:alpine Alpine Linux પર મલ્ટી-સ્ટેજ, જે પોતે જ ખૂબ નાનું છે 85 MB

સ્ટેપ 1 – બેઝલાઇન

ડિફોલ્ટ Python ઇમેજથી શરૂઆત કરતા, ડેવલપરે 1.18 GB ની આર્ટિફેક્ટ (artifact) જોઈ. ઇમેજમાં આખું Debian સ્ટેક, ડેવલપમેન્ટ હેડર્સ અને pip કેશ સામેલ હતા.

સ્ટેપ 2 – બિલ્ડર સાથે slim

python:slim પર સ્વિચ કરવાથી OS નો ફૂટપ્રિન્ટ ઘટી ગયો, પરંતુ બિલ્ડ ટૂલ્સ તો રહ્યા જ. એક builder સ્ટેજ ઉમેરવાથી gcc, make અને અન્ય કમ્પાઈલ-ટાઇમ ડિપેન્ડન્સીઝ ઇન્સ્ટોલ, કમ્પાઈલ અને પછી દૂર કરી શકાય છે. ફાઈનલ સ્ટેજમાં ફક્ત કમ્પાઈલ કરેલા wheels અને રનટાઇમ ફાઇલો મેળવવા માટે COPY --from=builder નો ઉપયોગ કરવામાં આવ્યો, જેનાથી સાઈઝ ઘટીને 210 MB થઈ ગઈ.

સ્ટેપ 3 – Alpine વિજેતા

Alpine Linux એ musl libc અને busybox પર બનેલું છે. Alpine પર મલ્ટી-સ્ટેજ પેટર્નનું પુનરાવર્તન કરવાથી 85 MB ની ઇમેજ મળી—જે મૂળ ઇમેજ કરતા 93% ઘટાડો છે. ડેવલપરે નોંધ્યું કે Kubernetes એ સેકન્ડોમાં ઇમેજ પુલ કરી લીધી અને CI જોબ 90 સેકન્ડમાં પૂર્ણ થઈ ગઈ.

વાસ્તવિક દુનિયા પર અસર

  • ઓછો સ્ટોરેજ ખર્ચ – રજિસ્ટ્રી સ્ટોરેજ ઘટે છે.
  • સુધારેલી સુરક્ષા – ઓછા પેકેજનો અર્થ છે ટ્રેક કરવા માટે ઓછા CVEs. Alpine ઇમેજમાં ફક્ત Python રનટાઇમ અને એપ્લિકેશન કોડ હોય છે.
  • ઝડપી CI – પાઇપલાઇનનો રનટાઇમ 11 મિનિટથી ઘટીને 90 સેકન્ડ થઈ ગયો.

તમારા Dockerfile ને ટ્રીમ કરવા માટે વ્યવહારુ ટિપ્સ

  • :latest ટેગ્સ ટાળો; તમારી જરૂરિયાત મુજબ :slim અથવા :alpine વેરિઅન્ટ્સ પસંદ કરો.
  • મલ્ટી-સ્ટેજ બિલ્ડ્સનો ઉપયોગ કરો: કમ્પાઈલેશન માટે સમર્પિત builder સ્ટેજ, અને runtime સ્ટેજ જે ફક્ત તમને ખરેખર જરૂરી આર્ટિફેક્ટ્સ જ મેળવે.
  • COPY --from=builder /path/to/installed /path/in/final સાથે પસંદગીપૂર્વક કોપી કરો.
  • કમાન્ડ્સનો ક્રમ એવી રીતે રાખો કે ડિપેન્ડન્સી ઇન્સ્ટોલેશન સોર્સ કોડ કોપી કરતા પહેલા ચાલે; આ લેયર કેશિંગને મહત્તમ બનાવે છે.
  • કેશને સ્પષ્ટપણે સાફ કરો, દા.ત., rm -rf /var/lib/apt/lists/* ~/.cache/pip.

જો તમે Alpine અપનાવો છો, તો જ્યારે તમારી એપ DNS રિઝોલ્યુશન સમસ્યાઓ અનુભવે ત્યારે nss પેકેજ ઉમેરો. pip સાથે ઇન્સ્ટોલ કરતી વખતે, PATH માં /root/.local/bin ઉમેરો જેથી લોકલી ઇન્સ્ટોલ કરેલા સ્ક્રિપ્ટ્સ રનટાઇમ પર મળી શકે.

સાવચેતીઓ

Alpine ની musl libc, glibc માટે કમ્પાઈલ કરેલા બાઈનરી wheels સાથે અથડાઈ શકે છે, જેનાથી રનટાઇમ એરર આવી શકે છે. તેવા કિસ્સાઓમાં Alpine બિલ્ડરની અંદર wheels ને ફરીથી બિલ્ડ કરો અથવા slim બેઝનો ઉપયોગ કરો. DNS વિશ્વસનીયતા માટે વધારાનું nss પેકેજ એ નાની કિંમત છે.

આગળ શું જોવું

  • તમારી હાલની ઇમેજમાં મોટા લેયર્સ માટે સ્કેન કરો જે મલ્ટી-સ્ટેજ રીરાઈટ માટે ઉમેદવાર હોઈ શકે છે.
  • ઇમેજ બ્લોટ શોધવા માટે અપલોડ અને ડાઉનલોડ સમય માટે CI લોગ્સ મોનિટર કરો.
  • તમે પસંદ કરેલા બેઝ ડિસ્ટ્રિબ્યુશન માટે વલ્નરેબિલિટી રિપોર્ટ્સ પર