8 মিনিট

কেন Docker ক্লাউডে অ্যাপ নির্ভরযোগ্যভাবে চালাতে জরুরি

শিখুন কেন Docker আপনার অ্যাপকে ল্যাপটপ থেকে ক্লাউড পর্যন্ত একইভাবে চালাতে সাহায্য করে, ডেপ্লয় সহজ করে, পরিবহনযোগ্যতা বাড়ায় এবং পরিবেশ সম্পর্কিত ঝামেলা কমায়।

কেন Docker ক্লাউডে অ্যাপ নির্ভরযোগ্যভাবে চালাতে জরুরি

ক্লाउড ডেপ্লয়মেন্টে Docker কেন এত সহায়ক

অধিকাংশ ক্লাউড ডেপ্লয়মেন্টের সমস্যা একটি পরিচিত অবাক করে দেওয়ার থেকে শুরু হয়: অ্যাপটি ল্যাপটপে কাজ করে, কিন্তু ক্লাউড সার্ভারে পৌঁছানোর পর ব্যর্থ হয়ে যায়। হতে পারে সার্ভারে Python বা Node-এর ভিন্ন সংস্করণ আছে, কোনো সিস্টেম লাইব্রেরি নেই, কনফিগ ফাইলে ছোট তফাৎ আছে, বা কোনো ব্যাকগ্রাউন্ড সার্ভিস চালু নেই। এই ছোট-বড় তফাৎ মিলিত হয়ে দলগুলোকে পরিবেশ ডিবাগ করতে বাধ্য করে, ফলে প্রোডাক্ট উন্নত করার বদলে পরিবেশে আটকে যায়।

Docker, সহজ ভাষায়

Docker সাহায্য করে আপনার অ্যাপকে সেই রানটাইম ও ডিপেনডেন্সিসহ প্যাক করে দেওয়ার মাধ্যমে। "ভার্সন X ইনস্টল করো, তারপর লাইব্রেরি Y যোগ করো, তারপর এই কনফিগ সেট করো"—এর মতো ধাপে ধাপে নির্দেশের বদলে আপনি একটি কনটেইনার ইমেজ পাঠান যেটাতে এসব ইতিমধ্যেই অন্তর্ভুক্ত।

একটি সহজ মানসিক মডেল:

  • ইমেজ = প্যাকেজ করা অ্যাপ (চলানোর জন্য সবকিছু সহ একটি স্ন্যাপশট)
  • কনটেইনার = সেই ইমেজের একটি চলমান কপি

যখন আপনি ক্লাউডে একই ইমেজ চালান যেটা আপনি লোকালি টেস্ট করেছেন, তখন "কিন্তু সার্ভার আলাদা" সমস্যা উল্লেখযোগ্যভাবে কমে যায়।

কে লাভ করে (ইঙ্গিত: শুধু ডেভেলপার নয়)

Docker বিভিন্ন ভূমিকাকে বিভিন্ন কারণে সাহায্য করে:

  • ডেভেলপাররা একটি পূর্বনির্ধারিত পরিবেশ ও দ্রুত অনবোর্ডিং পায় ("এই কনটেইনার চালাও" বহু পৃষ্ঠার সেটআপ ডকসের চেয়ে অনেক সহজ)।
  • অপস ও প্ল্যাটফর্ম টিম ধারাবাহিক ডেপ্লয়মেন্ট ও পরিষ্কার সীমানা পায় অ্যাপ ও সার্ভারের মধ্যে।
  • ছোট দলগুলো প্রোডাকশনে পৌঁছাতে পুনরাবৃত্তিমূলক পথ পায়, প্রতিটি প্রজেক্টের জন্য কাস্টম স্ক্রিপ্ট বানাতে হয় না।
  • এন্টারপ্রাইজগুলো স্ট্যান্ডার্ডাইজেশন পায়: বহু টিম ও সার্ভিস জুড়ে একই প্যাকেজিং ফরম্যাট।

বাস্তবসম্মত প্রত্যাশা

Docker অত্যন্ত সহায়ক, কিন্তু এটা একমাত্র টুল নয় যা আপনার দরকার হবে। আপনাকে এখনও কনফিগারেশন, সিক্রেটস, ডেটা স্টোরেজ, নেটওয়ার্কিং, মনিটরিং এবং স্কেলিং ম্যানেজ করতে হবে। অনেক দলের জন্য Docker একটি বিল্ডিং ব্লকের মতো কাজ করে—লোকাল ওয়ার্কফলো জন্য Docker Compose ও প্রোডাকশনে অর্কেস্ট্রেশন প্ল্যাটফর্মের সাথে এটি মিলেমিশে কাজ করে।

Docker-কে ভাবুন আপনার অ্যাপের জন্য একটি শিপিং কনটেইনার হিসেবে: ডেলিভারি আরও পূর্বানুমানযোগ্য করে তোলে। বন্দরের পরে (ক্লাউড সেটআপ ও রানটাইম) কি হচ্ছে তা এখনও গুরুত্বপূর্ণ—কিন্তু প্রতিটি চালান একইভাবে প্যাক করা থাকলে কাজ অনেক সহজ হয়ে যায়।

Docker মৌলিক: কনটেইনার, ইমেজ, ও রেজিস্ট্রি

Docker নতুন কিছু শব্দভান্ডার মনে করাতে পারে, কিন্তু মূল ধারণা সহজ: আপনার অ্যাপ এমনভাবে প্যাক করুন যাতে এটি যে কোনো জায়গায় একইভাবে চলে।

কনটেইনার বনাম ভার্চুয়াল মেশিন (VM)

একটি ভার্চুয়াল মেশিন আপনার অ্যাপের পাশাপাশি একটি পূর্ণ গেস্ট অপারেটিং সিস্টেম বাণ্ডিল করে। সেটা নমনীয়, কিন্তু রান করার জন্য ভারী এবং শুরুতে ধীর।

একটি কনটেইনার আপনার অ্যাপ ও তার ডিপেনডেন্সি বাণ্ডিল করে, কিন্তু হোস্ট মেশিনের OS কার্নেল শেয়ার করে পুরো OS পাঠায় না। এ কারণে কনটেইনার সাধারণত হালকা, কয়েক সেকেন্ডে শুরু হয়, এবং একই সার্ভারে অনেকগুলো চালানো যায়।

প্রচলিত টার্মগুলি

ইমেজ: আপনার অ্যাপের একটি রিড-অনলি টেমপ্লেট। এটিকে এমন একটি প্যাকেজড আর্টিফ্যাক্ট হিসেবে ভাবুন যাতে আপনার কোড, রানটাইম, সিস্টেম লাইব্রেরি ও ডিফল্ট সেটিংস রয়েছে।

কনটেইনার: একটি ইমেজের চলমান ইনস্ট্যান্স। ইমেজ যদি ব্লুপ্রিন্ট হয়, কনটেইনার হলো আপনি এখন যে বাড়িতে বাস করছেন।

Dockerfile: ইমেজ বানানোর ধাপে ধাপে নির্দেশ (কোন ডিপেনডেন্সি ইনস্টল করতে হবে, কোন ফাইল কপি করতে হবে, কোন কমান্ড দিয়ে শুরু করতে হবে)।

