Docker Compose কমান্ডের সম্পূর্ণ গাইড ও চিট শিট
সার্ভারে নিয়মিত ব্যবহৃত Docker Compose কমান্ডগুলো এখানে গুছিয়ে দেওয়া হয়েছে। লাইফসাইকেল ম্যানেজমেন্ট, লগ দেখা, নেটওয়ার্ক কনফিগারেশন এবং নিরাপদ ক্লিনআপের প্রয়োজনীয় সব কমান্ড জানুন।
যে Compose কমান্ডগুলো আপনার নিয়মিত প্রয়োজন হয়
Docker Compose-এ চল্লিশটিরও বেশি সাবকমান্ড রয়েছে। সার্ভারে দৈনন্দিন কাজের জন্য প্রায় এক ডজন কমান্ড ব্যবহৃত হয়। এই পৃষ্ঠায় কাজ অনুযায়ী সেই কমান্ডগুলোকে ভাগ করা হয়েছে, প্রতিটি কমান্ডের একটি সহজ কারণ দেওয়া হয়েছে এবং কোনো কমান্ডে জটিলতা থাকলে তার বিস্তারিত আলোচনার দিকে নির্দেশ করা হয়েছে।
এখানে সবকিছু Compose V2 ব্যবহার করে: docker compose, স্পেস দিয়ে, পুরোনো docker-compose স্ক্রিপ্ট নয়। V2 হলো একটি Go প্লাগিন যা Docker Engine-এর সাথে ইনস্টল হয় এবং বর্তমান প্যাকেজগুলো থেকে V1 সরিয়ে ফেলা হয়েছে। তাই জুলাই 2026 অনুযায়ী একটি নতুন Ubuntu বক্সে docker-compose: command not found চালানো প্রত্যাশিত, এটি কোনো ত্রুটি নয়। docker compose version দিয়ে যাচাই করুন। যদি এটি কিছু না দেখায়, তবে docker-compose-plugin প্যাকেজটি ইনস্টল করুন।
নিচের প্রতিটি কমান্ড সেই ডিরেক্টরি থেকে চালাতে হয় যেখানে আপনার compose.yaml ফাইলটি রয়েছে, কারণ Compose সেই ডিরেক্টরি থেকে প্রজেক্টের নাম নেয় এবং সেই অনুযায়ী ফাইলটি খুঁজে পায়। এক লেভেল উপরে গিয়ে একই কমান্ড চালালে Compose no configuration file provided: not found ত্রুটি দেখিয়ে থেমে যাবে। যদি ফাইলের ফরম্যাট আপনার কাছে নতুন হয়, তবে একটি VPS-এ প্রথম Compose ফাইল দিয়ে শুরু করুন এবং কমান্ডগুলোর জন্য এখানে ফিরে আসুন।
লাইফসাইকেল: যে চারটি আপনি টাইপ করেন এবং যেটি কন্টেইনার মুছে ফেলে
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d নেটওয়ার্ক তৈরি করে, কন্টেইনারগুলো তৈরি করে, সেগুলো চালু করে এবং ফিরে আসে। এটি কন্টেইনারগুলো তৈরি হওয়ার সাথে সাথেই ফিরে আসে, যে কারণে এর ঠিক পরেই curl প্রোব ব্যবহার করা একটি ডিপ্লয় স্ক্রিপ্ট প্রায়শই প্রথমবার ব্যর্থ হয়। up -d --wait ততক্ষণ পর্যন্ত অপেক্ষা করে যতক্ষণ না হেলথচেক ঘোষণা করা প্রতিটি সার্ভিস সুস্থ (healthy) হিসেবে রিপোর্ট করে; কোনো একটি সার্ভিস সুস্থ না হলে এটি নন-জিরো এক্সিট কোড প্রদান করে। এই ফ্ল্যাগটি কেবল তার পেছনের চেকের ওপর নির্ভর করে কার্যকর হয়, তাই অটোমেশনে এর ওপর নির্ভর করার আগে Compose বিশ্বাস করতে পারে এমন একটি হেলথচেক লিখুন।
stop কন্টেইনারগুলোকে থামিয়ে দেয় কিন্তু সেগুলো রেখে দেয়, তাই start একই রাইটেবল লেয়ারসহ সেই কন্টেইনারগুলোকেই আবার ফিরিয়ে আনে। down সেগুলোকে থামায় এবং তারপর কন্টেইনার ও প্রজেক্ট নেটওয়ার্ক মুছে ফেলে। ভলিউমের বাইরে কন্টেইনারের ভেতরে লেখা যেকোনো কিছু সেগুলোর সাথেই মুছে যায়। এটি Compose-এর ক্ষেত্রে সবচেয়ে ব্যয়বহুল ভুল বোঝাবুঝি, এবং down এবং stop-এর মধ্যে সম্পূর্ণ পার্থক্য বিষয়টি কোথায় সমস্যা তৈরি করে তা ব্যাখ্যা করে।
restart কোনো রিলোড নয়। এটি বিদ্যমান কনফিগারেশনসহ একই কন্টেইনারকে থামায় এবং পুনরায় চালু করে, তাই পরিবর্তিত এনভায়রনমেন্ট ভেরিয়েবল, নতুন ইমেজ ট্যাগ বা এডিট করা পোর্ট ম্যাপিংয়ের কোনো প্রভাব পড়ে না। ফাইলের পরিবর্তন কার্যকর করতে আপনাকে পুনরায় up -d চালাতে হবে। Compose প্রতিটি সার্ভিসকে তার চলমান কন্টেইনারের সাথে তুলনা করে এবং শুধুমাত্র সেগুলোরই পুনর্নির্মাণ করে যেগুলোর কনফিগারেশন পরিবর্তিত হয়েছে।
পরিবর্তন প্রয়োগ করা: recreate, pull, অথবা rebuild
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d নিজে থেকে কোনো কাজ করে না যদি কোনো পরিবর্তন না থাকে, আর এই কারণেই এটি বারবার চালানো নিরাপদ। --force-recreate সেই তুলনাকে উপেক্ষা করে এবং কনফিগারেশন অভিন্ন হলেও প্রতিটি কন্টেইনারকে প্রতিস্থাপন করে, তাই কন্টেইনারের ভেতরের অসামঞ্জস্যপূর্ণ অবস্থা পরিষ্কার করার এটিই দ্রুততম উপায়।
একটি ইমেজ আপডেট করতে দুটি কমান্ডের প্রয়োজন হয় কারণ তারা দুটি ভিন্ন কাজ করে। pull ফাইলে উল্লিখিত প্রতিটি ট্যাগের জন্য বর্তমান ইমেজটি ডাউনলোড করে। এরপর up -d শনাক্ত করে যে সার্ভিসের ইমেজ আইডি আর চলমান কন্টেইনারের সাথে মিলছে না এবং সেটিকে পুনরায় তৈরি (recreate) করে। pull কমান্ডটি বাদ দিলে up -d কোনো ত্রুটি ছাড়াই গত মাসের latest চালিয়ে যাবে।
build সেইসব সার্ভিসের ক্ষেত্রে প্রযোজ্য যেগুলোতে image: এর পরিবর্তে একটি build: সেকশন ঘোষণা করা থাকে। up -d --build এক ধাপেই বিল্ড এবং স্টার্ট সম্পন্ন করে, যা কোড পরিবর্তনের সময় স্বাভাবিক কাজের প্রক্রিয়া। --no-cache শুধুমাত্র তখনই ব্যবহার করুন যখন কোনো ক্যাশড লেয়ার স্পষ্টভাবে পুরনো হয়ে যায়, কারণ এটি প্রতিটি লেয়ারকে শুরু থেকে পুনরায় তৈরি করে।
চলমান প্রক্রিয়াগুলো দেখা
docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose lsps শুধুমাত্র চলমান কন্টেইনারগুলোর তালিকা দেখায়। শুরুর সময় ক্র্যাশ করা কোনো সার্ভিস সেখানে দেখা যায় না, যতক্ষণ না আপনি -a যোগ করছেন। তাই কোনো কন্টেইনার ps-এ অনুপস্থিত থাকা এবং একই সময়ে ps -a-এ সেটিকে Exited (1) হিসেবে দেখানো একটি সাধারণ স্টার্টআপ ব্যর্থতার লক্ষণ। এক্সিট কোডটি পড়ুন, তারপর লগগুলো দেখুন।
logs -f একই সাথে প্রতিটি সার্ভিস অনুসরণ করে এবং প্রতিটি লাইনের শুরুতে সার্ভিসের নাম যুক্ত করে। যখন সার্ভিসগুলো একে অপরের সাথে যোগাযোগ করে এবং ঘটনার ক্রম গুরুত্বপূর্ণ হয়, তখন এই ভিউটি আপনার প্রয়োজন হবে। কোনো নির্দিষ্ট সার্ভিসকে সংকুচিত করতে তার নাম উল্লেখ করুন। --tail=100 এমন কন্টেইনারের ক্ষেত্রে গুরুত্বপূর্ণ যা এক মাস ধরে চলছে, কারণ ডিফল্ট কমান্ডটি পুরো ইতিহাস প্রিন্ট করে টার্মিনালকে পূর্ণ করে ফেলে। --since 15m আপনার সাধারণ প্রশ্নের উত্তর দেয়, যা হলো আপনি যে রিস্টার্টটি করেছেন তার সময় কী ঘটেছিল।
top প্রতিটি কন্টেইনারের ভেতরের প্রসেসগুলোর তালিকা দেখায়, যা "কন্টেইনারটি চলছে" এবং "এর ভেতরের প্রসেসটি চলছে" - এই দুটির মধ্যে পার্থক্য স্পষ্ট করে। ls বর্তমান ডিরেক্টরির বাইরে গিয়ে হোস্টের প্রতিটি Compose প্রজেক্ট এবং তাদের স্ট্যাটাস তালিকাভুক্ত করে, যাতে আপনি তিন মাস আগে শুরু করা স্ট্যাকটি খুঁজে পেতে পারেন।
একটি সার্ভিসের ভেতরে শেল পাওয়া
docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web shexec একটি চলমান কন্টেইনারের ভেতরে কমান্ড চালায়। run একই সার্ভিস ডেফিনিশন থেকে একটি নতুন কন্টেইনার শুরু করে; যখন সার্ভিসটি এত অল্প সময় চালু থাকে যে সেটির ভেতরে exec করা সম্ভব হয় না, তখন এটি প্রয়োজন হয়। সবসময় run-এর সাথে --rm ব্যবহার করুন, কারণ এটি ছাড়া প্রতিটি ইনভোকেশন একটি বন্ধ কন্টেইনার রেখে দেয় এবং সেগুলো জমা হয়ে docker compose ps -a-কে অপাঠ্য করে তোলে।
bash-এর আগে sh ব্যবহার করে দেখুন। Alpine ভিত্তিক ইমেজগুলোতে কোনো bash থাকে না এবং ব্যর্থতার বার্তায় exec: "bash": executable file not found in $PATH লেখা আসে। run-এ --no-deps যোগ করলে সার্ভিসের ডিপেন্ডেন্সিগুলো এড়িয়ে যাওয়া যায়, যা একটি দ্রুত কনফিগারেশন চেক করার সময় আপনার পুরো ডেটাবেসকে চালু হওয়া থেকে বিরত রাখে।
একটি সার্ভিস প্রকৃতপক্ষে কী এনভায়রনমেন্ট পেয়েছে তা দেখার দ্রুততম উপায় হলো run --rm web env, যেখানে প্রতিটি .env ফাইল, environment: ব্লক এবং শেল ভেরিয়েবল মার্জ করা হয়েছে। যখন কোনো ভ্যালু ভুল থাকে, তখন সাধারণত মার্জ করার ক্রমই এর কারণ হয় এবং Compose কীভাবে env ফাইল এবং সিক্রেট সমাধান করে তা ব্যাখ্যা করে যে কোন সোর্সটি কার্যকর হবে।
নেটওয়ার্ক, পোর্ট এবং নেম রেজোলিউশন
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksCompose প্রতিটি সার্ভিসকে একটি প্রজেক্ট নেটওয়ার্কে যুক্ত করে এবং প্রতিটি সার্ভিসের নাম সেখানে একটি DNS নাম হিসেবে কাজ করে। web এর ভেতরে getent hosts db কমান্ডটি চালালে রেজোলিউশন কাজ করলে কন্টেইনারের IP দেখাবে, আর কাজ না করলে কিছুই দেখাবে না। এটি দুই সেকেন্ডের মধ্যে উত্তর দেয় যে "এই কন্টেইনারগুলো কি একে অপরকে দেখতে পাচ্ছে"। যদি নাম রেজলভ হয় কিন্তু সংযোগ প্রত্যাখ্যান করা হয়, তবে db এর ভেতরের প্রসেসটি 0.0.0.0 এর পরিবর্তে 127.0.0.1 এ বাইন্ড করা আছে। ফলে এটি অন্য কোনো কন্টেইনার থেকে আসা প্যাকেট গ্রহণ করে না। এই মডেলের বাকি অংশ Compose নেটওয়ার্ক এবং সার্ভিস DNS কীভাবে কাজ করে-এ রয়েছে।
port web 80 কমান্ডটি হোস্টের সেই অ্যাড্রেস এবং পোর্ট প্রিন্ট করে যেখানে একটি কন্টেইনার পোর্ট পাবলিশ করা হয়েছে। এটি ম্যাপিং কোনো ভেরিয়েবল থেকে আসলে অনুমান করার ঝামেলা কমায়। একটি পোর্ট পাবলিশ করলে তা একটি ফায়ারওয়াল রুলও তৈরি করে যা Docker নিজেই পরিচালনা করে। এই রুলটি আপনার তৈরি করা রুলের আগে অবস্থান করে, তাই আপনি যে সার্ভিসটিকে ব্যক্তিগত মনে করেছিলেন সেটি ইন্টারনেটের জন্য উন্মুক্ত হয়ে যেতে পারে। এই বিষয়টি কেন পাবলিশ করা Docker পোর্ট ufw বাইপাস করে-এ আলোচনা করা হয়েছে।
ভলিউম এবং ডেটা
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes কমান্ডটি প্রজেক্টে ঘোষিত নামযুক্ত ভলিউমগুলোকে প্রতি লাইনে একটি করে প্রদর্শন করে। এই তালিকাটিই আপনাকে ব্যাকআপ রাখতে হবে। cp কমান্ডটি কোনো শেল ওপেন না করেই কন্টেইনারের ভেতরে বা বাইরে ফাইল কপি করতে ব্যবহৃত হয়, যেখানে কন্টেইনারের দিকের জন্য service:path ফরম্যাটটি ব্যবহার করা হয়।
down -v কমান্ডটি কন্টেইনারের পাশাপাশি সেই নামযুক্ত ভলিউমগুলোকেও মুছে ফেলে। কোনো টেস্ট স্ট্যাক পুরোপুরি মুছে ফেলার জন্য এটি সঠিক কমান্ড, কিন্তু গুরুত্বপূর্ণ ডেটা আছে এমন কোনো কিছুর জন্য এটি ভুল কমান্ড, কারণ এতে কোনো নিশ্চিতকরণ বা পূর্বাবস্থায় ফিরিয়ে আনার (undo) সুযোগ নেই। বাইন্ড মাউন্টগুলো (bind mounts) এই কমান্ডের পরেও টিকে থাকে, কারণ সেগুলো হোস্ট ফাইলসিস্টেমে থাকে। ব্লাস্ট রেডিয়াসের এই পার্থক্যের কারণেই বাইন্ড মাউন্ট এবং নামযুক্ত ভলিউম-এর মধ্যে সতর্কতার সাথে নির্বাচন করা প্রয়োজন।
ডেটা না হারিয়ে ডিস্ক খালি করার উপায়
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans কমান্ডটি এমন সব কন্টেইনার মুছে ফেলে যা প্রজেক্টের অন্তর্ভুক্ত কিন্তু ফাইলে আর নেই; কোনো সার্ভিসের নাম পরিবর্তন করলে সাধারণত এমনটিই ঘটে। এটি ব্যবহার না করলে সেই কন্টেইনারগুলো চলতে থাকে এবং docker compose ps সেগুলোকে আর দেখতে পায় না।
কিছু মুছে ফেলার আগে ডিস্কের জায়গা কোথায় খরচ হচ্ছে তা দেখতে docker system df ব্যবহার করুন। এটি ইমেজ, কন্টেইনার, লোকাল ভলিউম এবং বিল্ড ক্যাশ আলাদা করে দেখায় এবং প্রতিটি থেকে কতটুকু জায়গা পুনরুদ্ধার করা সম্ভব তা জানায়। image prune -a এমন সব ইমেজ মুছে ফেলে যেগুলোর কোনো ট্যাগ নেই। যেসব সার্ভারে বড় কোনো ইমেজের একাধিক ভার্সন ডাউনলোড করা থাকে, সেখানে এটি সবচেয়ে বেশি জায়গা খালি করে। builder prune বিল্ড ক্যাশ পরিষ্কার করে, যা নিজের ইমেজ নিজে তৈরি করে এমন যেকোনো সার্ভারে নীরবে বাড়তে থাকে।
এগুলোর কোনোটিই নেমড ভলিউম স্পর্শ করে না। শুধুমাত্র docker volume prune এবং docker compose down -v তা করে থাকে।
ফাইলটি নষ্ট হওয়ার আগেই তা যাচাই করা
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet ফাইল যাচাই করে এবং সফল হলে কোনো আউটপুট দেয় না, তাই এটি কোনো প্রি-ডিপ্লয় ধাপ বা git hook-এ ব্যবহার করা উচিত। সাধারণ config কমান্ডটি সম্পূর্ণ মার্জ এবং ইন্টারপোলেট করা ফাইলটি প্রিন্ট করে। এর মাধ্যমে আপনি নিশ্চিত হতে পারেন যে কোনো ভেরিয়েবল সঠিকভাবে রেজলভ হয়েছে কিনা এবং ওভাররাইড ফাইলটি আপনার প্রত্যাশা অনুযায়ী কাজ করছে কিনা। কোনো ভেরিয়েবল সেট করা না থাকলে তা সেখানে খালি মান হিসেবে দেখাবে এবং সাথে The "X" variable is not set. Defaulting to a blank string. ওয়ার্নিংটি আসবে।
--dry-run একটি গ্লোবাল ফ্ল্যাগ, সাবকমান্ড ফ্ল্যাগ নয়, তাই এটি up-এর আগে বসে। এটি Compose যে সমস্ত কাজ করবে তা প্রিন্ট করে দেখায় কিন্তু কোনো পরিবর্তন করে না। গুরুত্বপূর্ণ কোনো স্ট্যাকে down চালানোর আগে এই ত্রিশ সেকেন্ড সময় ব্যয় করা বুদ্ধিমানের কাজ।
ফাইল, প্রোফাইল এবং প্রজেক্ট নিয়ে কাজ করা
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dএকাধিক -f ফ্ল্যাগ ক্রমানুসারে মার্জ হয় এবং পরবর্তী ফাইলগুলো পূর্ববর্তী ফাইলের কি (key) গুলোকে ওভাররাইড করে। একটি বেস ফাইলের সাথে ছোট প্রোডাকশন ওভাররাইড রাখার এটিই আদর্শ উপায়, তবে লিস্ট এবং ম্যাপের ক্ষেত্রে নিয়মগুলো ভিন্ন। তাই কোনো অপ্রত্যাশিত সমস্যা সমাধানের আগে কিভাবে Compose একাধিক ফাইল মার্জ করে পড়ে নিন।
--profile সেই প্রোফাইল দিয়ে ট্যাগ করা সার্ভিসগুলোকে আনট্যাগ করা সার্ভিসগুলোর পাশাপাশি চালু করে, যা সাধারণ up থেকে ডিবাগ টুলিংকে দূরে রাখে। -p প্রজেক্টের নাম সেট করে, ফলে একটি স্ট্যাকের দুটি কপি আলাদা নেটওয়ার্ক এবং আলাদা ভলিউম নাম নিয়ে পাশাপাশি চলতে পারে। রিবুটের পর স্ট্যাকটি ফিরিয়ে আনা কোনো কমান্ড নয় যা আপনাকে টাইপ করতে হবে, এটি একটি ইউনিট যা আপনার জন্য এটি চালু করে, যার বর্ণনা বুট হওয়ার সময় Compose স্ট্যাক চালু করা-তে দেওয়া আছে।
FAQ
docker-compose-এর পরিবর্তে হাইফেন ব্যবহার করা হয়েছে কেন?
Compose V2, যা docker compose হিসেবে স্পেস দিয়ে ব্যবহার করা হয়। এটি Docker Engine-এর সাথে যুক্ত একটি প্লাগইন এবং বর্তমান প্যাকেজগুলোতে V1 পাইথন টুলটি আর ইনস্টল করা থাকে না। যদি স্পেস ফরম্যাটে কোনো আউটপুট না আসে, তবে আপনার ডিস্ট্রিবিউশনের জন্য docker-compose-plugin প্যাকেজটি ইনস্টল করুন। পুরনো স্ক্রিপ্টগুলোতে এলিয়াস (alias) যোগ না করে সেগুলোকে স্পেস ফরম্যাটে আপডেট করুন, কারণ V2-তে এমন অনেক ফ্ল্যাগ রয়েছে যা V1-এ ছিল না।
docker compose restart আমার কনফিগারেশন পরিবর্তনগুলো কেন গ্রহণ করছে না?
restart বিদ্যমান কন্টেইনারটিকে সেই কনফিগারেশন দিয়েই বন্ধ এবং চালু করে যা দিয়ে এটি তৈরি করা হয়েছিল, এটি কখনোই compose.yaml পুনরায় পড়ে না। এনভায়রনমেন্ট ভেরিয়েবল, পোর্ট, ভলিউম বা ইমেজ ট্যাগের যেকোনো পরিবর্তনের জন্য docker compose up -d প্রয়োজন, যা প্রতিটি সার্ভিসকে তার চলমান কন্টেইনারের সাথে তুলনা করে এবং যেগুলোর পার্থক্য থাকে সেগুলো পুনরায় তৈরি করে। ফাইলে কোনো পরিবর্তন না থাকলেও যদি আপনি রিপ্লেসমেন্ট করতে চান, তবে --force-recreate যোগ করুন।
আমি কীভাবে একটি সার্ভিসকে নতুন ইমেজে আপডেট করব?
প্রথমে docker compose pull এবং তারপর docker compose up -d রান করুন। pull কমান্ডটি ফাইলে থাকা প্রতিটি ট্যাগের জন্য বর্তমান ইমেজটি সংগ্রহ করে এবং up -d সেই সার্ভিসগুলোকে পুনরায় তৈরি করে যেগুলোর ইমেজ আইডি বর্তমান কন্টেইনারের সাথে মেলে না। শুধুমাত্র up -d রান করলে ডিস্কে থাকা পুরনো ইমেজটিই পুনরায় ব্যবহৃত হয়, যার ফলে latest-এ পিন করা কোনো স্ট্যাক মাসের পর মাস পুরনো বিল্ডেই চলতে থাকে এবং কোনো ত্রুটি দেখায় না।
লাইভ সার্ভারে কোন ক্লিনআপ কমান্ডগুলো নিরাপদ?
docker system df, docker image prune -a এবং docker builder prune শুধুমাত্র ইমেজ এবং ক্যাশে মুছে ফেলে, তাই চলমান সার্ভিসগুলো কাজ করতে থাকে এবং নামযুক্ত ভলিউমগুলো অক্ষত থাকে। বিপজ্জনক কমান্ডের জোড়া হলো docker compose down -v এবং docker volume prune, যা কোনো সতর্কতা ছাড়াই নামযুক্ত ভলিউম মুছে ফেলে। আগে docker compose config --volumes রান করুন যাতে আপনি বুঝতে পারেন কী ঝুঁকির মুখে রয়েছে।
পুরো স্ট্যাক চালু না করে কি আমি একটি কমান্ড রান করতে পারি?
হ্যাঁ। docker compose run --rm --no-deps web sh কমান্ডটি web সার্ভিস ডেফিনিশন থেকে একটি একক কন্টেইনার চালু করে, এর ডিপেন্ডেন্সিগুলো এড়িয়ে যায় এবং আপনি বের হয়ে গেলে কন্টেইনারটি মুছে ফেলে। কন্টেইনারটি আগে থেকেই চালু থাকলে এর পরিবর্তে exec ব্যবহার করুন, কারণ exec লাইভ প্রসেসে যুক্ত হয় এবং সার্ভিসটি বর্তমানে কী অবস্থায় আছে তা আপনাকে দেখায়।