Docker আমাদের সফটওয়্যার তৈরি, শিপ এবং চালানোর পদ্ধতি বদলে দিয়েছে। "আমার মেশিনে কাজ করে"-এর বদলে, Docker নিশ্চিত করে যে আপনার অ্যাপ্লিকেশন সব জায়গায় একইভাবে চলবে - আপনার ল্যাপটপে, সহকর্মীর মেশিনে, CI/CD-তে এবং প্রোডাকশনে। এই গাইডে, আমরা শূন্য থেকে শুরু করে একটি বাস্তব অ্যাপ্লিকেশন ডিপ্লয় করা পর্যন্ত যাব।
Docker কী?
Docker হলো একটি প্ল্যাটফর্ম যা আপনার অ্যাপ্লিকেশন এবং এর সমস্ত নির্ভরতা একটি মানসম্মত ইউনিটে প্যাকেজ করে যাকে কন্টেইনার বলা হয়। কন্টেইনার হলো একটি বিচ্ছিন্ন, হালকা প্রক্রিয়া যা হোস্ট OS কার্নেল শেয়ার করে কিন্তু এর নিজস্ব ফাইলসিস্টেম, নেটওয়ার্ক এবং প্রক্রিয়া স্থান আছে।
কন্টেইনার বনাম ভার্চুয়াল মেশিন
| দিক | কন্টেইনার | ভার্চুয়াল মেশিন |
|---|---|---|
| স্টার্টআপ | সেকেন্ড | মিনিট |
| আকার | MBs | GBs |
| OS | হোস্ট কার্নেল শেয়ার করে | সম্পূর্ণ গেস্ট OS |
| আইসোলেশন | প্রক্রিয়া-স্তর | হার্ডওয়্যার-স্তর |
| পারফরম্যান্স | প্রায় নেটিভ | হাইপারভাইজরের ওভারহেড |
| ঘনত্ব | প্রতি হোস্টে শত শত | প্রতি হোস্টে কয়েক ডজন |
Docker ইনস্টল করা
# macOS brew install --cask docker # Ubuntu/Debian curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Verify installation docker --version docker run hello-world
মূল ধারণা
ইমেজ
একটি ইমেজ হলো একটি রিড-অনলি টেমপ্লেট যাতে কন্টেইনার তৈরির নির্দেশনা থাকে। এটিকে আপনার অ্যাপ্লিকেশন এবং এর পরিবেশের একটি স্ন্যাপশট হিসেবে ভাবুন।
# Pull an image from Docker Hub docker pull node:20-alpine # List local images docker images # Remove an image docker rmi node:20-alpine
কন্টেইনার
কন্টেইনার হলো একটি ইমেজের চলমান ইনস্ট্যান্স। আপনি কন্টেইনার তৈরি, শুরু, বন্ধ এবং মুছে ফেলতে পারেন।
# Run a container docker run -d --name my-app -p 3000:3000 node:20-alpine # List running containers docker ps # List all containers (including stopped) docker ps -a # Stop a container docker stop my-app # Remove a container docker rm my-app # View logs docker logs my-app # Execute a command inside a running container docker exec -it my-app sh
Dockerfile লেখা
Dockerfile হলো একটি টেক্সট ফাইল যাতে ইমেজ তৈরির নির্দেশনা থাকে। প্রতিটি নির্দেশনা একটি লেয়ার তৈরি করে।
Node.js অ্যাপের জন্য বেসিক Dockerfile
# Use an official Node.js runtime as base image FROM node:20-alpine # Set working directory WORKDIR /app # Copy package files first (better caching) COPY package.json package-lock.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port the app runs on EXPOSE 3000 # Command to run the application CMD ["node", "server.js"]
বিল্ড এবং রান
# Build the image docker build -t my-node-app . # Run the container docker run -d -p 3000:3000 my-node-app # Visit http://localhost:3000
মাল্টি-স্টেজ বিল্ড
মাল্টি-স্টেজ বিল্ড বিল্ড পরিবেশকে রানটাইম থেকে আলাদা করে আপনার প্রোডাকশন ইমেজ ছোট রাখে।
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:20-alpine AS runner WORKDIR /app COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
এটি শুধুমাত্র কম্পাইল করা আউটপুট এবং প্রোডাকশন নির্ভরতা সহ একটি ইমেজ তৈরি করে - কোনো সোর্স কোড নেই, কোনো ডেভ নির্ভরতা নেই, কোনো বিল্ড টুল নেই।
Next.js মাল্টি-স্টেজ উদাহরণ
FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static EXPOSE 3000 CMD ["node", "server.js"]
ভলিউম: স্থায়ী ডেটা
ডিফল্টভাবে, কন্টেইনারের ভিতরের ডেটা কন্টেইনার মুছে ফেলার সময় হারিয়ে যায়। ভলিউম এই সমস্যার সমাধান করে।
# Create a named volume docker volume create my-data # Run with a volume docker run -d -v my-data:/app/data my-app # Bind mount (map host directory to container) docker run -d -v $(pwd)/data:/app/data my-app # List volumes docker volume ls
নেটওয়ার্কিং
Docker কন্টেইনারদের যোগাযোগের জন্য বিচ্ছিন্ন নেটওয়ার্ক তৈরি করে।
# Create a custom network docker network create my-network # Run containers on the same network docker run -d --name api --network my-network my-api docker run -d --name db --network my-network postgres:16 # Containers can reach each other by name # From "api" container: postgres://db:5432
Docker Compose
Docker Compose আপনাকে একটি YAML ফাইল দিয়ে মাল্টি-কন্টেইনার অ্যাপ্লিকেশন সংজ্ঞায়িত এবং চালাতে দেয়।
docker-compose.yml
services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb depends_on: - db db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: pgdata:
কমান্ড
# Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down # Rebuild and restart docker compose up -d --build # Scale a service docker compose up -d --scale api=3
.dockerignore
.gitignore-এর মতো, এই ফাইলটি অপ্রয়োজনীয় ফাইলগুলোকে ইমেজে কপি হওয়া থেকে আটকায়।
node_modules .git .env *.md .next dist coverage
প্রোডাকশনের সেরা অনুশীলন
1. ছোট বেস ইমেজ ব্যবহার করুন
# Bad: 1GB+ FROM node:20 # Good: ~180MB FROM node:20-alpine
2. Root হিসেবে চালাবেন না
FROM node:20-alpine RUN addgroup -S app && adduser -S app -G app USER app WORKDIR /home/app COPY . .
3. নির্দিষ্ট ইমেজ ট্যাগ ব্যবহার করুন
# Bad: can change unexpectedly FROM node:latest # Good: pinned version FROM node:20.11-alpine3.19
4. বিল্ড ক্যাশের সুবিধা নিন
আপনার Dockerfile নির্দেশনাগুলো সবচেয়ে কম থেকে সবচেয়ে বেশি পরিবর্তিত হওয়ার ক্রমে সাজান:
FROM node:20-alpine WORKDIR /app # These change rarely - cached COPY package.json package-lock.json ./ RUN npm ci --only=production # This changes often - not cached COPY . .
5. হেলথ চেক
HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1
6. এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করুন
ENV NODE_ENV=production ENV PORT=3000
সাধারণ Docker কমান্ড চিট শিট
# Images docker build -t name:tag . # Build image docker images # List images docker rmi image_name # Remove image docker image prune # Remove unused images # Containers docker run -d -p 3000:3000 image # Run detached docker ps # List running docker stop container_name # Stop docker rm container_name # Remove docker logs -f container_name # Follow logs docker exec -it container sh # Shell into container # Compose docker compose up -d # Start services docker compose down # Stop services docker compose logs -f # Follow all logs docker compose ps # List services # Cleanup docker system prune -a # Remove everything unused
Docker থেকে Kubernetes
Docker পৃথক কন্টেইনার পরিচালনা করে। যখন আপনাকে একাধিক সার্ভারে শত শত কন্টেইনার অর্কেস্ট্রেট করতে হয়, তখন আপনার Kubernetes দরকার। Docker এবং Kubernetes পরিপূরক:
- Docker: কন্টেইনার তৈরি এবং চালায়
- Kubernetes: বড় পরিসরে কন্টেইনার অর্কেস্ট্রেট করে (শিডিউলিং, স্কেলিং, হিলিং)
আপনি যদি পরবর্তী ধাপে আগ্রহী হন, Kubernetes পরিচিতি সম্পর্কে আমার লেখাটি দেখুন।
উপসংহার
Docker আধুনিক ডেভেলপারদের জন্য একটি মৌলিক দক্ষতা। এটি পরিবেশের অসামঞ্জস্যতা দূর করে, ডিপ্লয়মেন্ট সহজ করে, এবং Kubernetes দিয়ে কন্টেইনার অর্কেস্ট্রেশনের ভিত্তি। একটি সহজ Dockerfile দিয়ে শুরু করুন, মাল্টি-সার্ভিস অ্যাপের জন্য Docker Compose-এ যান, এবং আপনি বাড়ার সাথে সাথে মাল্টি-স্টেজ বিল্ড এবং নিরাপত্তার সেরা অনুশীলন গ্রহণ করুন।
Docker শেখার সেরা উপায় হলো আপনি ইতিমধ্যে যে প্রজেক্টে কাজ করছেন সেটি কন্টেইনারাইজ করা। আজই শুরু করুন।