SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-10-07

Docker Compose services को boot पर auto-start कैसे करें

Docker Compose services को reboot के बाद स्वतः चालू करने का तरीका जानें। restart: always नीति का उपयोग करें और समझें कि systemd unit की आवश्यकता कब पड़ती है।

संक्षिप्त उत्तर

Docker Compose services तब boot पर start होती हैं जब दो शर्तें एक साथ पूरी होती हैं। Docker daemon को system service के रूप में enabled होना चाहिए, और file में प्रत्येक service के पास unless-stopped या always की restart policy होनी चाहिए। हर service में restart: unless-stopped जोड़ें, एक बार docker compose up -d चलाएं, और reboot के बाद containers अपने आप वापस आ जाएंगे। सामान्य स्थिति के लिए इसके अलावा कुछ और आवश्यक नहीं है।

आपको systemd unit की आवश्यकता केवल तब होती है जब क्रम (order) मायने रखता है: जैसे कि कोई stack जो mounted disk, VPN interface, या network share पर निर्भर हो, जो Docker daemon के start होने के समय तैयार न हो। यह स्थिति वास्तविक है, और इस guide का दूसरा भाग इसे कवर करता है। यदि आप अभी भी service definitions और volumes को समझने की कोशिश कर रहे हैं, तो VPS पर Docker Compose की बुनियादी बातें से शुरुआत करें और फिर वापस आएं।

compose.yaml में restart policy सेट करें

यह policy प्रति service एक लाइन की होती है। इसमें कोई global switch नहीं है, इसलिए यदि आप किसी service को भूल जाते हैं, तो बाकी stack के start होने के बाद भी वह service down ही रहेगी।

services:
  app:
    image: nginx:1.27
    restart: unless-stopped
    ports:
      - "8080:80"
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: change-me
    volumes:
      - dbdata:/var/lib/postgresql/data

volumes:
  dbdata:

इसे लागू करें और फिर चल रहे container से policy को वापस पढ़ें:

docker compose up -d
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app)

यह unless-stopped प्रिंट करता है। यदि यह no प्रिंट करता है, तो इसका मतलब है कि file edit की गई थी लेकिन container को कभी recreate नहीं किया गया।

यह सबसे आम विफलता है। Restart policy container पर store होती है, न कि YAML file में। compose.yaml को edit करने से पहले से मौजूद container पर कोई प्रभाव नहीं पड़ता है। docker compose restart भी मदद नहीं करता है, क्योंकि यह configuration को छुए बिना उसी container object को stop और start करता है। केवल docker compose up -d ही file की तुलना चल रहे containers से करता है, policy में बदलाव को पहचानता है और उन्हें recreate करता है।

जिस container को आप अभी recreate नहीं करना चाहते हैं, उसके लिए policy को सीधे बदलें:

docker update --restart unless-stopped my-container

फिर भी YAML file को भी edit करें। docker update live container को बदल देता है, और अगला docker compose up -d file को पढ़ेगा और पुरानी value को वापस लागू कर देगा।

प्रत्येक restart मान वास्तव में क्या करता है

Docker चार मान परिभाषित करता है, और उनके बीच का अंतर केवल तब दिखाई देता है जब मशीन रीबूट होती है या daemon को रीस्टार्ट किया जाता है।

  • no डिफ़ॉल्ट मान है। कंटेनर किसी भी परिस्थिति में स्वचालित रूप से रीस्टार्ट नहीं होता है।
  • always कंटेनर के रुकने पर उसे हर बार रीस्टार्ट करता है। यदि आपने इसे मैन्युअल रूप से रोका है, तो भी Docker daemon के अगली बार स्टार्ट होने पर यह वापस आ जाता है। यह अक्सर आश्चर्यजनक होता है: पिछले सप्ताह आपके द्वारा जानबूझकर रोका गया कंटेनर रीबूट के बाद फिर से चल रहा होता है।
  • unless-stopped का व्यवहार always जैसा ही है, सिवाय इसके कि मैन्युअल रूप से रोका गया कंटेनर daemon रीस्टार्ट होने पर भी रुका रहता है। यदि आप किसी सर्विस को रखरखाव के लिए कभी-कभी बंद करते हैं, तो यह मान आपके लिए उपयुक्त है।
  • on-failure कंटेनर को केवल तब रीस्टार्ट करता है जब वह non-zero exit code के साथ बंद होता है। आप प्रयासों की संख्या को सीमित कर सकते हैं, जैसा कि restart: on-failure:3 में दिखाया गया है।

ऐसी stack के लिए जिसे सर्वर चालू होने पर हमेशा चलना चाहिए, unless-stopped सही डिफ़ॉल्ट है। always को केवल तब चुनें जब आप चाहते हैं कि कंटेनर बंद न हो।