রেজিস্ট্রি: ইমেজ সংরক্ষণ ও বিতরণের সার্ভিস। আপনি ইমেজগুলোকে রেজিস্ট্রিতে “push” করেন এবং সার্ভারগুলো পরে সেগুলো “pull” করে (পাবলিক বা প্রাইভেট রেজিস্ট্রি)।

স্ট্যান্ডার্ডাইজেশন কেন গুরুত্বপূর্ণ

একবার আপনার অ্যাপ একটি Dockerfile থেকে বানানো ইমেজ হিসেবে সংজ্ঞায়িত হলে, আপনি একটি স্ট্যান্ডার্ড ডেলিভারি ইউনিট পান। সেই স্ট্যান্ডার্ডাইজেশন রিলিজগুলো পুনরাবৃত্তিমূলক করে তোলে: আপনি যেই ইমেজ টেস্ট করেছিলেন, সেটাই ডেপ্লয় করেন।

এটি হ্যান্ডঅফও সহজ করে দেয়। "আমার মেশিনে কাজ করে" বলার বদলে আপনি একটি নির্দিষ্ট ইমেজ ভার্সন রেজিস্ট্রিতে দেখিয়ে বলতে পারেন: এই কনটেইনার চালান, এই পরিবেশ ভ্যারিয়েবলগুলোর সাথে, এই পোর্টে। এটা ডেভ ও প্রোড পরিবেশের কনসিস্টেন্সির ভিত্তি।

ল্যাপটপ থেকে ক্লাউড পর্যন্ত কনসিস্টেন্সি: মূল সুবিধা

Docker ক্লাউড ডেপ্লয়মেন্টে সবচেয়ে বড় সুবিধা হলো কনসিস্টেন্সি। ল্যাপটপ, CI রানার বা ক্লাউড VM-এ যা ইনস্টল আছে তার ওপর নির্ভর করার বদলে আপনি একবার Dockerfile-এ পরিবেশ সংজ্ঞায়িত করেন এবং বিভিন্ন ধাপে তা পুনর্ব্যবহার করেন।

"কনসিস্টেন্ট" বলতে আসলে কী বোঝায়

প্র্যাকটিসে কনসিস্টেন্সি এমনভাবে প্রকাশিত হয়:

  • ডেভ, টেস্ট, প্রোড-এ একই রানটাইম সংস্করণ (যেমন একই Node/Python/JVM ও OS প্যাকেজ)
  • কম ডিপেনডেন্সি ড্রিফট ইস্যু (লাইব্রেরি, OS প্যাকেজ)
  • সহজ রোলব্যাক—একই ইমেজ ট্যাগ পুনরায় ডেপ্লয় করে
  • বেশি পরিষ্কার ডিবাগিং কারণ পরিবেশ মিলছে

এই কনসিস্টেন্সি দ্রুত লাভ দেয়। প্রোডে যে বাগটি আসে, সেটি একই ইমেজ ট্যাগ চালিয়ে লোকালি পুনরুত্পাদন করা যায়। এমন একটি ডেপ্লয় যা কোনো লাইব্রেরি অনুপস্থিতির কারণে ব্যর্থ হয়—এমনটা অসাধারণ কারণ যদি লাইব্রেরি অনুপস্থিত থাকতো, তা আপনার টেস্ট কনটেইনারেও অর থাকবে।

এটা "সেটআপ একইভাবে করো" বলার থেকে কেন আলাদা

দলগুলো প্রায়ই সেটআপ ডকস বা স্ক্রিপ্ট দিয়ে স্ট্যান্ডার্ডাইজ করার চেষ্টা করে। সমস্যা হলো ড্রিফট: মেশিনগুলো সময়ের সাথে পরিবর্তিত হয় প্যাচ ও প্যাকেজ আপডেট আসার ফলে, এবং ধীরে ধীরে পার্থক্য জমে।

Docker-এ পরিবেশকে একটি আর্টিফ্যাক্ট হিসেবে দেখা হয়। যদি পরিবর্তন করতে হয়, আপনি একটি নতুন ইমেজ পুনর্নির্মাণ করেন এবং সেটা ডেপ্লয় করেন—পরিবর্তনগুলো স্পষ্ট ও রিভিউযোগ্য। যদি আপডেটে সমস্যা হয়, রোলব্যাক প্রায়ই পূর্বের ভাল ট্যাগ পুনরায় ডেপ্লয় করাই সহজ।

ক্লাউড ও সার্ভার জুড়ে পরিবহনযোগ্যতা

Docker-এর আরেকটা বড় জয় হলো পোর্টেবিলিটি। একটি কনটেইনার ইমেজ আপনার অ্যাপকে একটি পোর্টেবল আর্টিফ্যাক্টে পরিণত করে: একবার বানান, তারপর যেখানে-ই সঙ্গত কনটেইনার রানটাইম আছে সেখানে চালান।

একই ইমেজ, বিভিন্ন ঘর

Docker ইমেজ আপনার অ্যাপ কোড এবং রানটাইম ডিপেনডেন্সিসহ বানায় (উদাহরণ: Node.js, Python প্যাকেজ, সিস্টেম লাইব্রেরি)। এর মানে একটি ইমেজ যা আপনি ল্যাপটপে চালিয়েছেন তা এই জায়গাগুলোতেও চালানো যাবে:

  • AWS, Azure বা Google Cloud-এ একটি VM
  • আপনার ডেটা সেন্টারের নিজস্ব সার্ভার
  • ম্যানেজড কনটেইনার প্ল্যাটফর্ম (Kubernetes-ভিত্তিক সার্ভিস)

এটি অ্যাপ রানটাইম স্তরে ভেন্ডর লক-ইন কমায়। আপনি এখনও ক্লাউড-নেটিভ সার্ভিস (ডাটাবেস, কিউ, স্টোরেজ) ব্যবহার করতে পারেন, কিন্তু আপনার কোর অ্যাপকে হোস্ট বদলাতে আবার বিল্ড করতে হয় না।

রেজিস্ট্রিগুলো কোথায় ফিট করে

পোর্টেবিলিটি তখনই ভাল কাজ করে যখন ইমেজগুলো রেজিস্ট্রিতে সংরক্ষণ ও ভার্সন করা হয়—পাবলিক বা প্রাইভেট। একটি সাধারণ ওয়ার্কফ্লো:

  1. একবার ইমেজ বানান (উদাহরণ myapp:1.4.2)।
  2. সেটি রেজিস্ট্রিতে push করুন।
  3. প্রতিটি পরিবেশে সেই একই ইমেজ pull করে চালান।

রেজিস্ট্রিগুলো ডেপ্লয়মেন্ট পুনরুত্পাদন ও অডিট করাও সহজ করে: যদি প্রোডাকশন 1.4.2 চালায়, পরে আপনি একই আর্টিফ্যাক্ট pull করে একই বিট পেতে পারেন।

বাস্তবধর্মী পরিস্থিতি

