SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-10-24

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

reboot नंतर Docker Compose सेवा सुरू ठेवण्यासाठी restart policy वापरा. on-failure का पुरेसे नाही आणि mounted disk किंवा VPN साठी systemd unit कधी आवश्यक आहे ते जाणून घ्या.

थोडक्यात

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

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

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

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

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 असे output मिळते. no असे output मिळाल्यास file edit केली आहे, पण container पुन्हा तयार केलेला नाही.

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

सध्या पुन्हा तयार करायचा नसलेल्या container साठी policy थेट लागू करा:

docker update --restart unless-stopped my-container

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

प्रत्येक restart value प्रत्यक्षात काय करते

Docker चार values परिभाषित करते. त्यांच्यातील फरक machine reboot झाल्यावर किंवा daemon restart केल्यावरच दिसतो.

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

Server up असताना stack ने फक्त up राहावे असे अपेक्षित असल्यास, unless-stopped हे योग्य default आहे. Container down स्थितीत राहू नये असे हवे असल्यासच always निवडा.

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

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

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

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

docker compose ps -a

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

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

रीबूटच्या वेळी Docker सेवा सुरू झाली तरच restart policies कार्य करतात

restart policies ची अंमलबजावणी Docker daemon करतो. daemon सुरू झाला नाही, तर कोणतीही policy लागू होत नाही. हे तपासा:

systemctl is-enabled docker
systemctl is-enabled containerd

दोन्ही आदेशांनी enabled प्रदर्शित केले पाहिजे. Docker च्या अधिकृत repository मधील packages install करताना हे आपोआप enable करतात. त्यामुळे नवीन server वर ही तपासणी सहसा यशस्वी होते. यापैकी कोणत्याही आदेशाने disabled प्रदर्शित केले, तर ते दुरुस्त करा:

sudo systemctl enable --now docker containerd

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

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

Restart policies मध्ये प्रणालीतील इतर घटकांशी क्रम ठरवण्याची कोणतीही संकल्पना नसते. 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 तयार असणे आवश्यक आहे. box वरील इतर प्रत्येक service प्रमाणे systemctl stop myapp आणि systemctl start myapp कार्य करावेत अशी तुमची इच्छा आहे. किंवा shutdown वेळी daemon सोबत stack ला जबरदस्तीने बंद करण्याऐवजी ते व्यवस्थित बंद करायचे आहे. systemd units तुमच्यासाठी नवीन असल्यास, systemd service आणि timer लिहिणे या मार्गदर्शिकेत file format अधिक तपशीलाने स्पष्ट केला आहे.

systemd unit लिहिणे

stack साठी home directory च्या बाहेर एक स्थिर path वापरा. /srv/myapp हा चांगला पर्याय आहे, कारण कोणीही login करण्यापूर्वी चालणाऱ्या unit ला /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

निरोगी 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 समाविष्ट करते आणि त्याची प्रतीक्षा करते. restart policy ऐवजी unit वापरण्याचे हेच मुख्य कारण आहे. मोठी image अजून pull होत असताना TimeoutStartSec=0 systemd ला start job थांबवण्यापासून रोखते.

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

ज्याला चालू ठेवायचे आहे ते stack ऐवजी साधे दीर्घकाळ चालणारे process असल्यास unit वेगळी दिसते. अशा वेळी त्याखाली daemon नसतो आणि systemd च्या स्वतःच्या Restart= ला supervision करावे लागते; systemd मागे headless dsh चालवणे हा त्या रचनेचा सविस्तर उदाहरण आहे. त्यात dedicated user आणि journal यांचाही समावेश आहे.

प्रत्यक्ष reboot सह पडताळणी

प्रत्यक्ष चाचणीला पर्याय नाही. systemctl restart docker मुळे mount ordering तपासले जात नाही आणि docker compose down नंतर docker compose up -d चालवल्याने boot संदर्भातील कोणतीही बाब तपासली जात नाही.

sudo reboot

थांबा, पुन्हा कनेक्ट करा आणि पुढील क्रमाने तपासा:

uptime
systemctl is-active docker
docker compose ps

uptime मुळे तुम्ही खरोखर reboot झालेल्या मशीनकडे पाहत आहात याची खात्री होते. स्टॅकच्या directory मधून चालवलेले docker compose ps प्रत्येक service ची स्थिती running म्हणून दाखवायला हवे आणि uptime मशीनच्या uptime जवळ असायला हवा. एखादी service Exited दाखवत असल्यास तिची तपासणी करा.

एखादी गोष्ट सुरू झाली नसेल, तर daemon log मध्ये boot window मधील माहिती मिळते:

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

unit द्वारे व्यवस्थापित स्टॅकसाठी journalctl -u myapp.service -b --no-pager boot पासूनचे अचूक docker compose output दाखवते. यात अपयशी image pull किंवा गहाळ .env file यांचाही समावेश असतो. तुम्ही schedule केलेला reboot तुम्ही स्वतः monitor करता. त्यामुळे ज्या reboot वर तुम्ही लक्ष ठेवत नाही, त्यांची माहिती unit कडून मिळू द्या: स्वतःच्या server वर चालणाऱ्या ntfy server कडे निर्देश करणारी OnFailure= line, पुन्हा सुरू न झालेला stack तुम्हाला काही दिवसांनी लक्षात येण्याऐवजी push notification मध्ये कळवते.

आपोआप सुरू होण्याची प्रक्रिया शांतपणे बिघडवणाऱ्या गोष्टी

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

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

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

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

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

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

FAQ

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

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

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

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

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

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

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

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

हा लेख उपयुक्त होता का?