reboot के बाद restart: on-failure काम क्यों नहीं करता है

बहुत से लोग on-failure को चुनते हैं क्योंकि यह सुरक्षित लगता है, लेकिन फिर वे पाते हैं कि पहला reboot होते ही हर container रुक गया है। इसका कारण इसकी परिभाषा में है। on-failure केवल एक ही चीज़ पर प्रतिक्रिया करता है: container process का error code के साथ बंद होना।

Reboot कोई error नहीं है। जब host shutdown होता है, तो systemd docker.service को रोक देता है, और daemon जानबूझकर प्रत्येक container को बंद कर देता है। Container fail नहीं हुआ था, इसलिए policy के पास प्रतिक्रिया करने के लिए कुछ नहीं होता। वापस start होते समय, daemon उन containers को देखता है जिन्हें उसे resume करना है, और एक on-failure container जिसे व्यवस्थित तरीके से बंद किया गया था, वह उनमें शामिल नहीं होता है। यह exited state में ही रहता है।

आप इसे सीधे देख सकते हैं। किसी service पर restart: on-failure सेट करें, docker compose up -d चलाएं, reboot करें, और फिर यह चलाएं:

docker compose ps -a

Service को Exited की state और Exited (0) 2 minutes ago जैसी status के साथ सूचीबद्ध किया जाता है। कुछ भी टूटा नहीं है और कुछ भी error के रूप में log नहीं हुआ है, यही कारण है कि इसका निदान करना कठिन होता है। Policy ने बिल्कुल वही किया जो वह कहती है।

on-failure अभी भी उपयोगी है। यह उस container के लिए उपयुक्त है जो कोई job चलाता है और crash हो सकता है, जहाँ आप retries की एक सीमित संख्या चाहते हैं और कोई restart loop नहीं चाहते हैं। reboots के दौरान long-running service को जीवित रखने के लिए यह गलत tool है।

Restart policies केवल तभी काम करती हैं जब Docker service boot के समय start हो

Restart policies को Docker daemon द्वारा लागू किया जाता है। यदि daemon start नहीं होता है, तो कोई भी policy लागू नहीं होगी। इसकी जाँच करें:

systemctl is-enabled docker
systemctl is-enabled containerd

दोनों commands को enabled आउटपुट देना चाहिए। Docker के आधिकारिक repository से प्राप्त packages install होते समय इन्हें enable कर देते हैं, इसलिए एक नए server पर यह आमतौर पर सही रहता है। यदि कोई भी command disabled आउटपुट दे, तो इसे ठीक करें:

sudo systemctl enable --now docker containerd

यहाँ एक ऐसी स्थिति है जिसे समझना आवश्यक है। Ubuntu में docker.socket भी होता है, जो पहली बार Docker API से संपर्क करने पर daemon को start कर देता है। लोग docker.socket को enabled देखते हैं, मान लेते हैं कि daemon सुरक्षित है, और memory बचाने के लिए docker.service को disable कर देते हैं। Boot के समय, API को कोई call नहीं करता है, इसलिए socket को कभी touch नहीं किया जाता, daemon कभी start नहीं होता, और जब तक आप अपना पहला docker command नहीं चलाते, तब तक कोई container start नहीं होता है। Socket activation, docker.service के enabled होने का विकल्प नहीं है।

जब systemd unit एक बेहतर विकल्प हो

Restart policies में सिस्टम के अन्य हिस्सों के साथ क्रम (ordering) का कोई प्रावधान नहीं होता। Daemon start होता है और यह आपके containers को जितनी जल्दी हो सके, start कर देता है। यदि आपका stack किसी अलग volume, NFS (network file system) share, या encrypted disk से कोई directory bind-mount करता है, तो हो सकता है कि containers उस path के मौजूद होने से पहले ही start हो जाएं। Docker mount point पर खुशी-खुशी एक खाली directory बना देगा और container को उसके साथ start कर देगा, जिससे आपका database बिना किसी data के start हो जाएगा।

जब इनमें से कोई भी स्थिति लागू हो, तो एक systemd unit लिखें। Stack को किसी mount, VPN interface, या किसी अन्य unit के पहले तैयार होने की आवश्यकता हो। आप चाहते हैं कि systemctl stop myapp और systemctl start myapp वैसे ही काम करें जैसे वे box पर मौजूद अन्य सभी services के लिए करते हैं। या आप चाहते हैं कि shutdown के दौरान stack को daemon के साथ kill करने के बजाय व्यवस्थित रूप से बंद किया जाए। यदि आप systemd units के लिए नए हैं, तो systemd service और timer लिखना file format के बारे में अधिक विस्तार से जानकारी देता है।