হোস্ট মাইগ্রেশন: যদি আপনি এক ভিপি প্রোভাইডার থেকে অন্যটিতে যান, পুরো স্ট্যাক পুনরায় ইনস্টল করতে হবে না। নতুন সার্ভারকে রেজিস্ট্রির দিকে পয়েন্ট করুন, ইমেজ pull করুন এবং একই কনফিগে কনটেইনার শুরু করুন।

স্কেল আউট: বেশি ক্যাপাসিটি দরকার? একই ইমেজ থেকে সার্ভারে অতিরিক্ত কনটেইনার চালু করুন। প্রতিটি ইনস্ট্যান্স একই হওয়ায় স্কেল করা একটি পুনরাবৃত্তিমূলক অপারেশন হয়ে যায়, ম্যানুয়াল সেটআপ নয়।

ইমেজ বানানো—ছোট, পুনরাবৃত্তি যোগ্য ও রক্ষণযোগ্য

ভালো Docker ইমেজ শুধু "কিছু চলায়" এমন নয়। এটি একটি প্যাকেজড, ভার্সনকৃত আর্টিফ্যাক্ট যা আপনি পরে পুনর্নির্মাণ করলেও বিশ্বাসযোগ্য থাকবে। এটিই ক্লাউড ডেপ্লয়মেন্টকে পূর্বানুমানযোগ্য করে তোলে।

Dockerfile: আপনার বিল্ড রেসিপি

একটি Dockerfile ধাপে ধাপে কিভাবে আপনার অ্যাপ ইমেজ তৈরি হবে বর্ণনা করে—একটি রেসিপির মতো স্পষ্ট পরিমাপ ও নির্দেশ সহ। প্রতিটি লাইন একটি লেয়ার তৈরি করে, এবং একসাথে এগুলো নির্ধারণ করে:

  • শুরুস্থান (বেস ইমেজ)
  • কোন ডিপেনডেন্সি ইনস্টল করতে হবে
  • কিভাবে কোড কপি করতে হবে
  • কোন কমান্ড অ্যাপ শুরু করে

এই ফাইলটি পরিষ্কার ও ইচ্ছাকৃত রাখলে ইমেজ ডিবাগ, রিভিউ ও রক্ষণাবেক্ষণ সহজ হয়।

ইমেজ ছোট ও পুনরাবৃত্তিমূলক রাখার সেরা অনুশীলন

ছোট ইমেজ দ্রুত pull হয়, দ্রুত শুরু হয় এবং কম জিনিস ভেঙে পড়ার সম্ভাবনা থাকে।

  • একটি ছোট বেস ইমেজ নির্বাচন করুন (যেমন alpine বা slim ভ্যারিয়েন্ট) যদি আপনার অ্যাপের সাথে উপযুক্ত হয়।
  • বেস ইমেজ ও গুরুত্বপূর্ণ প্যাকেজগুলোর সংস্করণ পিন করুন। ফ্লোটিং সংস্করণ আপনার নীচে পরিবর্তন আনতে পারে।
  • লেয়ার ও ফাইলগুলো কম রাখুন: সম্পর্কিত কমান্ডগুলো একত্রিত করুন এবং প্যাকেজ ক্যাশ পরিষ্কার করুন যাতে আপনি অস্থায়ী বিল্ড জাঙ্ক পাঠান না।

মাল্টি-স্টেজ বিল্ড: বড় করে বানান, ছোট করে পাঠান

অনেক অ্যাপ কম্পাইলার ও বিল্ড টুল চায়, কিন্তু রানটাইমে তা দরকার হয় না। মাল্টি-স্টেজ বিল্ড আপনাকে এক স্টেজে বিল্ড করে এবং দ্বিতীয়, মিনিমাল স্টেজে প্রোড ইমেজ প্রস্তুত করতে দেয়।

# build stage
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# runtime stage
FROM nginx:1.27-alpine
COPY --from=build /app/dist /usr/share/nginx/html

ফলাফল একটি ছোট প্রোডাকশন ইমেজ যা প্যাচ করার মতো ডিপেনডেন্সি কম রাখে।

ট্যাগিং স্ট্র্যাটেজি: ডেপ্লয়মেন্টকে ট্রেসযোগ্য করুন

ট্যাগগুলোই নির্ধারণ করে আপনি ঠিক কী ডেপ্লয় করেছেন।

  • প্রোডে latest নির্ভর করবেন না; এটি অস্পষ্ট।
  • সিমান্টিক ভার্সন (উদাহরণ: 1.4.2) রিলিজের জন্য ব্যবহার করুন।
  • কমিট SHA ট্যাগ যোগ করুন (উদাহরণ 1.4.2-<sha> বা কেবল <sha>) যাতে আপনি সবসময় ইমেজকে কোডের সঙ্গে ট্রেস করতে পারেন।

এটি রোলব্যাক ও ক্লিয়ার অডিটকে সমর্থন করে যখন ক্লাউডে কিছু বদলায়।

বাস্তবে চালানো অ্যাপ: নেটওয়ার্কিং, কনফিগ ও ডেটা

বিল্ড করে শিখুন
গাইডেড চ্যাট ওয়ার্কফ্লো দিয়ে সার্ভিস, কনফিগ ও Docker সেটআপে পুনরাবৃত্তি করুন।

একটি "বাস্তব" ক্লাউড অ্যাপ সাধারণত একক প্রসেস নয়। এটি একটি ছোট সিস্টেম: একটি ওয়েব ফ্রন্টএন্ড, একটি API, হয়তো একটি ব্যাকগ্রাউন্ড ওয়ার্কার, এবং একটি ডাটাবেস বা ক্যাশ। Docker একক ও মাল্টি-সার্ভিস উভয় সেটআপকে সমর্থন করে—আপনাকে শুধু বুঝতে হবে কিভাবে কনটেইনারগুলো একে অপরের সাথে কথা বলে, কনফিগ কোথায় থাকে, এবং কিভাবে ডেটা রিস্টার্ট টিকে থাকে।

একক-কনটেইনার বনাম বহু-সার্ভিস অ্যাপ

একক-কনটেইনার অ্যাপ হতে পারে একটি স্ট্যাটিক সাইট বা একটিমাত্র API যা অন্যকিছুর ওপর নির্ভর করে না। আপনি একটি পোর্ট (যেমন 8080) এক্সপোজ করে চালাবেন।

বহু-সার্ভিস অ্যাপ বেশি সাধারণ: web api-র উপর নির্ভর করে, api db-র উপর নির্ভর করে, এবং একটি worker জব কনসিউম করে। IP ঠিকানা হার্ডকোড না করে, কনটেইনারগুলো সাধারণত সার্ভিস নাম দিয়ে একটি শেয়ার্ড নেটওয়ার্কে একে অপরকে খুঁজে পায় (উদাহরণ: db:5432)।

লোকাল ও স্টেজিংয়ের জন্য Docker Compose

Docker Compose লোকাল ডেভ ও স্টেজিংয়ের জন্য একটি ব্যবহারিক পছন্দ কারণ এটি একটি কমান্ডে পুরো স্ট্যাক চালায়। এ 또한 আপনার অ্যাপের "আকৃতি" (সার্ভিস, পোর্ট, ডিপেনডেন্সি) একটি ফাইলে দলভুক্তভাবে ডকুমেন্ট করে।

