একজন জুনিয়র ডেভেলপার একটি Python Docker ইমেজ ১.২ GB থেকে কমিয়ে ৮৫ MB এ নিয়ে এসেছেন, যার ফলে CI পাইপলাইন ১১ মিনিট থেকে কমিয়ে ৯০ সেকেন্ডে নামিয়ে আনা সম্ভব হয়েছে। ছোট ইমেজ দ্রুত ডাউনলোড হয়, স্টোরেজ খরচ কমায় এবং নিরাপত্তার ঝুঁকিও কমায়।

কেন ইমেজের সাইজ গুরুত্বপূর্ণ

প্রতিবার যখন একটি কন্টেইনার পুল (pull) করা হয়, তখন রেজিস্ট্রি পুরো ইমেজটি স্ট্রিম করে। একটি ৮৫ MB লেয়ার কয়েক সেকেন্ডের মধ্যে চলে আসে; কিন্তু একটি ১.২ GB লেয়ার সাধারণ নেটওয়ার্কে কয়েক মিনিট সময় নিতে পারে। বিল্ড এজেন্টকেও পুরো ইমেজটি আপলোড এবং ক্যাশ করতে হয়, যা CI সময় এবং ক্লাউড-স্টোরেজ বিল বাড়িয়ে দেয়। প্রতিটি অতিরিক্ত প্যাকেজ একটি সম্ভাব্য দুর্বলতা (vulnerability) হতে পারে, তাই বেস ইমেজ ছোট করলে অ্যাটাক সারফেস (attack surface) বা আক্রমণের ঝুঁকি কমে যায়।

অতিরিক্ত সাইজ বা Bloat কোথা থেকে আসে

  • gcc এর মতো বিল্ড টুলগুলো যদি অ্যাপ চালানোর একই স্টেজে ইনস্টল করা হয়, তবে সেগুলো ফাইনাল ইমেজে থেকে যায়।
  • প্যাকেজ-ম্যানেজার ক্যাশ (যেমন, apt বা pip ক্যাশ) ডিস্কে থেকে যায় এবং ডিফল্টভাবে সেগুলো কখনো পরিষ্কার করা হয় না।
  • প্রতিটি RUN ইন্সট্রাকশন একটি নতুন রিড-অনলি (read-only) লেয়ার তৈরি করে; লেয়ারগুলোর মধ্যে ডুপ্লিকেট ফাইল থাকলে সাইজ বেড়ে যায়।
  • ubuntu:latest এর মতো বড় বেস ইমেজগুলোর সাথে একটি পূর্ণাঙ্গ OS থাকে, যা একটি মিনিমাল Python রানটাইমের প্রয়োজনের চেয়ে অনেক বেশি।

তিন ধাপে সাইজ কমানোর প্রক্রিয়া

ধাপ বেস ইমেজ বিল্ড পদ্ধতি চূড়ান্ত সাইজ
1 Standard Python (full) সিঙ্গেল স্টেজ, সব টুলস বিদ্যমান 1.18 GB
2 python:slim মাল্টি-স্টেজ: gcc সহ বিল্ডার, ফাইনাল স্টেজে শুধুমাত্র কম্পাইল করা প্যাকেজগুলো কপি করা হয় 210 MB
3 python:alpine Alpine Linux-এ মাল্টি-স্টেজ, যা নিজেই অত্যন্ত ছোট 85 MB

ধাপ ১ – বেসলাইন

ডিফল্ট Python ইমেজ দিয়ে শুরু করে ডেভেলপার ১.১৮ GB সাইজের একটি আর্টিফ্যাক্ট (artifact) দেখতে পান। ইমেজে পুরো Debian স্ট্যাক, ডেভেলপমেন্ট হেডার এবং pip ক্যাশ ছিল।

ধাপ ২ – বিল্ডার সহ slim

python:slim ব্যবহার করায় OS-এর সাইজ কমেছে, কিন্তু বিল্ড টুলগুলো থেকে গিয়েছিল। একটি builder স্টেজ যোগ করার ফলে gcc, make এবং অন্যান্য কম্পাইল-টাইম ডিপেন্ডেন্সি ইনস্টল, কম্পাইল এবং তারপর মুছে ফেলা সম্ভব হয়েছে। ফাইনাল স্টেজে শুধুমাত্র কম্পাইল করা wheels এবং রানটাইম ফাইলগুলো নিতে COPY --from=builder ব্যবহার করা হয়েছে, যা সাইজ কমিয়ে ২১০ MB এ নামিয়ে এনেছে।

ধাপ ৩ – Alpine-এর জয়

Alpine Linux তৈরি হয়েছে musl libc এবং busybox-এর ওপর। Alpine-এ একই মাল্টি-স্টেজ প্যাটার্ন অনুসরণ করে ৮৫ MB সাইজের একটি ইমেজ পাওয়া গেছে—যা মূল ইমেজের তুলনায় ৯৩% হ্রাস পেয়েছে। ডেভেলপার লক্ষ্য করেছেন যে Kubernetes কয়েক সেকেন্ডের মধ্যেই ইমেজটি পুল করেছে এবং CI জবটি ৯০ সেকেন্ডের মধ্যে শেষ হয়েছে।

বাস্তব জগতের প্রভাব

  • স্টোরেজ খরচ কম – রেজিস্ট্রি স্টোরেজ কমে যায়।
  • উন্নত নিরাপত্তা – কম প্যাকেজ মানে ট্র্যাক করার জন্য কম CVE। Alpine ইমেজে শুধুমাত্র Python রানটাইম এবং অ্যাপ্লিকেশন কোড থাকে।
  • দ্রুততর CI – পাইপলাইনের রানটাইম ১১ মিনিট থেকে কমিয়ে ৯০ সেকেন্ডে আনা হয়েছে।

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 যোগ করুন যাতে রানটাইমে লোকালি ইনস্টল করা স্ক্রিপ্টগুলো খুঁজে পাওয়া যায়।

সতর্কতা (Caveats)

Alpine-এর musl libc, glibc-এর জন্য কম্পাইল করা বাইনারি wheels-এর সাথে সাংঘর্ষিক হতে পারে, যা রানটাইম এরর তৈরি করতে পারে। সেক্ষেত্রে Alpine বিল্ডারের ভেতরেই wheels পুনরায় বিল্ড করুন অথবা slim বেস ইমেজে ফিরে যান। DNS নির্ভরযোগ্যতার জন্য অতিরিক্ত nss প্যাকেজটি একটি ছোট মূল্য মাত্র।

পরবর্তী করণীয়

  • আপনার বিদ্যমান ইমেজগুলো স্ক্যান করুন এবং বড় লেয়ারগুলো চিহ্নিত করুন যেগুলোকে মাল্টি-স্টেজ রিরাইট করা যেতে পারে।
  • ইমেজ Bloat শনাক্ত করতে আপলোড এবং ডাউনলোড সময় দেখার জন্য CI লগ মনিটর করুন।
  • আপনার নির্বাচিত বেস ডিস্ট্রিবিউশনের ভলনারেবিলিটি (vulnerability) রিপোর্টগুলোর দিকে নজর রাখুন।

শিক্ষাটি স্পষ্ট: একটি সুশৃঙ্খল Dockerfile, একটি হালকা বেস ইমেজ এবং একটি বিল্ডার স্টেজ একটি Python ইমেজকে বহুগুণ ছোট করতে পারে, যা কার্যকারিতা বজায় রেখেই উল্লেখযোগ্য গতি এবং খরচ সাশ্রয় নিশ্চিত করে।