Core Concept & Architecture (ডকারের)

সহজ কথায়, ডকার হলো OS-level virtualization। এটি হাইপারভাইজরের মতো পুরো হার্ডওয়্যার সিমুলেট করে না, বরং হোস্ট অপারেটিং সিস্টেমের Kernel শেয়ার করে।

ডকারের আসল জাদুকর: ডকার মূলত লিনাক্স কার্নেলের দুটি প্রধান ফিচারের ওপর দাঁড়িয়ে:

ডকার ইমেজ বনাম কন্টেইনার:

ডকার কখন ‘ফেল’ করে:

ইমেজ ম্যানেজমেন্ট (ইমেজ নিয়ে কাজ করার জন্য)

ইমেজ হলো আপনার অ্যাপ্লিকেশনের “ব্লু-প্রিন্ট”।

  1. docker build -t <image-name> . : আপনার Dockerfile থেকে একটি ইমেজ তৈরি (Build) করে। -t দিয়ে ইমেজের একটা নাম দেওয়া হয়।

  2. docker images : আপনার কম্পিউটারে বর্তমানে কতগুলো ইমেজ ডাউনলোড করা বা তৈরি করা আছে তার লিস্ট দেখায়।

  3. docker rmi <image-id> : অপ্রয়োজনীয় কোনো ইমেজ ডিলিট করার জন্য। (rmi = Remove Image)

  4. docker pull <image-name> : Docker Hub থেকে কোনো ইমেজ ডাউনলোড করার জন্য (যেমন: docker pull postgres)।

কন্টেইনার লাইফসাইকেল (কন্টেইনার চালানো ও বন্ধ করা)

  1. docker run <image-name> : ইমেজ থেকে একটি নতুন কন্টেইনার তৈরি করে এবং সেটি চালু করে।

  2. docker run -d -p 5000:5000 <image-name> :
    • -d (Detached mode): কন্টেইনার ব্যাকগ্রাউন্ডে চলবে।
    • -p (Port mapping): হোস্টের ৫০০০ পোর্টের সাথে কন্টেইনারের ৫০০০ পোর্ট কানেক্ট করবে।
  3. -d (Detached mode): কন্টেইনার ব্যাকগ্রাউন্ডে চলবে।

  4. -p (Port mapping): হোস্টের ৫০০০ পোর্টের সাথে কন্টেইনারের ৫০০০ পোর্ট কানেক্ট করবে।

  5. docker ps : বর্তমানে কোন কোন কন্টেইনার চলছে তার লিস্ট দেখায়।

  6. docker ps -a : সব কন্টেইনারের লিস্ট দেখায় (সেটা চলুক বা বন্ধ থাকুক)।

  7. docker stop <container-id> : রানিং কোনো কন্টেইনারকে থামিয়ে দেয়।

  8. docker start <container-id> : বন্ধ হয়ে থাকা (Exited) কোনো কন্টেইনারকে আবার চালু করে।

  9. docker rm <container-id> : কোনো কন্টেইনার পার্মানেন্টলি ডিলিট করে দেয়।

কন্টেইনারের ভেতরে উঁকি দেওয়া (Debugging)

ডেভেলপমেন্টের সময় কন্টেইনারের ভেতর কী হচ্ছে তা দেখার জন্য এগুলো লাগে।

  1. docker logs <container-id> : কন্টেইনারের কনসোলে কী কী আউটপুট বা এরর আসছে তা দেখার জন্য।

  2. docker logs -f <container-id> : লাইভ লগ দেখার জন্য (যেমনটা আপনি টার্মিনালে দেখেন)।

  3. docker exec -it <container-id> sh (বা bash) : কন্টেইনারের ভেতরে ঢোকার জন্য। অনেকটা SSH করার মতো। এর ভেতরে ঢুকে আপনি ফাইল চেক করতে পারেন।

  4. docker inspect <container-id> : কন্টেইনারের IP address, মাউন্ট করা ভলিউমসহ সব টেকনিক্যাল ডিটেইলস দেখার জন্য।

হাউস-কিপিং

