SSD Nodes Learn 8GB RAM — $66/वर्ष
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-01

Docker Compose सेवा बूटवेळी आपोआप सुरू कशा कराव्यात

reboot नंतर Docker Compose सेवा सुरू ठेवण्यासाठी restart policies वापरा. on-failure एकदाच थांबलेल्या container नंतर पुन्हा सुरू का होत नाही आणि systemd unit कधी आवश्यक आहे ते समजा.

थोडक्यात उत्तर

Docker Compose सेवा बूटवेळी सुरू होण्यासाठी दोन अटी एकाच वेळी पूर्ण झाल्या पाहिजेत. Docker daemon system service म्हणून सक्षम केलेला असावा आणि फाइलमधील प्रत्येक सेवेसाठी unless-stopped किंवा always restart policy दिलेली असावी. प्रत्येक सेवेत restart: unless-stopped जोडा, docker compose up -d एकदा चालवा आणि reboot नंतर containers आपोआप पुन्हा सुरू होतील. सामान्य परिस्थितीत याशिवाय दुसरे काही आवश्यक नाही.

क्रम महत्त्वाचा असेल तेव्हाच systemd unit आवश्यक असते: Docker daemon सुरू होताना mounted disk, VPN interface किंवा network share उपलब्ध नसलेला stack. ही परिस्थिती प्रत्यक्षात येऊ शकते आणि या मार्गदर्शकाच्या दुसऱ्या भागात तिचे वर्णन केले आहे. तुम्ही अजून service definitions आणि volumes समजून घेत असाल, तर VPS वरील Docker Compose च्या मूलभूत बाबी पासून सुरुवात करा आणि नंतर येथे परत या.

compose.yaml मध्ये restart policy सेट करा

ही policy प्रत्येक service साठी एका ओळीत असते. कोणताही global switch नाही. त्यामुळे एखाद्या service साठी policy सेट करणे विसरलात, तर reboot नंतर तो service बंद राहतो आणि stack मधील इतर service सुरू होतात.

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 प्रदर्शित झाल्यास, फाइल संपादित केली आहे; परंतु container पुन्हा तयार केलेला नाही.

ही सर्वाधिक आढळणारी चूक आहे. restart policy YAML फाइलमध्ये नाही, तर container वर साठवली जाते. compose.yaml संपादित केल्याने आधीपासून अस्तित्वात असलेल्या container मध्ये कोणताही बदल होत नाही. docker compose restart देखील उपयोगी ठरत नाही, कारण ते त्याच container object ला थांबवून पुन्हा सुरू करते आणि त्याच्या configuration मध्ये बदल करत नाही. फक्त docker compose up -d फाइलची चालू container शी तुलना करते, policy बदलल्याचे ओळखते आणि container पुन्हा तयार करते.

सध्या पुन्हा तयार करू इच्छित नसलेल्या container साठी policy थेट त्याच्यावर बदला:

docker update --restart unless-stopped my-container

YAML फाइलही संपादित करा. docker update चालू container मध्ये बदल करते, आणि पुढील docker compose up -d फाइल वाचून जुनी value पुन्हा लागू करेल.

प्रत्येक restart मूल्य प्रत्यक्षात काय करते

Docker चार मूल्ये परिभाषित करते. यांतील फरक मशीन reboot झाल्यावर किंवा daemon पुन्हा सुरू झाल्यावरच दिसून येतो.

  • no हे default आहे. कोणत्याही परिस्थितीत container आपोआप पुन्हा सुरू होत नाही.
  • always container थांबला की तो पुन्हा सुरू करते. तुम्ही तो स्वतः थांबवला असला, तरी Docker daemon पुढच्या वेळी सुरू झाल्यावर तो पुन्हा सुरू होतो. हे अनेकदा अनपेक्षित असते: तुम्ही मागील आठवड्यात जाणीवपूर्वक थांबवलेला container reboot नंतर पुन्हा सुरू असतो.
  • unless-stopped हे always प्रमाणेच कार्य करते. मात्र, स्वतः थांबवलेला container daemon पुन्हा सुरू झाल्यावरही थांबलेलाच राहतो. देखभालीसाठी अधूनमधून बंद कराव्या लागणाऱ्या service साठी हे मूल्य योग्य आहे.
  • on-failure container केवळ non-zero exit code सह बंद झाल्यावर पुन्हा सुरू करते. restart: on-failure:3 प्रमाणे तुम्ही प्रयत्नांची कमाल संख्या निश्चित करू शकता.