systemd unit लिखना

Stack को home directory के बाहर एक निश्चित path पर रखें। /srv/myapp एक अच्छा विकल्प है, क्योंकि जो unit किसी के login करने से पहले चलती है, उसे /home पढ़ने की कोई आवश्यकता नहीं है।

/etc/systemd/system/myapp.service बनाएँ:

[Unit]
Description=myapp docker compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target
RequiresMountsFor=/srv/myapp/data

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/myapp
ExecStart=/usr/bin/docker compose up -d --remove-orphans
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

इसे enable और start करें:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
systemctl status myapp.service

एक healthy unit Active: active (exited) दिखाती है। पहली बार देखने पर यह गलत लग सकता है। यह सही है: Type=oneshot के साथ RemainAfterExit=yes का मतलब है कि unit ने अपना command चला लिया है, command पूरा हो गया है, और systemd ने unit को active चिह्नित रखा है ताकि shutdown के समय ExecStop चल सके।

हर line का अपना महत्व है। Requires=docker.service का मतलब है कि unit dead socket के खिलाफ docker compose चलाने के बजाय तुरंत fail हो जाती है। After= क्रम निर्धारित करता है, क्योंकि Requires= अकेले ऐसा नहीं करता है। RequiresMountsFor= systemd को उस path के लिए mount unit को pull करने और उसकी प्रतीक्षा करने के लिए मजबूर करता है, जो restart policy के बजाय unit का उपयोग करने का मुख्य कारण है। TimeoutStartSec=0 systemd को start job को तब तक kill करने से रोकता है जब तक कि एक बड़ी image pull हो रही हो।

दोनों mechanisms को संयोजित करने पर एक नोट। Docker का documentation host process manager के साथ restart policies को मिलाने के खिलाफ सलाह देता है। वह चेतावनी उस process manager के बारे में है जो container process की निगरानी करता है और उसे तब restart करता है जब daemon भी वही करने की कोशिश कर रहा हो। एक Type=oneshot unit किसी चीज़ की निगरानी नहीं करती है, इसलिए इस unit के साथ compose file में restart: unless-stopped रखना ठीक है, और आप यही चाहते हैं। systemd boot के समय ordering को संभालता है, और daemon उस container को संभालता है जो रात के तीन बजे crash हो जाता है।

जब आप जिस चीज़ को जीवित रख रहे हैं वह stack के बजाय एक साधारण long-running process होती है, तो unit अलग दिखती है, क्योंकि तब उसके नीचे कोई daemon नहीं होता है और systemd के अपने Restart= को ही निगरानी करनी पड़ती है; systemd के पीछे dsh headless चलाना उस स्वरूप का एक उदाहरण है, जिसमें dedicated user और journal का उपयोग शामिल है।

वास्तविक रीबूट के साथ सत्यापन करें

वास्तविक परीक्षण का कोई विकल्प नहीं है। systemctl restart docker माउंट ऑर्डरिंग का परीक्षण नहीं करता है, और docker compose down के बाद docker compose up -d बूट प्रक्रिया के बारे में कुछ भी जांच नहीं करता है।

sudo reboot

प्रतीक्षा करें, पुनः कनेक्ट करें, और इस क्रम में जाँच करें:

uptime
systemctl is-active docker
docker compose ps

uptime यह पुष्टि करता है कि आप उस मशीन को देख रहे हैं जो वास्तव में रीबूट हुई है। docker compose ps, जिसे स्टैक डायरेक्टरी से चलाया जाता है, को प्रत्येक सर्विस को running के रूप में सूचीबद्ध करना चाहिए, जिसका अपटाइम मशीन के अपटाइम के करीब हो। जो सर्विस Exited दिखा रही है, उसी की जाँच करने की आवश्यकता है।

यदि कोई सर्विस स्टार्ट नहीं हुई है, तो डेमन लॉग बूट विंडो को कवर करता है:

journalctl -u docker.service -b --no-pager | tail -50

यूनिट द्वारा प्रबंधित स्टैक के लिए, journalctl -u myapp.service -b --no-pager बूट से सटीक docker compose आउटपुट दिखाता है, जिसमें विफल इमेज पुल या गायब .env फाइल शामिल है। जिस रीबूट को आप शेड्यूल करते हैं, उसी पर आपको नजर रखनी चाहिए, इसलिए यूनिट को उन रीबूट्स के बारे में बताने दें जिन्हें आप नहीं देख रहे हैं: एक OnFailure= लाइन जो एक self-hosted ntfy server की ओर इशारा करती है, वह उस स्टैक को, जो वापस नहीं आ पाया, एक पुश नोटिफिकेशन में बदल देती है, बजाय इसके कि आप उसे दिनों बाद खोजें।