একটি সাধারণ প্রগ্রেশন:

  • লোকালি Compose (দ্রুত ফিডব্যাক)
  • স্টেজিং VM-এ Compose (প্রোডের আচরণের কাছাকাছি)
  • প্রোডাকশনে ক্লাউড রানটাইম/অর্কেস্ট্রেটর

কনফিগ: ইমেজে কি থাকা উচিত নয়

ইমেজগুলো পুনরায় ব্যবহারযোগ্য ও শেয়ার করার জন্য নিরাপদ হওয়া উচিত। ইমেজের বাইরে রাখুন:

  • সিক্রেটস (API কী, DB পাসওয়ার্ড)
  • ভিন্ন হওয়া URL-গুলো (স্টেজিং বনাম প্রোড)
  • ফিচার ফ্ল্যাগ

এগুলো পরিবেশ ভ্যারিয়েবল, .env ফাইল (সতর্কতা: কমিট করবেন না) বা আপনার ক্লাউডের সিক্রেটস ম্যানেজারের মাধ্যমে ইনজেক্ট করুন।

ভলিউম দিয়ে ডেটা ধরে রাখা

কনটেইনার ডিস্পোজেবল; আপনার ডেটা হওয়া উচিত নয়। যাদের রিস্টার্ট টিকে থাকা জরুরি তাদের জন্য ভলিউম ব্যবহার করুন:

  • ডাটাবেস (Postgres, MySQL)
  • ইউজার আপলোড
  • এমন জেনারেটেড ফাইল যা সহজে পুনর্নির্মাণযোগ্য নয়

ক্লাউড ডেপ্লয়মেন্টে সমতুল্যটি ম্যানেজড স্টোরেজ (managed DBs, network disks, object storage)। মূল ধারণা অপরিবর্তিত: কনটেইনার অ্যাপ চালায়; পারসিস্টেন্ট স্টোরেজ স্টেট ধরে রাখে।

ডেপ্লয়মেন্ট ওয়ার্কফ্লো: বিল্ড থেকে ক্লাউডে চালানো

একটি সুস্থ Docker ডেপ্লয়মেন্ট ওয়ার্কফ্লো ইচ্ছাকৃতভাবে সহজ: একবার ইমেজ বানান, তারপর সেই একটিই সব জায়গায় চালান। ফাইল সার্ভারে কপির মতো কাজ বা ইনস্টলার পুনরায় চালানোর বদলে, ডেপ্লয়মেন্টকে একটি পুনরাবৃত্তিমূলক রুটিনে পরিণত করুন: ইমেজ pull করুন, কনটেইনার চালান।

মৌলিক ফ্লো: build → push → run

বেশিরভাগ দল এই পাইপলাইন অনুসরণ করে:

  1. একটি ভার্সনকৃত ইমেজ বানান (উদাহরণ myapp:1.8.3)।
  2. তা রেজিস্ট্রিতে push করুন (Docker Hub, ক্লাউড রেজিস্ট্রি, বা প্রাইভেট)।
  3. ক্লাউড পরিবেশে সেই ইমেজ pull করে কনটেইনার শুরু করে ডেপ্লয় করুন।

এই শেষ ধাপটিই Docker-কে “নিরস” (boring) মনে করায়—ভালোভাবে:

# build locally or in CI
docker build -t registry.example.com/myapp:1.8.3 .

docker push registry.example.com/myapp:1.8.3

# on the server / cloud runner
docker pull registry.example.com/myapp:1.8.3

docker run -d --name myapp -p 80:8080 registry.example.com/myapp:1.8.3

সাধারণ ক্লাউড প্যাটার্ন

ডকারাইজড অ্যাপ চালানোর দুইটি সাধারণ উপায়:

  • VM + Docker: আপনি একটি ভার্চুয়াল মেশিন ম্যানেজ করেন, Docker ইনস্টল করেন, এবং কনটেইনার নিজে চালান। এটা সরল এবং ছোট সেটআপের জন্য চমৎকার।
  • ম্যানেজড কনটেইনার সার্ভিস: ক্লাউড প্রোভাইডার আপনার জন্য কনটেইনার হোস্টগুলো চালায়। আপনি একই ইমেজ ডেপ্লয় করেন, কিন্তু স্কেলিং, রিস্টার্ট ও নেটওয়ার্কিং আরও অটোমেটেড হয়।

জিরো-ডাউনটাইমের বুনিয়াদি

রিলিজের সময় আউটেজ কমাতে, প্রোডাকশনে সাধারণত তিনটি বিল্ডিং ব্লক যোগ করা হয়:

  • হেলথ চেক: নিশ্চিত করে কনটেইনার সত্যিই রেডি (শুধুই শুরু নয়)।
  • রোলিং আপডেট: কনটেইনারগুলো একসঙ্গে নয়, ধাপে ধাপে প্রতিস্থাপন করা হয়।
  • লোড ব্যালান্সার: শুধুমাত্র হেলদি কনটেইনারকে ট্রাফিক রাউট করে এবং লোড বিতরণ করে।

রেজিস্ট্রি এবং পরিবেশগুলোর মধ্যে ইমেজ প্রোমোশন

রেজিস্ট্রি কেবল স্টোরেজ নয়—এটা কিভাবে আপনি পরিবেশগুলোর কনসিস্টেন্সি রাখেন। একটি প্রচলিত অনুশীলন হল একই ইমেজ প্রোমোট করা dev → staging → prod (প্রায়শই re-tag করে), পুনরায় বিল্ড না করে। এর ফলে প্রোডাকশন একই আর্টিফ্যাক্ট চালায় যেটা আপনি আগেই টেস্ট করেছেন, যা "স্টেজিং-এ কাজ করেছিল" এর ধোঁয়াশা কমায়।

CI/CD ও Docker: দ্রুত ও পরিষ্কার রিলিজ

CI বিল্ডগুলো পূর্বানুমানযোগ্য করুন
একটি সঙ্গতিপূর্ণ পরিবেশে বিল্ড ও টেস্ট করুন, তারপর একই আর্টিফ্যাক্টকে এগিয়ে নিন।

CI/CD (Continuous Integration ও Continuous Delivery) হচ্ছে সফটওয়্যার শিপ করার এসেম্বলি লাইন। Docker এটাকে আরও পূর্বানুমানযোগ্য করে তোলে কারণ প্রতিটি ধাপ একটি জ্ঞানীয় পরিবেশে চলে।

পাইপলাইনে Docker কোথায় ফিট করে

একটি Docker-বন্ধু পাইপলাইন সাধারণত তিনটি ধাপ থাকে:

  • Build: কোড থেকে একটি ভার্সনকৃত Docker ইমেজ তৈরি করুন (উদাহরণ, myapp:1.8.3)।
  • Test: কনটেইনারের ভিতরে অটোমেটেড টেস্ট চালান যাতে টুলিং ও ডিপেনডেন্সি পরে কি চলবে তা মেলে।
  • Publish: ইমেজ রেজিস্ট্রিতে push করুন যাতে অন্য পরিবেশগুলো একই আর্টিফ্যাক্ট pull করতে পারে।