server सुरू असताना stack फक्त सुरू असावा असे अपेक्षित असल्यास, unless-stopped हे योग्य default आहे. container बंद स्थितीत राहू नये असे तुम्हाला हवे असल्यासच always निवडा.

रीबूटनंतर on-failure टिकत नाही: कारण

अनेक जण on-failure निवडतात, कारण ते सावध पर्याय वाटतो. मात्र पहिल्या रीबूटनंतर प्रत्येक container थांबलेला आढळतो. याचे कारण त्याच्या व्याख्येत आहे. on-failure फक्त एका घटनेवर प्रतिक्रिया देते: container प्रक्रिया error code सह बंद होणे.

रीबूट ही त्रुटी नाही. host बंद होताना systemd docker.service थांबवते आणि daemon प्रत्येक container मुद्दाम थांबवतो. container अयशस्वी झालेला नसल्यामुळे policy कडे प्रतिक्रिया देण्यासाठी काहीही नसते. host पुन्हा सुरू झाल्यावर daemon ज्या container पुन्हा सुरू करणे आवश्यक आहे त्यांची तपासणी करतो. स्वच्छपणे थांबवलेला on-failure container त्यापैकी एक नसतो. तो exited स्थितीतच राहतो.

हे थेट पाहता येते. एखाद्या service वर restart: on-failure सेट करा, docker compose up -d चालवा, रीबूट करा आणि नंतर हे चालवा:

docker compose ps -a

service Exited स्थितीसह आणि Exited (0) 2 minutes ago सारख्या status सह सूचीबद्ध केलेली दिसते. काहीही बिघडलेले नसते आणि कोणतीही गोष्ट error म्हणून log केलेली नसते. त्यामुळे या समस्येचे निदान करणे कठीण होते. policy तिच्या व्याख्येनुसारच कार्य करते.

on-failure अजूनही उपयुक्त आहे. एखादे काम चालवणाऱ्या आणि crash होण्याची शक्यता असलेल्या container साठी ते योग्य आहे, जेव्हा मर्यादित संख्येने retry हवेत आणि restart loop नको असतो. रीबूटनंतर दीर्घकाळ चालणारी service सुरू ठेवण्यासाठी हे योग्य साधन नाही.

पुनःप्रारंभ धोरणे Docker सेवा बूटवेळी सुरू झाल्यासच कार्य करतात

पुनःप्रारंभ धोरणांची अंमलबजावणी Docker daemon करतो. daemon सुरू झाला नाही, तर कोणतीही अंमलबजावणी होत नाही. ते तपासा:

systemctl is-enabled docker
systemctl is-enabled containerd

दोन्ही ठिकाणी enabled छापले गेले पाहिजे. Docker च्या अधिकृत repository मधील packages स्थापना करताना ही सेटिंग्ज सक्षम करतात. त्यामुळे नवीन server वर ही तपासणी सामान्यतः यशस्वी होते. यांपैकी कोणत्याही ठिकाणी disabled छापले गेले, तर ते दुरुस्त करा:

sudo systemctl enable --now docker containerd

येथे एक महत्त्वाचा मुद्दा समजून घेणे आवश्यक आहे. Ubuntu मध्ये docker.socket देखील समाविष्ट असते. Docker API शी प्रथमच काहीतरी संवाद साधल्यावर ते daemon मागणीनुसार सुरू करते. docker.socket सक्षम असल्याचे पाहून काही जण daemon संरक्षित आहे असे गृहीत धरतात आणि memory वाचवण्यासाठी docker.service अक्षम करतात. बूटवेळी API ला कोणताही call होत नाही. त्यामुळे socket ला कधीही प्रवेश होत नाही, daemon सुरू होत नाही आणि तुम्ही पहिली docker command टाइप करेपर्यंत कोणताही container सुरू होत नाही. docker.service सक्षम असण्याला socket activation पर्याय नाही.

