ডেভেলপারদের জন্য Docker: ইমেজ, কন্টেইনার, এবং Compose
আপনি একটি ওয়েব অ্যাপ তৈরি করেছেন যা আপনার মেশিনে নিখুঁতভাবে চলে, কিন্তু যখন আপনি এটি একটি সার্ভারে ডিপ্লয় করেন বা একজন টিমমেটের সাথে শেয়ার করেন, তখন এটি ভেঙে পড়ে। ডিপেন্ডেন্সি অনুপস্থিত, ভার্সন সংঘর্ষ, বা পরিবেশ ভেরিয়েবল ভুল। এটি ক্লাসিক "এটি আমার মেশিনে কাজ করে" সমস্যা। Docker এটি সমাধান করে আপনার অ্যাপ্লিকেশন এবং এর ডিপেন্ডেন্সিগুলোকে একটি কন্টেইনার নামক একটি মানক ইউনিটে প্যাকেজ করে। এই গাইডে, আপনি Docker-এর মূল ধারণাগুলো—ইমেজ, কন্টেইনার, এবং Compose—এবং আপনার ডেভেলপমেন্ট ওয়ার্কফ্লো স্ট্রিমলাইন করতে সেগুলো কীভাবে ব্যবহার করবেন তা শিখবেন।
Docker কী?
Docker হলো কন্টেইনারে অ্যাপ্লিকেশন বিল্ড, রান এবং শিপ করার একটি প্ল্যাটফর্ম। একটি কন্টেইনার হলো একটি হালকা, স্বতন্ত্র, এক্সিকিউটেবল প্যাকেজ যা একটি সফটওয়্যার চালানোর জন্য প্রয়োজনীয় সবকিছু অন্তর্ভুক্ত করে: কোড, রানটাইম, সিস্টেম টুলস, লাইব্রেরি, এবং সেটিংস। কন্টেইনারগুলো অ্যাপ্লিকেশনগুলোকে একে অপরের থেকে এবং অন্তর্নিহিত অবকাঠামো থেকে আলাদা করে, পরিবেশ জুড়ে ধারাবাহিকতা নিশ্চিত করে।
ইমেজ বনাম কন্টেইনার
একটি ইমেজ হলো একটি রিড-অনলি টেমপ্লেট যা একটি কন্টেইনার তৈরি করার নির্দেশনা ধারণ করে। এটি আপনার অ্যাপ্লিকেশন এবং এর পরিবেশের একটি স্ন্যাপশটের মতো। একটি কন্টেইনার হলো একটি ইমেজের রানেবল ইনস্ট্যান্স। আপনি Docker API বা CLI ব্যবহার করে কন্টেইনার তৈরি, শুরু, বন্ধ, সরানো, বা মুছে ফেলতে পারেন।
একটি ইমেজকে একটি ক্লাস এবং একটি কন্টেইনারকে সেই ক্লাসের একটি অবজেক্ট (ইনস্ট্যান্স) হিসেবে ভাবুন। আপনি একই ইমেজ থেকে একাধিক কন্টেইনার চালাতে পারেন, প্রতিটি অন্যদের থেকে আলাদা।
Dockerfile দিয়ে একটি ইমেজ বিল্ড করা
একটি Dockerfile হলো একটি টেক্সট ফাইল যাতে একটি ইমেজ বিল্ড করার নির্দেশনা থাকে। এখানে একটি Node.js অ্যাপের জন্য একটি সহজ উদাহরণ:
# Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of the application code
COPY . .
# Expose the port the app runs on
EXPOSE 3000
# Define the command to run the app
CMD ["node", "server.js"]
ইমেজ বিল্ড করতে, চালান:
docker build -t my-node-app .
-t ফ্ল্যাগ ইমেজটিকে একটি নাম (my-node-app) দিয়ে ট্যাগ করে। শেষের . বিল্ড কনটেক্সট (বর্তমান ডিরেক্টরি) নির্দিষ্ট করে।
কন্টেইনার চালানো
একবার আপনার একটি ইমেজ থাকলে, আপনি একটি কন্টেইনার চালাতে পারেন:
docker run -p 3000:3000 -d my-node-app
এটি আপনার হোস্টের পোর্ট 3000-কে কন্টেইনারের পোর্ট 3000-এ ম্যাপ করে এবং ডিটাচড মোডে (-d) চালায়।
সাধারণ কমান্ড:
docker ps– চলমান কন্টেইনার তালিকাdocker ps -a– সমস্ত কন্টেইনার তালিকা (বন্ধগুলো সহ)docker stop <container_id>– একটি কন্টেইনার বন্ধ করুনdocker rm <container_id>– একটি কন্টেইনার মুছুনdocker images– ইমেজ তালিকাdocker rmi <image_id>– একটি ইমেজ মুছুন
ভলিউম দিয়ে ডেটা পরিচালনা
কন্টেইনারগুলো ক্ষণস্থায়ী; যখন সেগুলো মুছে ফেলা হয়, তাদের ডেটা হারিয়ে যায়। ডেটা সংরক্ষণ করতে, ভলিউম ব্যবহার করুন। একটি ভলিউম হলো কন্টেইনারের ফাইলসিস্টেমের বাইরে একটি ডিরেক্টরি, যা Docker দ্বারা পরিচালিত হয়।
docker run -v my_volume:/app/data my-node-app
আপনি ডেভেলপমেন্টের জন্য একটি হোস্ট ডিরেক্টরি (বাইন্ড মাউন্ট) মাউন্ট করতে পারেন:
docker run -v $(pwd):/app my-node-app
Docker Compose: মাল্টি-কন্টেইনার অ্যাপ্লিকেশন
বাস্তব-জগতের অ্যাপগুলো প্রায়ই একাধিক সার্ভিস প্রয়োজন: একটি ওয়েব সার্ভার, একটি ডেটাবেস, একটি ক্যাশ, ইত্যাদি। Docker Compose আপনাকে একটি YAML ফাইল ব্যবহার করে মাল্টি-কন্টেইনার Docker অ্যাপ্লিকেশন সংজ্ঞায়িত এবং চালানোর সুযোগ দেয়। এখানে একটি PostgreSQL ডেটাবেসসহ একটি Node.js অ্যাপের জন্য একটি উদাহরণ docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:password@db:5432/mydb
depends_on:
- db
db:
image: postgres:15-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
সম্পূর্ণ স্ট্যাক চালান:
docker compose up -d
এটি web সার্ভিস বিল্ড করে, Postgres ইমেজ পুল করে, একটি নেটওয়ার্ক তৈরি করে, এবং উভয় কন্টেইনার শুরু করে। depends_on নিশ্চিত করে যে ডেটাবেস web সার্ভিসের আগে শুরু হয়।
কন্টেইনার, নেটওয়ার্ক, এবং ভলিউম বন্ধ এবং মুছে ফেলতে:
docker compose down -v
ডেভেলপমেন্টে Docker-এর জন্য সেরা অনুশীলন
- .dockerignore ব্যবহার করুন বিল্ড কনটেক্সট থেকে
node_modulesএবং.git-এর মতো ফাইল বাদ দিতে। - মাল্টি-স্টেজ বিল্ড ব্যবহার করুন ইমেজ ছোট রাখতে। উদাহরণস্বরূপ, একটি স্টেজে আপনার অ্যাপ বিল্ড করুন এবং শুধুমাত্র প্রোডাকশন আর্টিফ্যাক্টগুলো একটি ছোট রানটাইম ইমেজে কপি করুন।
- ভার্সন পিন করুন আপনার Dockerfile-এ (যেমন,
node:latest-এর পরিবর্তেnode:18-alpine) পুনরুৎপাদনযোগ্যতার জন্য। - স্থায়ী ডেটার জন্য ভলিউম ব্যবহার করুন এবং ডেভেলপমেন্টের সময় লাইভ কোড রিলোডিংয়ের জন্য বাইন্ড মাউন্ট ব্যবহার করুন।
- কন্টেইনার স্টেটলেস রাখুন; স্টেট ভলিউম বা বাহ্যিক সার্ভিসে সংরক্ষণ করুন।
তুলনা: Docker বনাম ভার্চুয়াল মেশিন
| দিক | Docker কন্টেইনার | ভার্চুয়াল মেশিন |
|---|---|---|
| স্টার্টআপ সময় | সেকেন্ড | মিনিট |
| রিসোর্স ব্যবহার | হালকা (OS কার্নেল শেয়ার করে) | ভারী (প্রতি VM-এ সম্পূর্ণ OS) |
| আইসোলেশন | প্রসেস-লেভেল | হার্ডওয়্যার-লেভেল |
| পোর্টেবিলিটি | উচ্চ (Docker যেখানে চলে সেখানে চলে) | হাইপারভাইজার সামঞ্জস্যতা দ্বারা সীমাবদ্ধ |
FAQ
একটি ইমেজ এবং একটি কন্টেইনারের মধ্যে পার্থক্য কী?
একটি ইমেজ হলো একটি রিড-অনলি টেমপ্লেট যা অ্যাপ্লিকেশন এবং এর পরিবেশ সংজ্ঞায়িত করে। একটি কন্টেইনার হলো একটি ইমেজের চলমান ইনস্ট্যান্স। আপনি একই ইমেজ থেকে একাধিক কন্টেইনার তৈরি করতে পারেন।
আমি কখন Docker Compose ব্যবহার করব?
যখন আপনার অ্যাপ্লিকেশন একাধিক সার্ভিস (যেমন, ওয়েব সার্ভার, ডেটাবেস, ক্যাশ) নিয়ে গঠিত যা একসাথে কাজ করতে হবে তখন Docker Compose ব্যবহার করুন। এটি ডেভেলপমেন্ট এবং টেস্টিংয়ের জন্য অর্কেস্ট্রেশন সরল করে।
আমি Docker-এ ডেটা কীভাবে সংরক্ষণ করব?
কন্টেইনারের ফাইলসিস্টেমের বাইরে ডেটা সংরক্ষণ করতে ভলিউম ব্যবহার করুন। ভলিউমগুলো Docker দ্বারা পরিচালিত হয় এবং কন্টেইনারগুলোর মধ্যে শেয়ার করা যায়। হোস্ট ডিরেক্টরি মাউন্ট করতেও বাইন্ড মাউন্ট ব্যবহার করা যায়।
আপনার পরবর্তী প্রকল্প কন্টেইনারাইজ করতে প্রস্তুত? একটি সহজ অ্যাপের জন্য একটি Dockerfile লিখে শুরু করুন, তারপর Docker Compose দিয়ে ধীরে ধীরে সার্ভিস যোগ করুন। আরও ডেভেলপার টুলের জন্য, আপনার কনফিগারেশন ফাইল ভ্যালিডেট এবং বিউটিফাই করতে আমাদের JSON Formatter দেখুন।