اگر بعد از Reboot سرور، Docker بالا میآید اما سرویسهای تعریفشده در Docker Compose اجرا نمیشوند، دو راه اصلی دارید: تعریف Restart Policy برای Containerها یا ساخت یک سرویس systemd که پروژه Compose را بعد از بالا آمدن Docker اجرا کند.
پاسخ سریع: اگر Containerها یکبار با Compose ساخته شدهاند، در بسیاری از پروژهها اضافهکردن restart: unless-stopped یا restart: always کافی است. اگر میخواهید خود Stack Compose با systemd مدیریت شود، یک Unit بسازید که بعد از docker.service دستور docker compose up -d را اجرا کند.
روش اول: استفاده از Restart Policy در Docker Compose
برای بیشتر پروژههای ساده، این روش کافی است. نمونه:
services:
web:
image: nginx:latest
restart: unless-stopped
db:
image: postgres:16
restart: unless-stopped
طبق مستندات Docker، گزینه restart میتواند مقادیری مانند no، always، on-failure و unless-stopped داشته باشد.
تفاوت always و unless-stopped
always باعث میشود Container بعد از توقف دوباره اجرا شود و پس از Restart شدن Docker Daemon نیز دوباره بالا بیاید.
unless-stopped تقریباً مشابه آن است، با این تفاوت که اگر Container را عمداً Stop کرده باشید، بعد از Restart شدن Docker بهصورت خودکار دوباره اجرا نمیشود.
بعد از تغییر restart باید چه کنیم؟
وارد پوشه پروژه شوید:
cd /opt/myapp
کانفیگ را بررسی کنید:
docker compose config
سپس Compose را اعمال کنید:
docker compose up -d
Docker Compose با up -d سرویسها را ایجاد یا اجرا میکند و در حالت Detached بعد از بالا آوردن Containerها از Terminal خارج میشود.
روش دوم: اجرای Docker Compose با systemd
اگر میخواهید خود پروژه Compose مثل یک سرویس Linux مدیریت شود، میتوانید برای آن Unit File بسازید.
فرض کنیم پروژه در این مسیر است:
/opt/myapp
و فایل Compose نیز در همین مسیر قرار دارد.
مرحله ۱: مسیر docker را پیدا کنید
which docker
در بسیاری از سرورها:
/usr/bin/docker
مرحله ۲: Unit File بسازید
sudo nano /etc/systemd/system/myapp-compose.service
نمونه Unit:
[Unit]
Description=MyApp Docker Compose
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose stop
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
این Unit File چه کاری انجام میدهد؟
Requires=docker.service وابستگی سرویس Compose به Docker را تعریف میکند.
After=docker.service باعث میشود Unit بعد از Docker اجرا شود.
WorkingDirectory=/opt/myapp پوشهای را مشخص میکند که فایل Compose داخل آن قرار دارد.
ExecStart پروژه را اجرا میکند.
RemainAfterExit=yes باعث میشود بعد از پایان موفق فرمان docker compose up -d، systemd Unit را Active در نظر بگیرد.
آیا ExecStop بهتر است stop باشد یا down؟
در نمونه بالا از:
docker compose stop
استفاده شده است، چون فقط Containerها را Stop میکند و ساختار پروژه را حذف نمیکند.
اگر بهجای آن از:
docker compose down
استفاده کنید، Compose علاوه بر Stop کردن Containerها، Containerها و Networkهای پروژه را نیز حذف میکند. بنابراین برای Shutdown معمولی سرور، stop معمولاً محافظهکارانهتر است.
مرحله ۳: Unit را بررسی کنید
systemd-analyze verify /etc/systemd/system/myapp-compose.service
اگر Error وجود ندارد، systemd را Reload کنید:
sudo systemctl daemon-reload
مرحله ۴: سرویس Compose را Enable کنید
sudo systemctl enable --now myapp-compose.service
وضعیت:
systemctl status myapp-compose.service --no-pager
Containerها را نیز بررسی کنید:
cd /opt/myapp
docker compose ps
Docker Compose روی VPS اجرا میکنید؟
اگر چند Container، دیتابیس و سرویس دائمی دارید، علاوه بر Auto-start باید RAM، Storage، Restart Policy و Healthcheckها را نیز متناسب با پروژه تنظیم کنید.
تماس با پشتیبانی ایرانیکاسرور:
021-91302467
مرحله ۵: بعد از Reboot تست کنید
قبل از Reboot مطمئن شوید سرویس Enable است:
systemctl is-enabled myapp-compose.service
در صورت آماده بودن سرور برای Reboot:
sudo reboot
بعد از بالا آمدن سرور:
systemctl status docker --no-pager
systemctl status myapp-compose.service --no-pager
cd /opt/myapp
docker compose ps
اگر Compose بعد از Reboot اجرا نشد
Log Unit را بخوانید:
journalctl -u myapp-compose.service -b --no-pager
همچنین Log Compose:
cd /opt/myapp
docker compose logs --tail=100
خطای docker: ‘compose’ is not a docker command
اگر systemd این خطا را ثبت کند، احتمالاً Docker Compose Plugin نصب نیست یا مسیر/نسخه Docker شما متفاوت است.
ابتدا:
docker compose version
اگر از Compose قدیمی مستقل استفاده میکنید، ممکن است فرمان شما docker-compose باشد؛ ولی برای نصبهای جدید بهتر است Docker Compose Plugin و Syntax جدید docker compose استفاده شود.
Environment File در systemd و Docker Compose
اگر Compose از فایل .env استفاده میکند، WorkingDirectory اهمیت زیادی دارد؛ چون Compose معمولاً فایلهای پروژه را نسبت به مسیر پروژه Resolve میکند.
به همین دلیل این خط در Unit مهم است:
WorkingDirectory=/opt/myapp
آیا network-online.target لازم است؟
در بیشتر Compose Stackها وابستگی به docker.service کافی است؛ اما اگر Containerها بلافاصله بعد از Start به یک سرویس Remote، DNS یا API خارجی متصل میشوند و Startup آنها بدون شبکه Fail میشود، میتوانید بررسی کنید آیا Unit واقعاً به network-online.target نیاز دارد.
نمونه:
[Unit]
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target
ترتیب Start سرویسهای داخل Compose
بالا آمدن Docker Compose به این معنی نیست که Database یا Redis فوراً آماده پاسخگویی هستند. Docker Compose سرویسها را بر اساس Dependency ایجاد میکند، اما Running شدن یک Container الزاماً به معنی Ready بودن Application داخل آن نیست.
برای سرویسهایی مثل PostgreSQL بهتر است Healthcheck تعریف کنید:
services:
db:
image: postgres:16
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
web:
image: myapp:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
Docker Compose میتواند برای Dependency با شرط service_healthy منتظر Healthy شدن سرویس وابسته بماند. :chatgpt-content-reference{index=”1″}
restart policy یا systemd؛ کدام بهتر است؟
| سناریو | روش مناسب |
|---|---|
| فقط اجرای دوباره Container بعد از Reboot | restart: unless-stopped |
| مدیریت کل Stack با systemctl | systemd Unit |
| وابستگی به Docker Service | systemd Unit |
| Restart ساده Containerهای موجود | Restart Policy |
| کنترل Startup/Shutdown پروژه | systemd Unit |
پرسشهای متداول
آیا برای اجرای Docker Compose بعد از Reboot حتماً systemd لازم است؟
خیر. اگر Containerها قبلاً ساخته شدهاند و Restart Policy مناسب دارند، Docker Daemon میتواند آنها را بعد از Restart دوباره اجرا کند.
برای Auto-start بهتر است always بگذاریم یا unless-stopped؟
برای بسیاری از سرویسهای دائمی unless-stopped مناسب است، چون اگر Container را عمداً Stop کنید، بعد از Restart Daemon دوباره اجرا نمیشود.
docker compose start بهتر است یا up -d؟
start فقط Containerهایی را اجرا میکند که قبلاً ایجاد شدهاند. up -d میتواند سرویسهای تعریفشده را ایجاد یا اجرا کند و برای Unit مدیریت یک پروژه کامل معمولاً انعطاف بیشتری دارد. :chatgpt-content-reference{index=”2″}
بعد از تغییر compose.yml باید systemd را daemon-reload کنیم؟
اگر فقط فایل Compose تغییر کرده باشد و Unit File ثابت مانده باشد، معمولاً daemon-reload برای systemd لازم نیست. کافی است دوباره docker compose up -d یا Restart مناسب پروژه را اجرا کنید. اگر Unit File تغییر کرده، daemon-reload لازم است.
چرا Container بعد از Reboot Running است اما برنامه کار نمیکند؟
ممکن است Dependency مانند دیتابیس هنوز Ready نشده باشد. Healthcheck و depends_on با شرط مناسب را بررسی کنید.
آیا ExecStop را روی docker compose down بگذاریم؟
برای Shutdown معمولی، stop محافظهکارانهتر است. down Containerها و Networkهای Compose را حذف میکند و ممکن است در هر Stop سرویس چیزی فراتر از نیاز شما انجام دهد.
منابع رسمی
🔹 Docker Compose Services و Restart Policy
🔹 Docker Compose Startup Order و Healthcheck
🔹 تفاوت docker compose up و start
جمعبندی
برای اجرای خودکار Docker Compose بعد از Reboot، ابتدا مشخص کنید فقط Auto-restart Containerها را میخواهید یا مدیریت کامل Stack با systemd. برای حالت اول Restart Policy داخل Compose معمولاً کافی است. برای مدیریت کاملتر، یک Unit با وابستگی به docker.service، WorkingDirectory صحیح و ExecStart مبتنی بر docker compose up -d بسازید. بعد از Boot نیز Status سرویس و سلامت Containerها را بررسی کنید.
Docker Compose بعد از Reboot بالا نمیآید؟
اگر Docker فعال است اما Stack Compose اجرا نمیشود، میتوانید برای بررسی Unit File، Restart Policy، Environment، Healthcheck و Logهای Boot درخواست فنی ثبت کنید.
تماس با پشتیبانی ایرانیکاسرور:
021-91302467






دیدگاهها (۰)