systemd unit हा अधिक योग्य पर्याय कधी असतो

Restart धोरणांमध्ये प्रणालीतील इतर घटकांशी क्रम ठरवण्याची संकल्पना नसते. Daemon सुरू होतो आणि शक्य तितक्या लवकर तुमचे containers सुरू करतो. तुमच्या stack मध्ये स्वतंत्र volume, NFS (network file system) share किंवा encrypted disk वरील directory bind-mount केली असल्यास, तो path उपलब्ध होण्यापूर्वी containers सुरू होऊ शकतात. Docker mount point वर रिकामी directory तयार करून त्यावर container सुरू करतो. त्यामुळे तुमचा database कोणत्याही data शिवाय सुरू होतो.

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

systemd युनिट लिहिणे

स्टॅक home directory च्या बाहेर असलेल्या निश्चित path मध्ये ठेवा. /srv/myapp हा चांगला पर्याय आहे, कारण कोणीही 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 करून सुरू करा:

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

सुरळीतपणे चालणारे युनिट Active: active (exited) दाखवते. हे प्रथम पाहिल्यावर चुकीचे वाटते. ते योग्य आहे: RemainAfterExit=yes सह Type=oneshot याचा अर्थ युनिटने त्याची command चालवली, command पूर्ण झाली आणि systemd युनिटला active म्हणून चिन्हांकित ठेवते, जेणेकरून shutdown वेळी ExecStop चालेल.

प्रत्येक ओळीचा विशिष्ट उद्देश आहे. Requires=docker.service याचा अर्थ dead socket विरुद्ध docker compose चालवण्याऐवजी युनिट त्वरित अपयशी ठरते. After= क्रम निश्चित करते, कारण Requires= हे एकटे तसे करत नाही. RequiresMountsFor= मुळे systemd त्या path साठी mount unit समाविष्ट करून त्याची प्रतीक्षा करते. युनिट वापरण्याचे हेच मुख्य कारण आहे, restart policy वापरण्याचे नाही. मोठी image अद्याप pull होत असताना TimeoutStartSec=0 systemd ला start job थांबवण्यापासून प्रतिबंधित करते.

दोन यंत्रणा एकत्र वापरण्याबाबत एक सूचना. Docker च्या documentation मध्ये restart policies आणि host process manager एकत्र न वापरण्याचा सल्ला दिला आहे. ही सूचना container process चे स्वतः supervision करणाऱ्या आणि daemon तेच करण्याचा प्रयत्न करत असताना process पुन्हा सुरू करणाऱ्या process manager संदर्भात आहे. Type=oneshot unit कोणत्याही process चे supervision करत नाही. त्यामुळे या युनिटसोबत compose file मध्ये restart: unless-stopped ठेवणे योग्य आहे आणि तुम्हाला तेच हवे आहे. Boot वेळी क्रम systemd हाताळते आणि पहाटे तीन वाजता crash होणाऱ्या container ला daemon हाताळतो.

प्रत्यक्ष रीबूट करून पडताळणी करा

प्रत्यक्ष चाचणीला पर्याय नाही. 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 आउटपुट दाखवते. त्यात अयशस्वी image pull किंवा गहाळ .env फाइलसुद्धा दिसते.

स्वयंचलित सुरूवात शांतपणे बिघडण्याची कारणे

docker compose run ने तयार केलेल्या कंटेनरना फाइलमधील restart policy कधीही मिळत नाही. Compose त्यांना एकदाच चालणारे कंटेनर मानते. एखादी service तिच्या policy कडे दुर्लक्ष करत असल्यास, ती up ऐवजी run ने सुरू केली होती का ते तपासा.

volume मधील किंवा env_file entry मधील सापेक्ष path compose file च्या directory च्या संदर्भात ठरवला जातो. हे तुमच्या shell मधून कार्य करते. WorkingDirectory सेट करणाऱ्या unit मधूनही ते कार्य करते. WorkingDirectory नसलेल्या unit मधून ते अयशस्वी होते, कारण त्या वेळी working directory / असते.