ডকার অনেক সময় প্রচুর ডিস্ক স্পেস দখল করে ফেলে।

  1. docker system prune : এক কমান্ডে সব বন্ধ থাকা কন্টেইনার, অব্যবহৃত নেটওয়ার্ক এবং ক্যাশ ডিলিট করে দেয়। (সাবধানে ব্যবহার করবেন!)

  2. docker volume ls : আপনার সিস্টেমে কতগুলো ডকার ভলিউম (যেখানে ডাটা সেভ থাকে) আছে তা দেখার জন্য।

Run a web server container

docker run -d -p 8080:80 --name my-nginx nginx
  1. Open http://localhost:8080 in your browser to see nginx running!
  2. The -d flag is crucial for long-running services
  3. Port mapping format is always host:container

View running containers and logs

docker ps
docker logs my-nginx
  1. Refresh http://localhost:8080 in your browser and run docker logs my-nginx again to see new log entries
  2. Use docker logs -f my-nginx to follow logs in real-time (like tail -f)

Stop and remove containers

docker stop my-nginx
docker ps -a
docker rm my-nginx
docker ps -a
  1. You can combine: docker rm -f my-nginx to force-remove a running container
  2. Use docker container prune to remove all stopped containers at once
  3. Removing a container doesn’t remove the image - it’s still cached

Practice: Run and interact with a container

docker run -d -p 8081:80 --name my-apache httpd
docker ps
docker logs my-apache
docker stop my-apache
docker rm my-apache
  1. Try different port numbers to avoid conflicts
  2. Practice naming containers with --name for easier management
  3. Use docker images to see all the images you’ve downloaded

Search for images on Docker Hub

docker search nginx
docker search --filter stars=1000 nginx
  1. Look for OFFICIAL images (marked [OK]) - they’re maintained by Docker or the software vendor
  2. High star count usually indicates a well-maintained, popular image
  3. Check the image description for specific use cases

Pull a specific image

docker pull nginx
  1. Images are downloaded in layers - Docker reuses layers across images to save space
  2. The first pull takes time, but subsequent pulls reuse existing layers

Understanding image tags

docker pull nginx:1.25
docker pull nginx:alpine
docker images nginx
  1. Alpine images are typically 5-10x smaller than standard images

  2. Use specific version tags (like 1.25) in production to ensure consistency

  3. Check Docker Hub for available tags and their documentation

Inspect image details

docker inspect nginx:latest
docker history nginx:latest
  1. Use docker inspect nginx:latest | grep -A 10 Env to see just environment variables
  2. History shows how the image was built - useful for learning Dockerfile patterns
  3. Layers marked are from multi-stage builds or external registries

List all local images

docker images
docker images --format "table \t\t"
  1. Images are identified by REPOSITORY:TAG or IMAGE ID
  2. The same image can have multiple tags (aliases)
  3. Size shown is the compressed size; actual disk usage may differ due to shared layers

Understanding image layers

docker pull python:3.11
docker pull python:3.11-alpine
docker images python
  1. Alpine images save disk space and reduce attack surface
  2. Standard images include more tools, useful for debugging
  3. Choose alpine for production, standard for development

Tag an existing image

Create your own tag (alias) for an image.

docker tag nginx:latest my-nginx:v1
docker images | grep nginx
  1. Tags are just labels - multiple tags can point to the same image
  2. Use meaningful tag names for your custom images
  3. Format: repository:tag or registry/repository:tag for remote registries

View image disk usage

docker system df
docker system df -v
  1. Shared layers mean total size is less than sum of all images
  2. Reclaimable space shows what can be freed by removing unused images
  3. Run this regularly to monitor Docker’s disk usage

Remove unused images

docker rmi python:3.11
docker images
docker image prune -a
  1. Can’t remove images used by containers (even stopped ones)
  2. Remove containers first with docker container prune
  3. The -a flag is important - without it, only dangling images are removed

Practice: Find and pull a specific image version

Apply what you’ve learned to work with a different image.

docker search redis
docker pull redis:7-alpine
docker inspect redis:7-alpine | grep -A 5 ExposedPorts
docker rmi redis:7-alpine
  1. Always check the official image documentation on Docker Hub
  2. Use alpine variants when image size matters
  3. Inspect images to understand their configuration before running

Understanding container states

