Dockerfile শেখার সময় FROM, RUN, WORKDIR, এবং COPY নিয়ে কাজ করার পর খুব স্বাভাবিকভাবেই একটি প্রশ্ন আসে:
Container start হলে application automatically কীভাবে run করবে?
আমরা যদি শুধু এই ধরনের Dockerfile লিখি—
FROM ubuntu:24.04
RUN apt update
RUN apt install -y golang
WORKDIR /app
COPY ./server.go ./server.go
Enter fullscreen mode Exit fullscreen mode
তাহলে image তৈরি হবে ঠিকই।
Go-ও install হবে।
server.go-ও image-এর মধ্যে চলে যাবে।
কিন্তু container start করলে কি আমাদের Go server automatically চালু হবে?
না।
আমাদের আবার container-এর ভিতরে ঢুকে manually লিখতে হবে:
go run server.go
Enter fullscreen mode Exit fullscreen mode
এটাই সেই জায়গা যেখানে Dockerfile-এর একটি অত্যন্ত গুরুত্বপূর্ণ instruction সামনে আসে:
CMD
CMD আমাদের image-এর default runtime command নির্ধারণ করে।
এই article-এ আমরা দেখব:
- কেন container immediately exit করতে পারে
-
CMDকী -
RUNএবংCMD-এর পার্থক্য - build time বনাম runtime
-
CMDকীভাবে Docker image-এর সঙ্গে থাকে - কীভাবে
CMDoverride করা যায় - এবং একটি real Go server দিয়ে পুরো বিষয়টি hands-onভাবে বোঝা
এই distinction বোঝা Docker-এর fundamental concepts-এর একটি।
1. The Problem: Why Does the Container Exit?
ধরুন আমাদের image তৈরি হয়ে গেছে:
new_go_server:1.0.0
Enter fullscreen mode Exit fullscreen mode
এখন আমরা চালালাম:
docker run new_go_server:1.0.0
Enter fullscreen mode Exit fullscreen mode
কিন্তু কিছুক্ষণ পরেই container বন্ধ হয়ে গেল।
docker ps-এ কিছু নেই।
তখন:
docker ps -a
Enter fullscreen mode Exit fullscreen mode
দিলে দেখা যাবে container-এর status:
Exited
Enter fullscreen mode Exit fullscreen mode
কেন?
কারণ container কোনো GUI application নয় যে শুধু “open” হয়ে থাকবে।
একটি Docker container-এর lifecycle মূলত তার primary process-এর সঙ্গে সম্পর্কিত।
যে process container-এর প্রধান process হিসেবে চলছে সেটি শেষ হয়ে গেলে container-ও শেষ হয়ে যায়। Reference material-এও এই কারণেই default command/process না থাকলে container start হয়ে immediately exit করার বিষয়টি দেখানো হয়েছে।
আমাদের Go application-এর ক্ষেত্রে আমরা চাই:
docker run
↓
Container starts
↓
Go server starts
↓
Server keeps running
↓
Container stays alive
Enter fullscreen mode Exit fullscreen mode
কিন্তু Docker-কে তো আমরা বলিইনি যে server কীভাবে start করবে।
এখানেই CMD প্রয়োজন।
2. What Does CMD Actually Do?
সহজ ভাষায়:
CMDবলে দেয়—কোনো image থেকে container start হলে default হিসেবে কোন command চালানো হবে।
আমাদের ক্ষেত্রে:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
এর অর্থ:
Container starts
↓
Run:
go run server.go
Enter fullscreen mode Exit fullscreen mode
ফলে:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
দিলেই Go server automatically start হবে।
আর manually:
go run server.go
Enter fullscreen mode Exit fullscreen mode
লিখতে হবে না।
এটাই CMD-এর মূল purpose।
3. Our Complete Dockerfile
এখন আগের Dockerfile-এ CMD যোগ করি:
FROM ubuntu:24.04
RUN apt update
RUN apt install -y golang
WORKDIR /app
COPY ./server.go ./server.go
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
এখন আমাদের Dockerfile-এর responsibilities পরিষ্কার:
FROM
↓
Base Image
RUN
↓
Install Dependencies
WORKDIR
↓
Set Working Directory
COPY
↓
Bring Application Code
CMD
↓
Define Default Runtime Command
Enter fullscreen mode Exit fullscreen mode
এটি Dockerfile-এর একটি very useful mental model।
4. The Most Important Concept: RUN vs CMD
Dockerfile শেখার সময় সবচেয়ে common confusion:
“
RUNআরCMD—দুটোই তো command চালায়। তাহলে difference কী?”
Difference হলো কখন এবং কেন command চালানো হচ্ছে।
RUN
RUN execute হয়:
docker build
Enter fullscreen mode Exit fullscreen mode
এর সময়।
CMD
CMD execute হয়:
docker run
Enter fullscreen mode Exit fullscreen mode
এর সময়।
অর্থাৎ:
docker build
│
▼
┌─────────────┐
│ RUN │
└─────────────┘
│
▼
IMAGE
│
│ docker run
▼
┌─────────────┐
│ CMD │
└─────────────┘
│
▼
CONTAINER
Enter fullscreen mode Exit fullscreen mode
Reference material-এও RUN-কে build phase এবং CMD-কে run phase-এর instruction হিসেবে আলাদা করা হয়েছে।
5. What Happens During docker build?
ধরুন আমরা চালালাম:
docker build -t new_go_server:1.0.1 .
Enter fullscreen mode Exit fullscreen mode
Dockerfile:
FROM ubuntu:24.04
RUN apt update
RUN apt install -y golang
WORKDIR /app
COPY ./server.go ./server.go
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
Build-এর সময় Docker:
FROM ubuntu:24.04
↓
RUN apt update
↓
RUN apt install -y golang
↓
WORKDIR /app
↓
COPY server.go
↓
Create Image
Enter fullscreen mode Exit fullscreen mode
কিন্তু এখানে একটি গুরুত্বপূর্ণ বিষয়:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
এই command build-এর সময় execute হয় না।
এটি image-এর configuration/metadata-এর অংশ হিসেবে রাখা হয়।
Reference build flow-এও CMD build step হিসেবে execute না হয়ে image-এর সঙ্গে default runtime instruction হিসেবে সংরক্ষিত হওয়ার বিষয়টি দেখানো হয়েছে।
6. Then What Happens During docker run?
Build শেষ।
আমাদের image:
new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
এখন:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
চালালাম।
Docker image থেকে একটি container তৈরি করবে।
তারপর image-এর মধ্যে থাকা default CMD দেখবে:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
এবং container-এর ভিতরে সেটি execute করবে।
ফলে:
docker run
↓
Create Container
↓
Start Container
↓
Execute CMD
↓
go run server.go
↓
Go Server :8080
Enter fullscreen mode Exit fullscreen mode
Output:
Server is running on :8080
Enter fullscreen mode Exit fullscreen mode
এখন container আর সঙ্গে সঙ্গে exit করবে না, কারণ Go server foreground-এ চলমান process হিসেবে container-কে active রাখছে। Reference hands-on test-এও docker run new_go_server:1.0.1-এর পর CMD থেকে Go server automatically start হওয়ার বিষয়টি দেখানো হয়েছে।
7. Understanding the Exec Form
আমরা লিখেছি:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
এটাকে বলা হয় Exec Form।
এখানে প্রতিটি argument আলাদা string:
"go"
"run"
"server.go"
Enter fullscreen mode Exit fullscreen mode
এবং comma দিয়ে আলাদা করা হয়েছে।
Conceptually এটি:
go run server.go
Enter fullscreen mode Exit fullscreen mode
command-টির equivalent।
Reference material-এ Dockerfile-এর জন্য এই JSON-array/Exec Form syntax-টিকেই ব্যবহার করা হয়েছে।
8. A Critical Mental Model
এখন এই দুইটি statement মনে রাখুন:
RUN
Build the image.
CMD
Run the application when the container starts.
আরও সহজভাবে:
RUN
→ Image তৈরির সময়
CMD
→ Container চালুর সময়
Enter fullscreen mode Exit fullscreen mode
এই একটি distinction Dockerfile-এর অনেক confusion দূর করে।
9. CMD Does NOT Run During Build
এটি beginner-দের একটি common misunderstanding।
ধরুন:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
লিখেছি।
তারপর:
docker build -t go-server:1.0.1 .
Enter fullscreen mode Exit fullscreen mode
চালালাম।
এখানে Go server start হবে না।
আপনি build output-এ:
Server is running on :8080
Enter fullscreen mode Exit fullscreen mode
দেখবেন না।
কারণ CMD তখন execute হয়নি।
Image তৈরি হয়েছে এবং default command হিসেবে CMD image-এর সঙ্গে সংরক্ষিত হয়েছে।
তারপর:
docker run go-server:1.0.1
Enter fullscreen mode Exit fullscreen mode
দিলে CMD execute হবে।
10. The Magic of Default Commands
এখন সবচেয়ে useful part।
আমাদের image:
new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
এর default command:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
তাই:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
মানে effectively:
Run container
+
Use the image's default command
Enter fullscreen mode Exit fullscreen mode
ফলে server automatically start হয়।
এটাই containerized application-এর expected behaviour:
docker run image
↓
Application starts
↓
Application keeps running
Enter fullscreen mode Exit fullscreen mode
User-কে container-এর ভিতরে ঢুকে application manually start করতে হয় না।
11. But What If I Want Another Command?
এখানে Docker-এর আরেকটি powerful feature আছে।
ধরুন image-এর default:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
কিন্তু debugging-এর জন্য আমরা container-এর ভিতরে bash shell চাই।
তাহলে:
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
এখানে কী হলো?
আমরা bash command দিয়েছি।
Docker default CMD ব্যবহার না করে এই command execute করবে।
অর্থাৎ:
Dockerfile CMD
│
│ override
▼
docker run ... bash
│
▼
bash
Enter fullscreen mode Exit fullscreen mode
Reference material-এ এই exact behaviour দেখানো হয়েছে—docker run <image> <custom_command> ব্যবহার করলে Dockerfile-এর CMD override হয়ে custom command execute হয়।
12. CMD Override: A Practical Example
Default behaviour:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
Result:
go run server.go
Enter fullscreen mode Exit fullscreen mode
কিন্তু:
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
Result:
bash
Enter fullscreen mode Exit fullscreen mode
অর্থাৎ CMD override হয়েছে।
এটি বিশেষ করে debugging-এর সময় useful।
ধরুন application start হচ্ছে না।
তখন:
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
দিয়ে container-এর ভিতরে ঢুকে manually inspect করতে পারি:
ls
go version
go run server.go
Enter fullscreen mode Exit fullscreen mode
অর্থাৎ production-এ default command ব্যবহার করা হবে, আর troubleshooting-এর সময় custom command দিয়ে override করা যেতে পারে।
13. CMD Override মানে Image পরিবর্তন নয়
এখানে আরেকটি subtle point আছে।
যখন আমরা:
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
দিই, তখন আমরা Docker image-এর CMD permanently পরিবর্তন করছি না।
শুধু এই particular container-এর জন্য default command-এর পরিবর্তে bash চালাচ্ছি।
পরেরবার:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
দিলে আবার:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
execute হবে।
অর্থাৎ:
Image
│
├── Default CMD → go run server.go
│
├── Container A → default CMD
│
└── Container B → bash override
Enter fullscreen mode Exit fullscreen mode
Image-এর default configuration unchanged থাকে।
14. Hands-On: Build the New Image
এখন complete Dockerfile দিয়ে নতুন image build করি:
docker build -t new_go_server:1.0.1 .
Enter fullscreen mode Exit fullscreen mode
Build-এর সময়:
FROM
RUN
RUN
WORKDIR
COPY
Enter fullscreen mode Exit fullscreen mode
এর instructions process হবে।
কিন্তু:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
run হবে না।
এটি image-এর default runtime command হিসেবে save হবে।
15. Run Without -it
এবার:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
কোনো:
-it
Enter fullscreen mode Exit fullscreen mode
নেই।
কোনো:
bash
Enter fullscreen mode Exit fullscreen mode
নেই।
শুধু:
docker run
+
image
Enter fullscreen mode Exit fullscreen mode
এবং তারপরও Go server start হয়ে যাবে।
কারণ Docker image-এর মধ্যে আমরা already define করেছি:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
Output:
Server is running on :8080
Enter fullscreen mode Exit fullscreen mode
এটাই আমাদের desired behaviour।
16. Verify the Running Container
অন্য terminal খুলে:
docker ps
Enter fullscreen mode Exit fullscreen mode
চালালে running container দেখা যাবে।
তারপর container-এর ভিতরে প্রবেশ করতে:
docker exec -it <CONTAINER_ID> bash
Enter fullscreen mode Exit fullscreen mode
এবং:
curl http://localhost:8080
Enter fullscreen mode Exit fullscreen mode
Expected:
Hello World!
Enter fullscreen mode Exit fullscreen mode
Reference hands-on workflow-এ docker exec দিয়ে running container-এ ঢুকে curl http://localhost:8080 ব্যবহার করে Hello World! response verify করা হয়েছে।
17. docker run বনাম docker exec
এই example-এ আরেকটি important distinction পাওয়া যায়।
docker run
নতুন container তৈরি করে এবং তার default command বা supplied command চালায়।
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
docker exec
Already running container-এর ভিতরে নতুন command চালায়।
docker exec -it <CONTAINER_ID> bash
Enter fullscreen mode Exit fullscreen mode
অর্থাৎ:
docker run
→ Start a new container
docker exec
→ Execute inside an existing container
Enter fullscreen mode Exit fullscreen mode
এই distinction debugging-এর সময় খুব গুরুত্বপূর্ণ।
18. Complete Lifecycle
এখন পুরো lifecycle-টা একসঙ্গে দেখি:
Dockerfile
│
│ docker build
▼
Docker Image
│
┌──────┴──────┐
│ │
│ docker run │
│ │
▼ ▼
Default CMD Custom Command
│ │
▼ ▼
go run server.go bash
│
▼
Go HTTP Server
│
▼
:8080
Enter fullscreen mode Exit fullscreen mode
এখানে Dockerfile থেকে image, image থেকে container, এবং container start হওয়ার সময় CMD execution—পুরো chain-টি পরিষ্কার হয়ে যায়।
19. RUN vs CMD: Final Comparison
বিষয়
RUN
CMD
কখন execute হয়?
docker build
docker run
মূল উদ্দেশ্য
Image তৈরি/configure করা
Default runtime command
Image layer তৈরি করে?
হ্যাঁ
Command নিজে build layer তৈরি করে না
Build-এর সময় application চালায়?
হতে পারে
না
Container start হলে automatically execute?
না
হ্যাঁ, যদি override না করা হয়
Override করা যায়?
Runtime command হিসেবে নয়
হ্যাঁ
Example
RUN apt install -y golang
CMD ["go", "run", "server.go"]
Reference material-এও execution phase, purpose এবং image-এর সঙ্গে persistence-এর ভিত্তিতে RUN ও CMD-কে এভাবেই আলাদা করা হয়েছে।
20. The Three Most Important Commands
এই lesson-এর core workflow মাত্র কয়েকটি command-এ:
Build
docker build -t new_go_server:1.0.1 .
Enter fullscreen mode Exit fullscreen mode
Normal Run
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
→ CMD automatically execute হবে।
Debug / Override
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
→ CMD override হয়ে bash execute হবে।
এই তিনটি command-এর relationship বুঝলেই CMD অনেক সহজ হয়ে যায়।
21. The Most Important Mental Model
Dockerfile-এর ক্ষেত্রে এই flow-টি মনে রাখুন:
BUILD TIME
│
▼
┌────────────────────────┐
│ FROM │
│ RUN │
│ WORKDIR │
│ COPY │
└────────────────────────┘
│
▼
Docker Image
│
│ docker run
▼
RUNTIME
│
▼
CMD
│
▼
Application Process
Enter fullscreen mode Exit fullscreen mode
অর্থাৎ:
RUNprepares the image.CMDstarts the application.
এই এক লাইনের mental model-টি Dockerfile-এর অনেক confusion দূর করতে পারে।
22. Why This Matters Beyond This Example
আমাদের example একটি simple Go server।
কিন্তু একই principle practically সব ধরনের containerized application-এর ক্ষেত্রে দেখা যায়।
একটি application image তৈরি করার সময়:
Dependencies
Configuration
Application Files
Enter fullscreen mode Exit fullscreen mode
image-এর মধ্যে prepare করা হয়।
আর container start হওয়ার সময়:
Application Process
Enter fullscreen mode Exit fullscreen mode
start করা হয়।
তাই একটি well-designed container-এর ক্ষেত্রে user experience ideally এমন:
docker run <image>
Enter fullscreen mode Exit fullscreen mode
এবং application নিজে থেকেই start করবে।
User-কে container-এর ভিতরে গিয়ে manually setup করতে হবে না।
এটাই containerization-এর বড় সুবিধাগুলোর একটি।
23. One Last Look at Our Go Server
আমাদের server.go:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World!")
})
fmt.Println("Server is running on :8080")
http.ListenAndServe(":8080", nil)
}
Enter fullscreen mode Exit fullscreen mode
Dockerfile:
FROM ubuntu:24.04
RUN apt update
RUN apt install -y golang
WORKDIR /app
COPY ./server.go ./server.go
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
Build:
docker build -t new_go_server:1.0.1 .
Enter fullscreen mode Exit fullscreen mode
Run:
docker run new_go_server:1.0.1
Enter fullscreen mode Exit fullscreen mode
Debug:
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
Test:
curl http://localhost:8080
Enter fullscreen mode Exit fullscreen mode
Response:
Hello World!
Enter fullscreen mode Exit fullscreen mode
এই ছোট example-এর মধ্যেই Dockerfile-এর একটি complete lifecycle দেখা যাচ্ছে।
Final Takeaway
আজকের lesson-এ মূলত একটি প্রশ্নের উত্তর খুঁজেছি:
How do we make a Docker container automatically start our application?
উত্তর:
CMD ["go", "run", "server.go"]
Enter fullscreen mode Exit fullscreen mode
কিন্তু শুধু syntax মনে রাখলে হবে না।
বোঝা দরকার কখন এটি execute হয়।
docker build
FROM
RUN
WORKDIR
COPY
Enter fullscreen mode Exit fullscreen mode
এগুলো image তৈরি করে।
CMD তখন execute হয় না।
তারপর:
docker run
Container Created
↓
CMD Executed
↓
Go Server Started
↓
Container Keeps Running
Enter fullscreen mode Exit fullscreen mode
আর যদি debugging করতে চাই:
docker run -it new_go_server:1.0.1 bash
Enter fullscreen mode Exit fullscreen mode
তাহলে default CMD override হয়ে bash চালু হবে।
শেষ পর্যন্ত Docker-এর এই simple mental model-টি মনে রাখুন:
Build the environment with
RUN.
Define the default application process withCMD.
Start it withdocker run.
Override it when you need to debug.
একটি ছোট CMD instruction আসলে Docker image-কে একটি static filesystem থেকে একটি runnable application environment-এ পরিণত করার গুরুত্বপূর্ণ অংশ।
আর Docker শেখার পরবর্তী ধাপে এই concept থেকেই naturally আসে ENTRYPOINT, CMD বনাম ENTRYPOINT, environment variables, ports, volumes এবং production-grade container design।
Understand the lifecycle, not just the command. 🐳