এই ফ্লো নন-টেক স্টেকহোল্ডারদের কাছে বোঝানোও সহজ: “আমরা একটা সিল করা বক্স বানাই, বক্সটাকে টেস্ট করি, তারপর একই বক্স প্রতিটি পরিবেশে পাঠাই।”

কনটেইনারের ভিতরে টেস্ট চালানো (তাই প্রোড বিস্ময়কর না হয়)

টেস্টগুলো প্রায়ই লোকালেই পাস করে কিন্তু প্রোডে ব্যর্থ হয় কারণ রানটাইম মেলেনি, সিস্টেম লাইব্রেরি অনুপস্থিত বা ভিন্ন env ভ্যারিয়েবল। কনটেইনারে টেস্ট চালালে এসব ফাঁক কমে। আপনার CI রানারকে একটি যত্নশীল মেশিনের প্রয়োজন নেই—শুধু Docker লাগলেই হয়।

আর্টিফ্যাক্ট প্রোমোশন: dev → staging → production

Docker “promote, don’t rebuild” সমর্থন করে। প্রতি পরিবেশে আপনি একে করুন:

  1. একবার myapp:1.8.3 তৈরি ও টেস্ট করুন।
  2. একই ইমেজ dev-এ ডেপ্লয় করুন।
  3. ভালো হলে একই ইমেজ staging-এ ডেপ্লয় করুন।
  4. এরপরই একই ইমেজ production-এ ডেপ্লয় করুন।

পরিবেশগুলোর মধ্যে কেবল কনফিগ পরিবর্তন হয় (URL বা ক্রেডেনশিয়ালস), অ্যাপ আর্টিফ্যাক্ট নয়। এতে রিলিজ-ডে অনিশ্চয়তা কমে এবং রোলব্যাক সহজ হয়: পূর্বের ট্যাগ পুনরায় ডেপ্লয় করুন।

Koder.ai কোথায় সাহায্য করতে পারে

যদি আপনি দ্রুত চলছে থাকেন এবং Docker-এর সুবিধা পেতে চান কিন্তু কয়েকদিন স্ক্যাফল্ডিং এ কাটাতে চান না, Koder.ai আপনাকে চ্যাট-চালিত ওয়ার্কফ্লো থেকে প্রোডাকশন-আকৃতির অ্যাপ জেনারেট করতে এবং তারপর এটিকে পরিষ্কারভাবে কনটেইনারাইজ করতে সাহায্য করতে পারে।

উদাহরণস্বরূপ, দলগুলো প্রায়ই Koder.ai ব্যবহার করে:

  • React ফ্রন্টএন্ড এবং Go ব্যাকএন্ড সহ PostgreSQL তৈরি করতে,
  • শুরুতেই Dockerfile ও docker-compose.yml যোগ করতে (তাতে dev ও prod আচরণ সঙ্গত থাকে),
  • সম্পূর্ণ সোর্স কোড এক্সপোর্ট করে একটি মানক build → push → run পাইপলাইনে প্লাগ করতে,
  • ইটারেশনের সময় স্ন্যাপশট ও রোলব্যাক ব্যবহার করে ডেপ্লয়মেন্ট পরিবর্তন নিয়ন্ত্রিত রাখা।

মূল সুবিধা হলো Docker ডেপ্লয়মেন্টের প্রিমিটিভিন থাকলেও Koder.ai আইডিয়া থেকে কনটেইনার-রেডি কোডবেসে যেতে গতি বাড়ায়।

এক সার্ভারের বাইরে স্কেল করা: Docker ও অর্কেস্ট্রেশন

Docker একটি সার্ভিসকে একটি মেশিনে প্যাকেজ ও চালানো সহজ করে। কিন্তু যদি আপনার একাধিক সার্ভিস, প্রতিটির একাধিক কপি, এবং একাধিক সার্ভার থাকে, তাহলে আপনি এমন একটি সিস্টেম চান যা সবকিছু সমন্বয় করে। এটিই অর্কেস্ট্রেশন: সফটওয়্যার যা সিদ্ধান্ত নেয় কোথায় কনটেইনার চলবে, এগুলোকে সুস্থ রাখবে, এবং ডিমান্ড বদলালে ক্যাপাসিটি সামঞ্জস্য করবে।

অনেক কনটেইনারের সাথে অর্কেস্ট্রেশনের গুরুত্ব

মাত্র কয়েকটি কনটেইনার থাকলে আপনি ম্যানুয়ালি চালু ও রিস্টার্ট করে জ্বলন্ত মিডজওয়াল ঠিক রাখতে পারেন। বড় স্কেলে তা দ্রুত ভেঙে পড়ে:

  • একটি সার্ভার ফেইল করলে অনেক কনটেইনার হারিয়ে যেতে পারে।
  • ট্রাফিক অনুযায়ী 2, 10 বা 100 কপি লাগতে পারে।
  • আপডেটগুলো অ্যাপ অফলাইন না করে রোল আউট করতে হবে।
  • সার্ভিসগুলোর মধ্যে সার্ভিস ডিসকভারি ও কনফিগ শেয়ার করার নিয়ম দরকার।

Kubernetes, ভারি জার্গন ছাড়া

Kubernetes (সাধারণত “K8s”) সবচেয়ে প্রচলিত অর্কেস্ট্রেটর। একটি সহজ মানসিক মডেল:

  • Nodes: সেই মেশিনগুলো (VM বা সার্ভার) যেগুলো আপনার কনটেইনার চলে।
  • Pods: Kubernetes যে ছোট একক চালায় (সাধারণত একটি কনটেইনার, কখনও কখনও কিছু কনটেইনার একসঙ্গে থাকতে পারে)।
  • Deployments: “এই পডের N কপি চালাও এবং সেগুলো উচিত তেমনই রাখো”, রোলিং আপডেটসহ।
  • Services: স্থিতিশীল নেটওয়ার্কিং যাতে অ্যাপের অন্যান্য অংশগুলো পডগুলোকে নির্ভরযোগ্যভাবে অ্যাক্সেস করতে পারে।

Docker ইমেজ কিভাবে Kubernetes-এ ফিট করে

Kubernetes কনটেইনার বানায় না; এটি কেবল চালায়। আপনি ইমেজ বানান, রেজিস্ট্রিতে push করেন, তারপর Kubernetes সেই ইমেজ নোডে pull করে পডগুলো চালায়। আপনার ইমেজ সর্বত্র ব্যবহৃত একটি পোর্টেবল, ভার্সনকৃত আর্টিফ্যাক্ট থাকে।

কখন একটি সহজ অপশন যথেষ্ট

যদি আপনার একটি সার্ভার এবং কয়েকটি সার্ভিস থাকে, Compose অনেক সময় যথেষ্ট। অর্কেস্ট্রেশন তখনই উপকারী যখন আপনি উচ্চ প্রাপ্যতা, ঘন ডিপ্লয়মেন্ট, অটো-স্কেলিং, বা একাধিক সার্ভারে ক্ষমতা ও রেজিলিয়েন্স চান।