Learn about the different states a container can be in: created, running, paused, exited.

docker run -d --name demo-nginx nginx
docker ps
docker stop demo-nginx
docker ps -a
  1. Running containers consume resources; stopped containers don’t
  2. Stopped containers retain their filesystem and configuration
  3. You can restart stopped containers without losing data

Start and restart containers

docker start demo-nginx
docker ps
docker restart demo-nginx
docker ps
  1. Use ‘start’ for stopped containers, ‘restart’ for running ones
  2. Restart is useful for applying configuration changes
  3. The container retains its IP address and volumes after restart

Pause and unpause containers

Temporarily freeze a container’s processes without stopping it.

docker pause demo-nginx
docker ps
docker unpause demo-nginx
docker ps
  1. Paused containers still occupy memory
  2. Use pause for debugging or temporarily reducing system load
  3. Unlike stop/start, pause/unpause is instantaneous

Execute commands in running containers

Run commands inside a live container without stopping it.

docker exec demo-nginx ls /usr/share/nginx/html
docker exec demo-nginx cat /etc/nginx/nginx.conf
docker exec -it demo-nginx bash
  1. Exec is perfect for debugging running containers
  2. The container must be running to use exec
  3. Common commands: bash, sh, cat, ls, ps
  4. Type ‘exit’ to leave the shell - the container keeps running

View container logs with filters

docker logs demo-nginx
docker logs --tail 20 demo-nginx
docker logs --since 5m demo-nginx
docker logs -f demo-nginx
  1. Timestamps help correlate logs with events: –timestamps
  2. Combine options: docker logs –tail 50 –since 1h container
  3. Logs persist even after container stops
  4. Use grep to filter: docker logs demo-nginx grep error

Detached Mode (-d)

docker run -d -p 3000:3000 ts-docker:v1
docker start --attach ts-docker-container
  1. লাইভ লগ দেখা (Debugging): আপনার TypeScript অ্যাপ্লিকেশনে যদি কোনো বাগ (bug) থাকে বা কোড রান করার সময় কোনো এরর হয়, তবে –attach করলে সেই এরর মেসেজটি আপনি সরাসরি টার্মিনালে দেখতে পাবেন।
  1. ইন্টারঅ্যাক্টিভ কাজ (Input/Output): যদি আপনার অ্যাপটি ইউজারের কাছ থেকে কোনো ইনপুট চায়, তবে –attach ছাড়া আপনি সেই ইনপুট দিতে পারবেন না। এটি আপনার টার্মিনালকে কন্টেইনারের সাথে সরাসরি পাইপের মতো জুড়ে দেয়।

  2. কন্টেইনারের বর্তমান অবস্থা বোঝা: কখনও কখনও docker start দিলে মনে হয় কন্টেইনারটি চালু হয়েছে, কিন্তু আসলে সেটি ২ সেকেন্ড পরেই বন্ধ হয়ে যায়। –attach করলে আপনি দেখতে পাবেন কেন সেটি দ্রুত বন্ধ হয়ে যাচ্ছে (যেমন: কোনো ফাইল মিসিং বা কনফিগারেশন ভুল)।

Inspect container details

docker inspect demo-nginx
docker inspect --format '' demo-nginx
docker inspect --format '' demo-nginx
docker inspect --format '' demo-nginx
  1. Inspect shows everything: environment, volumes, networks, ports
  2. Use jq for better JSON formatting: docker inspect demo-nginx jq
  3. Check State section for detailed status information
  4. NetworkSettings shows IP, ports, and network configuration

Monitor container resource usage

docker stats demo-nginx
docker stats --no-stream demo-nginx
  1. Run ‘docker stats’ (no name) to see all containers
  2. Use this to identify resource-hungry containers
  3. Memory % is of total system memory
  4. NET I/O shows total data sent/received

Copy files between host and container

echo '<h1>Hello from Docker!</h1>' > custom.html
docker cp custom.html demo-nginx:/usr/share/nginx/html/
docker exec demo-nginx cat /usr/share/nginx/html/custom.html
docker cp demo-nginx:/etc/nginx/nginx.conf ./nginx-backup.conf
  1. Copy directories: docker cp ./folder container:/path/
  2. Works even if container is stopped
  3. Use this for quick config changes or log extraction
  4. For persistent data, use volumes instead (covered in later lessons)