Rootless Docker हे वेगळे प्रकरण आहे. daemon user service म्हणून चालतो. त्या user चे शेवटचे session संपल्यावर user service थांबते. तो user साठी enable करा आणि कोणताही user login केलेला नसतानाही तो चालू ठेवण्याची परवानगी द्या:

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

enable-linger शिवाय, तुम्ही logout केल्यावर rootless daemon बंद होतो आणि त्याच्यासोबत कंटेनरही बंद होतात. त्यामुळे restart policy बिघडल्यासारखेच दिसते.

आणखी एक मुद्दा. Automatic security updates मुळे server ठरावीक वेळी reboot होऊ शकतो. तुमचा stack स्वतःहून पुन्हा सुरू होत असेल तरच हे उपयुक्त ठरते. नवीन machine वर हे सेट करणे, नवीन VPS वरील पहिल्या दहा मिनिटांतील इतर प्रारंभिक कामांसोबत करावे.

FAQ

restart: always आणि restart: unless-stopped यांच्यात काय फरक आहे?

कंटेनर स्वतःहून थांबल्यावर दोन्ही धोरणे तो पुन्हा सुरू करतात. तुम्ही कंटेनर हाताने थांबवल्यानंतर त्यांचे वर्तन वेगळे असते. always वापरल्यास, Docker daemon पुढच्या वेळी सुरू झाल्यावर कंटेनर पुन्हा सुरू होतो. त्यामुळे reboot केल्यावर तुमची हाताने केलेली stop कृती रद्द होते. unless-stopped वापरल्यास, कंटेनर जाणीवपूर्वक थांबवला आहे हे daemon लक्षात ठेवतो आणि तो पुन्हा सुरू करत नाही. कंटेनर कायम बंद राहावा अशी विशेष गरज नसल्यास unless-stopped वापरा.

restart: unless-stopped जोडले, तरी reboot नंतर कंटेनर सुरू होत नाही. का?

धोरण file मध्ये नसून कंटेनरवर लागू असते. YAML संपादित केल्याने आधीपासून अस्तित्वात असलेला कंटेनर अपडेट होत नाही. Compose ने कंटेनर पुन्हा तयार करण्यासाठी docker compose up -d चालवा. त्यानंतर docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app) वापरून खात्री करा. त्यातून no दिसल्यास, तुमच्या संपादनापूर्वीच कंटेनर तयार झाला होता. दुसरे सामान्य कारण म्हणजे docker.service सक्षम केलेले नसणे. हे systemctl is-enabled docker वापरून तपासता येते.

मी restart policies वापरत असल्यास systemd unit आवश्यक आहे का?

सामान्यतः नाही. ज्या stack ला फक्त network आवश्यक असते, त्यासाठी restart policy पुरेशी असते. बहुतेक stack याच प्रकारचे असतात. Docker daemon सुरू होताना तयार नसलेल्या एखाद्या गोष्टीवर कंटेनर अवलंबून असल्यास unit जोडा. उदाहरणार्थ, external disk, encrypted volume, NFS share किंवा VPN interface. Restart policy व्यक्त करू शकत नाही असा क्रम unit तुम्हाला After= आणि RequiresMountsFor= द्वारे लागू करू देते.

पुढील reboot नंतर stack पुन्हा सुरू होऊ नये म्हणून तो कायमचा कसा थांबवायचा?

unless-stopped वापरत असल्यास docker compose stop पुरेसे आहे, कारण हाताने थांबवलेला कंटेनर daemon पुन्हा सुरू झाल्यावर पुन्हा सुरू होत नाही. always वापरत असल्यास stop पुरेसे नाही. reboot नंतर कंटेनर पुन्हा सुरू होतो. docker compose down चालवा. यामुळे कंटेनर काढले जातात. किंवा आधी docker update --restart no my-container वापरून धोरण बदला. systemd unit stack व्यवस्थापित करत असल्यास sudo systemctl disable myapp.service देखील चालवा. अन्यथा unit तो पुन्हा सुरू करेल.