কনটেইনার নিরাপত্তা ও কমপ্লায়েন্স মৌলিক

কনটেইনার স্বয়ংক্রিয়ভাবে অ্যাপকে নিরাপদ করে না—তবে তারা স্ট্যান্ডার্ডাইজ ও অটোমেট করা নিরাপত্তি কাজগুলো যোগ করার পরিমাণকে সহজ করে। সুবিধা হলো Docker আপনাকে স্পষ্ট, পুনরাবৃত্তি যোগ্য পয়েন্ট দেয় যেখানে অডিট ও সিকিউরিটি কন্ট্রোল যোগ করা যায়।

ইমেজ স্ক্যানিং (এবং কেন গুরুত্বপূর্ণ)

একটি কন্টেইনার ইমেজ আপনার অ্যাপ ও তার ডিপেনডেন্সির একটি বাণ্ডেল, তাই ভলনারেবিলিটিগুলো সাধারণত বেস ইমেজ বা সিস্টেম প্যাকেজ থেকে আসে। ইমেজ স্ক্যানিং ডেপ্লয়ের আগে পরিচিত CVE-গুলোর জন্য চেক করে।

পাইপলাইনে স্ক্যানিং একটি গেইট করুন: যদি ক্রিটিক্যাল ভলনারেবিলিটি পাওয়া যায়, বিল্ড ফেল করান এবং একটি প্যাচ করা বেস ইমেজ দিয়ে পুনরায় বিল্ড করুন। স্ক্যান ফলাফলগুলো আর্টিফ্যাক্ট হিসেবে রাখুন যাতে আপনি কি শিপ করেছেন তা কমপ্লায়েন্স রিভিউতে দেখাতে পারেন।

লিস্ট প্রিভিলেজ (least privilege)

সম্ভব হলে non-root ইউজার হিসেবে চালান। অনেক অ্যাটাক রুট অ্যাক্সেস ব্যবহার করে কনটেইনারের বাইরে যাওয়ার চেষ্টা করে বা ফাইলসিস্টেম টেম্পার করে।

পাঠযোগ্য ফাইলসিস্টেম ও নির্দিষ্ট লিখনযোগ্য পাথ মাউন্ট (লগ বা আপলোডস) ব্যবহার করার কথা ভাবুন। এতে অনধিকার প্রবেশ ঘটলে একজন আক্রমণকারী কি পরিবর্তন করতে পারবে তা সীমাবদ্ধ হয়।

সিক্রেটস হ্যান্ডলিং: সিক্রেটস ইমেজে bake করবেন না

API কী, পাসওয়ার্ড, বা ব্যক্তিগত সার্টিফিকেট Docker ইমেজে কপি করবেন না এবং Git-এ কমিট করবেন না। ইমেজ ক্যাশ হয়, শেয়ার হয় এবং রেজিস্ট্রিতে push হয়—সিক্রেটস ব্যাপকভাবে লিক হতে পারে।

পার্কোর হিসেবে, রানটাইমে আপনার প্ল্যাটফর্মের সিক্রেট স্টোর (উদাহরণ Kubernetes Secrets বা ক্লাউড প্রোভাইডারের সিক্রেট ম্যানেজার) দিয়ে সিক্রেট ইনজেক্ট করুন এবং কেবল সেই সার্ভিসকে অ্যাক্সেস অধিকার দিন যা প্রয়োজন।

আপডেট ও প্যাচিং: নিয়মিত পুনর্নির্মাণ

পরম্পরাগত সার্ভারের মতো কনটেইনার নিজে চলতে চলতে প্যাচ হয় না। সাধারণ পদ্ধতি হলো: আপডেটেড ডিপেনডেন্সিসহ ইমেজ পুনর্নির্মাণ করে পুনরায় ডেপ্লয় করা।

একটি ক্যালেন্ডার সেট করুন (সাপ্তাহিক বা মাসিক) এমনভাবে যে আপনি ইমেজগুলো পুনর্নির্মাণ করবেন এমনকি যখন আপনার অ্যাপ কোড বদলায়নি, এবং উচ্চ-গুরুত্বপূর্ণ CVE-র ক্ষেত্রে তৎক্ষণাৎ পুনর্নির্মাণ করুন। এই অভ্যাস ডেপ্লয়মেন্টগুলোকে অডিটযোগ্য ও কম ঝুঁকিপূর্ণ রাখে।

সাধারণ ভুলগুলো ও কিভাবে এড়াবেন

আপনার ডোমেইনে সেট করুন
আপনার কনটেইনারাইজড অ্যাপ ব্যবহারকারীর জন্য প্রস্তুত হলে একটি কাস্টম ডোমেইন যোগ করুন।

যেমনটুকু দলগুলো “Docker ব্যবহার করে” বললেও কিছু অভ্যাস থাকলে তবুও অনির্ভরযোগ্য ক্লাউড ডেপ্লয়মেন্ট শিপ হতে পারে। এখানে সবচেয়ে বেশি সমস্যার সৃষ্টি করা ভুলগুলো এবং প্রতিরোধের ব্যবহারিক উপায়গুলো আছে।

1) কনটেইনারকে পেটের মতো ব্যবহার করা (প্রোডে ম্যানুয়াল পরিবর্তন)

একটি সাধারণ অ্যান্টি-প্যাটার্ন হল “সার্ভারে SSH করে কিছু পরিবর্তন করা,” বা চালু কনটেইনারে exec করে কনফিগ হট-ফিক্স করা। একবার কাজ করে, পরে ভেঙে পড়ে কারণ কেউ সঠিক একই স্টেট পুনরায় তৈরি করতে পারে না।

বদলে কনটেইনারগুলোকে গবাদি বদলে (cattle) মতো আচরণ করুন: ডিসপোজেবল ও রিপ্লেসেবল। প্রতিটি পরিবর্তনই ইমেজ বিল্ড ও ডেপ্লয় পাইপলাইনের মাধ্যমে করুন। ডিবাগ করতে গেলে একটি অস্থায়ী পরিবেশে করুন এবং তারপর ফিক্সটি Dockerfile, কনফিগ বা ইনফ্রাস্ট্রাকচারে কোড করুন।

2) বিশাল ইমেজ ও ধীরে বিল্ড হওয়া messy Dockerfile

বড় ইমেজ CI/CD ধীর করে, স্টোরেজ খরচ বাড়ায়, এবং সিকিউরিটি সারফেস বাড়ায়।

এই সমস্যা এড়াতে Dockerfile কড়াকড়ি করুন:

  • যেখানে সম্ভব ছোট বেস ইমেজ ব্যবহার করুন।
  • ডিপেনডেন্সি ফাইলগুলো আগে কপি করুন (যাতে বিল্ড ক্যাশ ব্যবহার করে ইনস্টলগুলো দ্রুত হয়), তারপর অ্যাপ কোড কপি করুন।
  • কম্পাইল করা অ্যাপের জন্য মাল্টি-স্টেজ বিল্ড ব্যবহার করুন যাতে ফাইনাল ইমেজে কেবল রানটাইম লাগে।
  • .dockerignore যোগ করুন যাতে node_modules, বিল্ড আর্টিফ্যাক্ট বা লোকাল সিক্রেটস অনিচ্ছাকৃতভাবে পাঠানো না হয়।