Rename and update containers

docker rename demo-nginx my-webserver
docker ps
docker update --memory 512m my-webserver
docker inspect --format '' my-webserver
  1. Names must be unique across all containers
  2. Update is useful for adjusting resources without downtime
  3. Not all settings can be updated - some require recreating the container
  4. Common updates: –memory, –cpu-shares, –restart

View container differences

docker diff my-webserver
  1. A = Added, C = Changed, D = Deleted
  2. Helps debug containers with unexpected behavior
  3. Shows why containers are larger than their images
  4. Use this before committing a container to an image

Attach to a running container

docker run -d --name test-ubuntu ubuntu bash -c 'while true; do date; sleep 2; done'
docker attach test-ubuntu
  1. Attach is different from exec - it connects to PID 1
  2. Use Ctrl+P, Ctrl+Q to detach without stopping
  3. Exec is usually better for interactive work
  4. Attach is useful for seeing real-time output

Container cleanup strategies

docker stop my-webserver test-ubuntu
docker rm my-webserver test-ubuntu
docker ps -a
docker container prune
docker ps -a
  1. Use ‘docker rm -f $(docker ps -aq)’ to remove all containers (careful!)
  2. Add –rm flag when running containers for automatic cleanup
  3. Prune regularly to avoid accumulating stopped containers
  4. Remove containers before removing their images

ভলিউম কী এবং কেন?

মনে করুন, আপনার একটা স্মার্টফোন আছে (Container)। ফোনের ভেতরে আপনি কিছু ছবি তুললেন। এখন ফোনটা যদি পানিতে পড়ে নষ্ট হয়ে যায় বা হারিয়ে যায়, তবে আপনার সব ছবিও শেষ।

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

ডকার ভলিউম ঠিক ওই এসডি কার্ডের মতো কাজ করে।

  1. কন্টেইনারের সাথে এর কাহিনী কী? ডকার কন্টেইনারের ভেতরে আপনি যা-ই করবেন (কোনো ফাইল সেভ করা, ডাটাবেজ বানানো), তা কন্টেইনার ডিলিট করার সাথে সাথে মুছে যায়।

🛠️ হাতে কলমে প্রথম পাঠ (ভলিউম তৈরি ও ব্যবহার)

চলুন আমরা একটা এসডি কার্ড (Volume) কিনি এবং সেটা কন্টেইনারে লাগাই।

docker run -it --name phone1 -v my_sd_card:/app_data alpine sh

এই কমান্ডের মানে বুঝুন: -v my_sd_card:/app_data: এর মানে হলো, আমার তৈরি করা my_sd_card ভলিউমটিকে কন্টেইনারের ভেতরের /app_data ফোল্ডারের সাথে কানেক্ট করো।

docker rm phone1

(আপনার কন্টেইনার এখন ভ্যানিশ!)

এখন কন্টেইনারের ভেতরে গিয়ে দেখুন:

cat /some_other_folder/file.txt

আউটপুট আসবে: I have a plan

এখানে প্রত্যেকটি অংশের কাজ আলাদা:

২. এই ভলিউম (my_sd_card) আসলে থাকে কোথায়?

আপনি যখন docker volume create my_sd_card লিখেন, ডকার আপনার পিসির হার্ড ড্রাইভের একটি বিশেষ জায়গায় একটা ফোল্ডার তৈরি করে।

৩. phone1 ডিলিট করলে ডাটা থাকল কীভাবে? আর উদ্ধার (Rescue) হলো কীভাবে?

লিনাক্সে আপনার ভলিউমটি কোথায় আছে দেখুন:

docker volume inspect my_sd_card
"Mountpoint": "/var/lib/docker/volumes/my_sd_card/_data"
sudo ls /var/lib/docker/volumes/my_sd_card/_data

মূল কাহিনী (The Summary)

ডকার কন্টেইনারের ভেতর আপনি যা করবেন, কন্টেইনার ডিলিট করলে সব মুছে যাবে। এটা বাঁচানোর ২টা উপায় আছে:

Practice: Complete container lifecycle

docker run -d --name practice-redis redis:alpine
docker ps
docker exec practice-redis redis-cli PING
docker logs practice-redis
docker stats --no-stream practice-redis
docker pause practice-redis
docker unpause practice-redis
docker restart practice-redis
docker stop practice-redis
docker rm practice-redis
  1. This is a typical workflow for managing containers in development
  2. Always verify containers are running before executing commands
  3. Monitor resource usage to catch problems early
  4. Clean up containers when done to avoid clutter

Run a container from your custom image

docker run my-ubuntu:v1
docker run my-ubuntu:v1 curl --version
  1. Any command after the image name overrides the CMD
  2. The image includes all changes from RUN instructions
  3. Containers from the same image are identical at start
  4. Changes inside containers don’t affect the image

Understanding Dockerfile instructions

cat > Dockerfile << 'EOF'
# Base image
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy files
COPY package.json .

# Run commands
RUN npm install

# Copy application code
COPY . .

# Expose port
EXPOSE 3000

# Set environment variable
ENV NODE_ENV=production

# Default command
CMD ["node", "app.js"]
EOF

কেন alpine? এটি খুব গুরুত্বপূর্ণ। আলপাইন হলো লিনাক্সের সবথেকে হালকা ভার্সন। সাধারণ উবুন্টু ইমেজ ২০০এমবি হলে, আলপাইন মাত্র ৫এমবি। ইন্টারভিউতে বলবেন— “ইমেজ সাইজ ছোট রাখার জন্য আমি আলপাইন ব্যবহার করেছি।”

সুবিধা: এরপর আপনি যা কপি করবেন বা রান করবেন, সব এই /app ফোল্ডারের ভেতরেই হবে। পিসিতে cd /app করার মতো।

মাস্টার টিপস (Layer Caching): খেয়াল করুন, আপনি কিন্তু সব ফাইল একসাথে কপি করেননি, শুধু package.json করেছেন। কেন? কারণ ডকার প্রতিটি লাইনকে একটি Layer হিসেবে সেভ করে। যদি আপনার কোড চেঞ্জ হয় কিন্তু প্যাকেজ চেঞ্জ না হয়, তবে ডকার আগের লেয়ার থেকে npm install এর রেজাল্ট নিয়ে নেয়। এতে বিল্ড অনেক ফাস্ট হয়।

মনে রাখবেন: RUN চলে ইমেজ বানানোর সময়, আর CMD চলে কন্টেইনার রান করার সময়।

Build arguments and customization

FROM node:20-alpine
ARG NODE_ENV=development
ARG PORT=3000

WORKDIR /app
COPY package.json .
RUN npm install
COPY . .

EXPOSE ${PORT}
ENV NODE_ENV=${NODE_ENV}}
ENV PORT=${PORT}

CMD [ "node", "app.js" ]

ENV (Runtime): এটি কন্টেইনার চলার সময় কাজে লাগে। অ্যাপের ভেতরে কোড যখন রান করবে, তখন সে এই ভ্যালুগুলো দেখতে পাবে।

ARG NODE_ENV=development: এটি একটি ডিফল্ট মান। যদি আপনি বিল্ড করার সময় কিছু না বলেন, তবে সে development ধরে নেবে।

ENV NODE_ENV=${NODE_ENV}: এটি জাদুকরী লাইন! এখানে আপনি ARG এর মানটিকে ENV-এ ট্রান্সফার করছেন। কারণ আপনার নোড অ্যাপ (app.js) শুধু ENV পড়তে পারে, ARG নয়।

প্রথম বিল্ড (Dev Version): docker build -t my-node-app:dev .

এখানে আপনি কোনো –build-arg দেননি।

ফলাফল: এই ইমেজের ভেতর পোর্ট হবে 3000 আর এনভায়রনমেন্ট হবে development।

docker build -t my-node-app:prod --build-arg NODE_ENV=production --build-arg PORT=8080 .

আমি ARG ব্যবহার করে একই Dockerfile দিয়ে ডাইনামিক ইমেজ বানাতে পারি। এতে কোড ডুপ্লিকেট হয় না (DRY - Don’t Repeat Yourself)