वे चीजें जो चुपचाप auto-start को बाधित करती हैं

docker compose run के साथ बनाए गए containers को file से restart policy कभी नहीं मिलती है। Compose उन्हें one-off containers के रूप में देखता है। यदि कोई service अपनी policy को ignore करती हुई प्रतीत हो, तो जाँचें कि क्या उसे up के बजाय run से start किया गया था।

Volume या env_file entry में एक relative path को compose file की directory के आधार पर resolve किया जाता है। यह आपके shell से काम करता है, और यह उस unit से भी काम करता है जो WorkingDirectory set करती है। यह उस unit से विफल हो जाता है जिसमें यह set नहीं है, क्योंकि उस स्थिति में working directory / होती है।

Rootless Docker एक अलग मामला है। Daemon एक user service के रूप में चलता है, और जब उस user का अंतिम session समाप्त होता है तो user service रुक जाती है। इसे user के लिए enable करें और इसे तब भी चलते रहने दें जब कोई भी logged in न हो:

systemctl --user enable docker
sudo loginctl enable-linger $USER

enable-linger के बिना, rootless daemon आपके log out होते ही बंद हो जाता है और containers भी उसके साथ बंद हो जाते हैं, जो बिल्कुल एक टूटी हुई restart policy जैसा दिखता है।

एक आखिरी बात। Automatic security updates एक निश्चित समय पर सर्वर को reboot कर सकते हैं, जो केवल तभी अच्छा है यदि आपका stack अपने आप वापस आ जाए। एक नई machine पर इसे set करना एक नए VPS पर पहले दस मिनट के दौरान किए जाने वाले शुरुआती कार्यों का हिस्सा है।

FAQ

restart: always और restart: unless-stopped में क्या अंतर है?

दोनों ही स्थितियों में container के अपने आप बंद होने पर वह पुनः start हो जाता है। अंतर तब आता है जब आप container को मैन्युअल रूप से बंद करते हैं। always के साथ, अगली बार Docker daemon start होने पर container फिर से start हो जाता है, यानी reboot करने पर आपका मैन्युअल stop निष्प्रभावी हो जाता है। unless-stopped के साथ, daemon याद रखता है कि container को जानबूझकर बंद किया गया था और वह उसे बंद ही रहने देता है। unless-stopped का उपयोग करें, जब तक कि आपको विशेष रूप से ऐसा container न चाहिए हो जो बंद न रहे।

मैंने restart: unless-stopped जोड़ा है लेकिन reboot के बाद भी container start नहीं होता। क्यों?

यह policy container पर लागू होती है, न कि file पर, और YAML को edit करने से पहले से मौजूद container update नहीं होता। docker compose up -d चलाएं ताकि Compose उसे फिर से create करे, फिर docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app) के साथ पुष्टि करें। यदि वह no प्रिंट करता है, तो container आपके edit से पहले का है। दूसरा सामान्य कारण docker.service का enabled न होना है, जिसे आप systemctl is-enabled docker के साथ जांच सकते हैं।

क्या मुझे systemd unit की आवश्यकता है यदि मैं पहले से ही restart policies का उपयोग कर रहा हूँ?

आमतौर पर नहीं। एक restart policy उस stack के लिए पर्याप्त है जिसे केवल network की आवश्यकता होती है, जो कि अधिकांश stacks के लिए सही है। unit तब जोड़ें जब containers किसी ऐसी चीज़ पर निर्भर हों जो Docker daemon के start होने पर तैयार नहीं होती, जैसे कि external disk, encrypted volume, NFS share, या VPN interface। unit आपको After= और RequiresMountsFor= के माध्यम से क्रम निर्धारित करने की सुविधा देती है, जिसे restart policy व्यक्त नहीं कर सकती।

मैं किसी stack को स्थायी रूप से कैसे बंद करूँ ताकि वह अगले reboot पर वापस न आए?

unless-stopped के साथ, docker compose stop पर्याप्त है, क्योंकि मैन्युअल रूप से बंद किए गए container को daemon के restart होने पर फिर से शुरू नहीं किया जाता है। always के साथ, केवल stop करना पर्याप्त नहीं है और reboot के बाद container वापस आ जाता है। या तो docker compose down चलाएं, जो containers को हटा देता है, या पहले docker update --restart no my-container के साथ policy बदलें। यदि कोई systemd unit stack को manage कर रही है, तो sudo systemctl disable myapp.service भी चलाएं, अन्यथा unit उसे फिर से start कर देगी।