লক্ষ্য একটি পুনরাবৃত্তিমূলক ও দ্রুত বিল্ড—এমনকি ক্লিন মেশিনেও।

3) লগ ও মেট্রিক্স উপেক্ষা (অবজার্ভেবিলিটি এখনও জরুরি)

কনটেইনারগুলো অ্যাপের আচরণ বুঝতে বাধা দেয় না। লগ, মেট্রিক্স, ও ট্রেসিং ছাড়া আপনি কেবল ব্যবহারকারীর অভিযোগে জানবেন যে কোথাও সমস্যা আছে।

ন্যূনতমভাবে, নিশ্চিত করুন আপনার অ্যাপ stdout/stderr-এ লগ করে (লোকাল ফাইলে না), বেসিক হেলথ এন্ডপয়েন্ট আছে, এবং কয়েকটি কীগুলো মেট্রিক (এরর রেট, ল্যাটেন্সি, কিউ গভীরতা) নির্গত করে। তারপর সেগুলোকে আপনার ক্লাউড মনিটরিং সিস্টেমের সাথে সংযুক্ত করুন।

4) স্টেটফুল সার্ভিসগুলো দ্রুত পরিকল্পনা না করা (ডাটাবেস, কিউ, ফাইল)

স্ট্যাটলেস কনটেইনার সহজে রিপ্লেস করা যায়; স্টেটফুল ডেটা নয়। দলগুলো প্রায়ই পরে আবিষ্কার করে যে কনটেইনারে ডাটাবেস চালানো "ভালো হয়ে" ছিল যতক্ষণ না রিস্টার্টে ডেটা মুছে যায়।

শুরুতেই সিদ্ধান্ত নিন স্টেট কোথায় থাকবে:

  • সম্ভব হলে ম্যানেজড ডাটাবেস/কিউ ব্যবহার করুন।
  • যদি নিজে স্টেটফুল সার্ভিস চালাতে হয়, তাহলে স্টোরেজ, ব্যাকআপ ও আপগ্রেড পরিকল্পনা প্রথম দিন থেকেই ডিজাইন করুন।

Docker অ্যাপ প্যাকেজিংয়ে অসাধারণ—কিন্তু নির্ভরযোগ্যতা আসে যখন আপনি সচেতনভাবে কনটেইনারগুলো কিভাবে বানানো, পর্যবেক্ষণ ও পার্সিস্টেন্ট ডেটার সাথে সংযুক্ত করা হবে তা ডিজাইন করেন।

ব্যবহারিক শুরু করার চেকলিস্ট

Docker-এ নতুন হলে, দ্রুত মূল্য পাওয়ার সবচেয়ে সহজ উপায় হলো একটি বাস্তব সার্ভিসকে শেষ পর্যন্ত কনটেইনারাইজ করা: বিল্ড করা, লোকালি চালানো, রেজিস্ট্রিতে push করা, এবং ডেপ্লয় করা। নিম্ন чекলিস্টটুকু ব্যবহার করে স্কোপ ছোট রাখুন এবং ফলাফল ব্যবহারযোগ্য রাখুন।

1) একটি সার্ভিস দিয়ে শুরু করুন (end-to-end)

প্রথমে একটি স্ট্যাটলেস সার্ভিস বাছুন (একটি API, একটি worker, বা একটি সাধারণ ওয়েব অ্যাপ)। নির্ধারণ করুন কী দিয়ে শুরু হবে: কোন পোর্টে লিসেন করে, প্রয়োজনীয় পরিবেশ ভ্যারিয়েবলগুলো, এবং কোনো বাহ্যিক ডিপেনডেন্সি (যেমন একটি ডাটাবেস যা আপনি আলাদাভাবে চালাতে পারবেন)।

লক্ষ্য স্পষ্ট রাখুন: “আমি একই ইমেজ থেকে লোকালি ও ক্লাউডে একইভাবে চালাতে পারি।”

2) একটি মিনিমাল Dockerfile + Compose লোকাল ব্যবহারের জন্য তৈরি করুন

যে Dockerfile টা সবচেয়ে ছোটে আপনার অ্যাপ নির্ভরযোগ্যভাবে বানায় সেটি লিখুন। পছন্দ করবেন:

  • একটি ছোট বেস ইমেজ
  • কেবল যা দরকার তা কপি করা
  • একটি পরিষ্কার স্টার্ট কমান্ড

তারপর লোকাল ডেভের জন্য docker-compose.yml যোগ করুন যা env ভ্যারিয়েবল ও ডিপেনডেন্সি (ডাটাবেস ইত্যাদি) ওয়্যারিং করে—আপনার ল্যাপটপে Docker ছাড়া অন্য কিছু ইনস্টল না করিয়েই চালানো যাবে।

পরবর্তীতে দরকার হলে লোকালি সেটআপ বাড়াতে পারেন—শুরুতে সাদাসিধে রাখুন।

3) একটি রেজিস্ট্রি ও ট্যাগিং কনভেনশন নির্ধারণ করুন

ইমেজ কোথায় থাকবে (Docker Hub, GHCR, ECR, GCR ইত্যাদি) নির্ধারণ করুন। তারপর এমন ট্যাগাভিধি নিন যে ডেপ্লয়মেন্ট পূর্বানুমানযোগ্য হয়:

  • :dev লোকাল টেস্টিং (ঐচ্ছিক)
  • :git-sha (অপরিবর্তনীয়, ডেপ্লয়মেন্টের জন্য শ্রেষ্ঠ)
  • :v1.2.3 রিলিজের জন্য

প্রোডাকশনে :latest নির্ভর করবেন না।

4) CI যুক্ত করুন যাতে স্বয়ংক্রিয়ভাবে build + publish করে

CI সেটআপ করুন যাতে প্রধান ব্রাঞ্চে প্রতিটি মর্জে ইমেজ বিল্ড করে এবং রেজিস্ট্রিতে push করে। আপনার পাইপলাইন উচিত:

  1. ইমেজ বিল্ড করা
  2. একটি বেসিক চেক চালানো (টেস্ট বা স্মোক রান)
  3. সম্মত ট্যাগগুলো দিয়ে push করা

এটা কাজ করলে, আপনি প্রকাশিত ইমেজটিকে ক্লাউড ডেপ্লয় ধাপে যুক্ত করে আরও итераট করতে প্রস্তুত থাকবেন।

সাধারণ প্রশ্ন

কেন Docker ক্লাউড ডেপ্লয়মেন্টকে বেশি নির্ভরযোগ্য করে?

Docker “আমার মেশিনে কাজ করে” সমস্যা কমায় কারণ এটি আপনার অ্যাপটিকে তার রানটাইম ও ডিপেনডেন্সিসহ একটি ইমেজে প্যাকেজ করে। একই ইমেজ লোকালি, CI-তে এবং ক্লাউডে চালালে OS প্যাকেজ, ভাষার সংস্করণ ও ইনস্টল করা লাইব্রেরিগুলোর ভিন্নতা আচমকা আচরণ পরিবর্তন করে না।

