ডেভেলপারদের জন্য Docker: ইমেজ, কন্টেইনার এবং Compose
আপনি একটি অ্যাপ তৈরি করেছেন যা আপনার মেশিনে কাজ করে, কিন্তু ডিপ্লয় করার সময় সমস্যা দেখা দেয়। ডিপেন্ডেন্সি মিসিং, ভার্সন ভিন্ন, আর কনফিগারেশন এলোমেলো। Docker এই সমস্যার সমাধান করে আপনার অ্যাপ্লিকেশন এবং তার এনভায়রনমেন্টকে একটি পোর্টেবল ইউনিটে প্যাকেজ করে। এই আর্টিকেলে ব্যবহারিক উদাহরণসহ Docker ইমেজ, কন্টেইনার এবং Docker Compose ব্যাখ্যা করা হয়েছে যাতে আপনি আপনার ডেভেলপমেন্ট ওয়ার্কফ্লো সহজ করতে পারেন।
Docker ইমেজ কী?
একটি Docker ইমেজ হলো একটি read-only টেমপ্লেট যা আপনার অ্যাপ্লিকেশন কোড, রানটাইম, লাইব্রেরি, এনভায়রনমেন্ট ভেরিয়েবল এবং কনফিগারেশন ফাইল ধারণ করে। এটিকে আপনার অ্যাপের এনভায়রনমেন্টের স্ন্যাপশট হিসেবে ভাবুন। ইমেজ একটি Dockerfile থেকে বিল্ড করা হয়, যা ইনস্ট্রাকশনসহ একটি টেক্সট ফাইল।
একটি Node.js অ্যাপের জন্য একটি সাধারণ Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
প্রতিটি ইনস্ট্রাকশন একটি লেয়ার তৈরি করে। লেয়ারগুলো ক্যাশ করা হয়, তাই কোড পরিবর্তনের পর রিবিল্ড করলে শুধু পরিবর্তিত লেয়ার থেকে পরবর্তী ধাপগুলো আবার চলে। এতে বিল্ড দ্রুত হয়।
Docker কন্টেইনার কী?
একটি কন্টেইনার হলো একটি ইমেজের চলমান ইনস্ট্যান্স। এটি নিজস্ব ফাইলসিস্টেম, নেটওয়ার্ক এবং প্রসেস স্পেসসহ একটি আইসোলেটেড প্রসেস, তবে এটি হোস্ট OS কার্নেল শেয়ার করে। এতে কন্টেইনারগুলো হালকা এবং ভার্চুয়াল মেশিনের তুলনায় দ্রুত স্টার্ট হয়।
একটি ইমেজ থেকে কন্টেইনার চালাতে:
docker run -d -p 3000:3000 --name myapp my-node-app
এটি ডিটাচড মোডে (-d) একটি কন্টেইনার শুরু করে, হোস্টের পোর্ট 3000 কে কন্টেইনারের পোর্ট 3000-এ ম্যাপ করে (-p 3000:3000), এবং এর নাম দেয় myapp।
কন্টেইনার ডিফল্টভাবে এফিমেরাল। ভিতরে লেখা যেকোনো ডেটা কন্টেইনার থামলে হারিয়ে যায়। ডেটা সংরক্ষণের জন্য ভলিউম ব্যবহার করুন:
docker run -v /host/data:/app/data my-node-app
Docker Compose কেন ব্যবহার করবেন?
বাস্তব অ্যাপ্লিকেশনে প্রায়ই একাধিক সার্ভিসের প্রয়োজন হয়: একটি ওয়েব সার্ভার, একটি ডেটাবেস, একটি ক্যাশ ইত্যাদি। প্রতিটিকে docker run দিয়ে চালানো এবং ম্যানুয়ালি লিংক করা কষ্টসাধ্য। Docker Compose একটি YAML ফাইল দিয়ে মাল্টি-কন্টেইনার অ্যাপ ডিফাইন ও রান করতে দেয়।
PostgreSQL এবং Redis সহ একটি Node.js অ্যাপের জন্য docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
- REDIS_URL=redis://cache:6379
depends_on:
- db
- cache
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7
volumes:
pgdata:
সবকিছু চালান:
docker compose up -d
Compose একটি নেটওয়ার্ক তৈরি করে যাতে সার্ভিসগুলো নাম দিয়ে একে অপরের কাছে পৌঁছাতে পারে (যেমন db, cache)। এটি ভলিউম তৈরি এবং ডিপেন্ডেন্সি অর্ডারও হ্যান্ডেল করে।
ডেভেলপারদের জন্য গুরুত্বপূর্ণ Docker কমান্ড
docker build -t myapp .– বর্তমান ডিরেক্টরির Dockerfile থেকে একটি ইমেজ বিল্ড করুন।docker images– লোকাল ইমেজের তালিকা দেখুন।docker ps– চলমান কন্টেইনারের তালিকা দেখুন (সব দেখতে-aযোগ করুন)।docker exec -it myapp sh– চলমান কন্টেইনারের ভিতরে একটি শেল খুলুন।docker logs myapp– কন্টেইনার লগ দেখুন।docker compose down– Compose-এ ডিফাইন করা কন্টেইনার, নেটওয়ার্ক এবং ভলিউম থামান ও সরান।
ডেভেলপমেন্টে Docker-এর জন্য সেরা অনুশীলন
- .dockerignore ব্যবহার করুন বিল্ড কনটেক্সট থেকে node_modules, .git এবং অন্যান্য অপ্রয়োজনীয় ফাইল বাদ দিতে।
- মাল্টি-স্টেজ বিল্ড ব্যবহার করুন প্রোডাকশন ইমেজ ছোট রাখতে। উদাহরণস্বরূপ, একটি স্টেজে আপনার অ্যাপ বিল্ড করুন এবং শুধু আর্টিফ্যাক্টগুলো একটি মিনিমাল রানটাইম ইমেজে কপি করুন।
- ভার্সন পিন করুন আপনার Dockerfile-এ (যেমন
node:latest-এর বদলেnode:18-alpine) রিপ্রোডিউসিবল বিল্ডের জন্য। - কোডের জন্য ভলিউম ব্যবহার করুন ডেভেলপমেন্টের সময় হট রিলোডিং-এর জন্য: Compose-এ
volumes: - .:/app। - প্রোডাকশনে root হিসেবে চালাবেন না। আপনার Dockerfile-এ একটি নন-রুট ইউজার তৈরি করুন।
সাধারণ ভুল এবং সেগুলো এড়ানোর উপায়
ভুল ১: ভারী ইমেজ। ubuntu-এর মতো সম্পূর্ণ OS বেস ইমেজ ব্যবহার করলে 1GB+ ইমেজ হতে পারে। slim বা alpine ভ্যারিয়েন্ট ব্যবহার করুন।
ভুল ২: ধীর বিল্ড। Dockerfile ইনস্ট্রাকশনগুলো কম পরিবর্তনশীল থেকে বেশি পরিবর্তনশীল ক্রমে সাজান। সোর্স কোড কপি করার আগে প্যাকেজ ফাইল কপি করে ডিপেন্ডেন্সি ইনস্টল করুন।
ভুল ৩: ডেটা লস। ডেটাবেসের জন্য সবসময় ভলিউম ব্যবহার করুন। ভলিউম ছাড়া কন্টেইনার সরালে ডেটা হারিয়ে যায়।
ভুল ৪: নেটওয়ার্কিং বিভ্রান্তি। Compose-এ সার্ভিসগুলো ডিফল্ট নেটওয়ার্কে সার্ভিস নামকে হোস্টনেম হিসেবে ব্যবহার করে যোগাযোগ করে। অন্য সার্ভিসে পৌঁছাতে localhost ব্যবহার করবেন না।
FAQ
ইমেজ এবং কন্টেইনারের মধ্যে পার্থক্য কী?
একটি ইমেজ হলো read-only টেমপ্লেট; একটি কন্টেইনার হলো সেই ইমেজের চলমান ইনস্ট্যান্স। একই ইমেজ থেকে একাধিক কন্টেইনার চালাতে পারেন।
প্রোডাকশনে Docker Compose ব্যবহার করা যায়?
Compose মূলত ডেভেলপমেন্ট ও টেস্টিং-এর জন্য। প্রোডাকশনের জন্য Kubernetes বা Docker Swarm-এর মতো অর্কেস্ট্রেটর বিবেচনা করুন, যদিও সাধারণ ডিপ্লয়মেন্টের জন্য Compose কাজ করতে পারে।
নতুন কোড দিয়ে কন্টেইনার কীভাবে আপডেট করব?
docker build দিয়ে ইমেজ রিবিল্ড করুন এবং তারপর কন্টেইনার পুনরায় তৈরি করুন: docker compose up -d --build।
আপনার ডেভেলপমেন্ট ওয়ার্কফ্লো সহজ করতে প্রস্তুত? আপনার কন্টেইনারাইজড ওয়েব সার্ভার লগ দ্রুত ডিবাগ করতে আমাদের Nginx Log Analyzer ব্যবহার করে দেখুন।