Docker ইমেজ এবং কনটেইনারের মধ্যে পার্থক্য কী?
  • ইমেজ: আপনার অ্যাপ + রানটাইম + ডিপেনডেন্সির একটি রিড-অনলি, ভার্সন করা প্যাকেজ।
  • কনটেইনার: সেই ইমেজের একটি চলন্ত অনুলিপি।

সাধারণত আপনি একবার একটি ইমেজ বানান (যেমন myapp:1.8.3) এবং বিভিন্ন পরিবেশে তা থেকে অনেকগুলি কনটেইনার চালান।

কনটেইনার কীভাবে ভার্চুয়াল মেশিন থেকে আলাদা?

একটি VM একটি সম্পূর্ণ গেস্ট অপারেটিং সিস্টেম নিয়ে আসে, তাই তা ভারী এবং সাধারণত ধীরে শুরু হয়। একটি কনটেইনার হোস্টের কার্নেল শেয়ার করে এবং শুধুমাত্র অ্যাপ ও তার লাইব্রেরিগুলো নিয়ে যায়, ফলে তা সাধারণত:

  • দ্রুত শুরু করে
  • CPU/RAM/Disk-এ হালকা
  • এক সার্ভারে অনেক অনুলিপি চালানো সহজ করে তোলে
Docker রেজিস্ট্রি কী, এবং কেন দরকার?

রেজিস্ট্রি হল যেখানে ইমেজগুলো সংরক্ষিত ও ভার্সন করা থাকে, যাতে অন্য মেশিনগুলো সেগুলো থেকে pull করতে পারে।

সাধারণ ওয়ার্কফ্লো:

  1. docker build -t myapp:1.8.3 .
  2. docker push <registry>/myapp:1.8.3
  3. ক্লাউড সেই নির্দিষ্ট ট্যাগ pull করে চালায়

এর ফলে রোলব্যাক সহজ হয়: আগের ট্যাগটি পুনরায় ডেপ্লয় করুন।

প্রোডাকশনের জন্য কী ধরণের ইমেজ ট্যাগিং কৌশল ভালো?

প্রোডাকশনে এমন ট্যাগ ব্যবহার করুন যা অপরিবর্তনীয় ও ট্রেসযোগ্য।

প্রায়োগিক নিয়ম:

  • রিলিজ ট্যাগ: :1.8.3
  • বিল্ড শনাক্তকারী: :<git-sha>
  • প্রোডাকশনে :latest এড়িয়ে চলুন (এটি অস্পষ্ট)

এটা ক্লিন রোলব্যাক ও অডিটকে সহায়তা করে।

Docker-এ সিক্রেট ও কনফিগ কিভাবে হ্যান্ডেল করা উচিত?

ইমেজের বাইরে রেখে পরিবেশ-নির্ভর কনফিগারেশন রাখুন। Dockerfile-এ API কী, পাসওয়ার্ড বা ব্যক্তিগত সার্টিফিকেট কপি করবেন না।

বিকল্প:

  • পরিবেশ ভ্যারিয়েবল দিয়ে কনফিগ পাস করুন
  • সিক্রেটস ম্যানেজার ব্যবহার করুন (ক্লাউড বা অর্কেস্ট্রেটরের)
  • .env ফাইল Git-এ কমিট করবেন না

এতে ইমেজগুলো পুনরায় ব্যবহারযোগ্য থাকে এবং লিক হওয়া কমে।

কিভাবে ডেটা ধরে রাখবেন যদি কনটেইনার রিস্টার্ট বা রিপ্লেস করা হয়?

কনটেইনার ক্ষণস্থায়ী; তাই তাদের ফাইলসিস্টেম রিস্টার্ট বা রিপ্লেস হলে বদলে যেতে পারে।

ব্যবহার করুন:

  • ভলিউমস এমন ডেটার জন্য যা টিকে থাকতে হবে (ডাটাবেস, আপলোডস)
  • সম্ভব হলে ম্যানেজড ক্লাউড সার্ভিস (managed DB, object storage)

নীতিগতভাবে: অ্যাপগুলো কনটেইনারে চালান, স্টেট পলি-বিল্ট স্টোরেজে রাখুন।

কখন Docker Compose ব্যবহার করা উচিত এবং কখন Kubernetes?

Compose লোকাল ডেভ ও এক একহোস্ট ব্যবহারের জন্য চমৎকার:

  • এক কমান্ডে পুরো স্ট্যাক চালান
  • সার্ভিস নাম দিয়ে সহজ নেটওয়ার্কিং (উদাহরণ db:5432)
  • নতুন ডেভেলপারদের জন্য কনসিস্টেন্ট অনবোর্ডিং

যখন আপনি মাল্টি-সার্ভার, উচ্চ প্রাপ্যতা ও অটো-স্কেলিং চান, তখন সাধারণত একটি অর্কেস্ট্রেটর (কখনো কবারনেটিস) যোগ করা হয়।

Docker সহ একটি সাধারণ CI/CD ওয়ার্কফ্লো কেমন?

একটি বাস্তবসম্মত পাইপলাইন: build → test → publish → deploy

  • CI-তে ইমেজ বিল্ড করুন
  • কনটেইনারের ভিতরে টেস্ট চালান (প্রোডের কাছাকাছি পরিবেশ)
  • ইমেজ রেজিস্ট্রিতে push করুন
  • প্রতিটি পরিবেশে একই ইমেজ pull করে deploy করুন

“প্রোমোট, পুনরায় বিল্ড নয়” নীতি অনুসরণ করুন (dev → staging → prod) যাতে আর্টিফ্যাক্ট অপরিবর্তিত থাকে।

কোন কারণগুলো সাধারণত কনটেইনার লোকালে চলে কিন্তু ক্লাউডে ব্যর্থ করে?

সাধারণ কারণগুলো:

  • পোর্ট ভুলভাবে এক্সপোজ করা: নিশ্চিত করুন অ্যাপটি সেই কনটেইনার পোর্টে লিসেন করছে যা আপনি পাবলিশ করেছেন (উদাহরণ: -p 80:8080).
  • পরিবেশ ভ্যারিয়েবল অনুপস্থিত: প্রোড কনফিগ লোকালি একই env ভ্যারিয়েবল দিয়ে পুনরায় তৈরি করুন।
  • ডিপেনডেন্সি ড্রিফট: পিন করা সংস্করণ সহ ইমেজ পুনর্নির্মাণ করুন এবং হোস্ট-ইনস্টল করা প্যাকেজে নির্ভর করবেন না।
  • হেলথ চেক নেই: রেডিনেস/হেলথ এন্ডপয়েন্ট যোগ করুন যাতে রোলআউটের সময় ট্রাফিক আগে না যায়।

ডিবাগ করতে, একই প্রোড ট্যাগ লোকালি চালান এবং প্রথমে কনফিগ তুলনা করুন।

Related posts