Skip to Content

Volume در Docker چیست و چه زمانی استفاده می‌شود؟ راهنمای انتخاب Storage ماندگار

Volume داده را خارج از writable layer کانتینر نگه می‌دارد. تفاوت volume، bind mount و tmpfs، مجوز، lifecycle، performance و معیار انتخاب را بررسی کنید.

نویسنده مدیر کل تاریخ انتشار
این پست را به اشتراک بگذارید

Container باید قابل‌حذف و جایگزینی باشد، اما دیتابیس، upload کاربر و بعضی stateها باید بعد از recreate باقی بمانند. Docker Volume فضایی است که lifecycle آن از writable layer کانتینر جداست و Docker مدیریت mount آن را بر عهده می‌گیرد. این ماندگاری به معنی backup، replication یا دسترس‌پذیری روی host دیگر نیست.

پاسخ سریع: برای داده ماندگار برنامه که Docker باید محل آن را مدیریت کند از named volume استفاده کنید؛ برای توسعه یا فایل hostمحور با مسیر صریح، bind mount ممکن است مناسب باشد؛ برای داده موقت حساس یا cache کوتاه‌عمر، tmpfs را بررسی کنید. قبل از انتخاب، مالکیت، backup، portability، performance و رفتار حذف را مشخص کنید.

چرا writable layer برای داده مهم مناسب نیست؟

لایه نوشتنی به همان container وابسته است و با حذف آن از دسترس می‌رود. storage driver نیز برای الگوی copy-on-write طراحی شده و همیشه بهترین محل دیتابیس پرنوشتن نیست. image باید کد و dependency را حمل کند، نه وضعیت زنده مشتری. جداسازی state امکان rebuild و rollback برنامه را می‌دهد، اما migration داده همچنان باید سازگار باشد.

Named Volume چگونه دیده می‌شود؟

Volume نام‌دار در Compose تعریف و در مسیر داخل container mount می‌شود. برنامه فقط مسیر داخل container را می‌بیند؛ Docker محل host و driver را مدیریت می‌کند. برای مدیریت روزمره بهتر است به‌جای دستکاری مستقیم پوشه داخلی Docker، volume را از طریق container ابزار یا فرمان‌های Docker mount کنید. ساختار storage داخلی implementation detail است و تغییر دستی ownership می‌تواند سرویس را خراب کند.

Bind Mount چه تفاوتی دارد؟

Bind mount یک مسیر مشخص host را به container وصل می‌کند. برای mount source در Development، config قابل‌ویرایش یا integration با فایل host مفید است. در مقابل، برنامه به layout و permission همان host وابسته می‌شود و container ممکن است فایل‌های host را تغییر دهد. مسیر اشتباه یا خالی می‌تواند config واقعی را بپوشاند. mount فقط‌خواندنی برای config و assetهایی که نباید تغییر کنند انتخاب امن‌تری است.

tmpfs چه زمانی مفید است؟

tmpfs داده را در حافظه نگه می‌دارد و با توقف container باقی نمی‌ماند. برای فایل موقت حساس یا cache‌ای که نباید روی disk باشد مناسب است، به شرط کنترل اندازه و فشار RAM. tmpfs جای volume دیتابیس یا backup نیست. اگر برنامه انتظار می‌رود پس از restart همان session یا فایل را ببیند، tmpfs انتخاب درستی نیست.

جدول تصمیم سریع

  • Named volume: داده ماندگار تحت مدیریت Docker، جابه‌جایی ساده‌تر بین containerهای همان host.
  • Bind mount: ارتباط صریح با فایل یا پوشه host، مناسب source/config با کنترل مسیر.
  • tmpfs: داده موقت و فرّار در حافظه.
  • Object/block storage بیرونی: وقتی چند host، ظرفیت یا durability مستقل لازم است؛ نیازمند طراحی برنامه.

هیچ گزینه‌ای به‌تنهایی بهترین نیست. دیتابیس، upload و cache نیازهای متفاوت دارند و ممکن است در یک stack از سه نوع storage استفاده شود.

نمونه Compose برای Volume نام‌دار

services:
  app:
    image: registry.example/app@sha256:...
    volumes:
      - app_data:/var/lib/app
volumes:
  app_data:

مسیر /var/lib/app باید همان مسیر واقعی نوشتن برنامه باشد. اگر image هنگام اولین اجرا داده اولیه در آن مسیر دارد، رفتار copy/populate volume را در نسخه Docker خود آزمون کنید. mount کردن volume روی مسیر اشتباه ممکن است فایل‌های داخل image را پنهان کند. digest و نام image نمونه‌اند.

Anonymous Volume چرا دردسر می‌شود؟

Volume بی‌نام می‌تواند هنگام اجرای موقت ایجاد شود و بعد از حذف container باقی بماند، در نتیجه تشخیص مالک و پاک‌سازی دشوار می‌شود. برای داده مهم نام روشن، label، owner و مستند lifecycle داشته باشید. پیش از prune، volumeها را به container و پروژه مرتبط کنید؛ پاک‌سازی کورکورانه روی host production می‌تواند داده لازم را حذف کند.

مجوز، UID و GID

برنامه non-root باید روی مسیر لازم حق نوشتن داشته باشد. UID/GID داخل image ممکن است با فایل‌های موجود volume هماهنگ نباشد. خطای permission را با chmod 777 عمومی حل نکنید؛ مالکیت و mode حداقلی را برای user runtime تنظیم کنید. اگر چند container یک volume را مشترک می‌نویسند، locking و semantics برنامه را بررسی کنید؛ filesystem مشترک خودبه‌خود concurrency را ایمن نمی‌کند.

Read-only و جداسازی مسیرها

config، certificate و static asset اغلب باید read-only mount شوند. مسیر upload، cache و log را از هم جدا کنید تا policy backup و retention یکسان به همه تحمیل نشود. read-only root filesystem همراه با mountهای writable محدود، تغییر ناخواسته runtime را کم می‌کند. قبل از فعال‌سازی، مسیرهای temp و socket برنامه را شناسایی کنید.

Volume Driver و Storage بیرونی

Driver می‌تواند storage شبکه یا سرویس بیرونی را ارائه کند، اما latency، locking، failover و credential آن با filesystem محلی فرق دارد. plugin یا NFS به‌تنهایی high availability نمی‌سازد. رفتار قطع شبکه، reconnect و corruption را در staging بررسی کنید. برای دیتابیس، راهنمای سازنده آن درباره filesystem و fsync مهم‌تر از راحتی mount است.

Performance را با workload واقعی بسنجید

دیتابیس به latency و durability حساس است؛ upload بیشتر به ظرفیت و throughput. benchmark عمومی روی لپ‌تاپ معیار production نیست. storage driver، host filesystem، encryption، شبکه و محدودیت container بر نتیجه اثر دارند. علاوه بر throughput، p95 latency، fsync، queue و رفتار نزدیک پرشدن Disk را ببینید.

Volume و چند Replica

Named volume محلی معمولاً به همان Docker host وابسته است. اگر replica روی host دیگری بالا بیاید، داده به‌طور خودکار همراهش نمی‌رود. برای چند node باید state را به دیتابیس/شیء‌ذخیره‌سازی مدیریت‌شده، replication یا storage مشترک مناسب منتقل کنید. mount یک filesystem مشترک برای برنامه‌ای که locking توزیع‌شده را نمی‌شناسد، می‌تواند ناسازگاری بسازد.

Lifecycle در Compose

توقف یا recreate container معمولاً volume نام‌دار را نگه می‌دارد، اما فرمان‌ها و گزینه‌های حذف volume رفتار متفاوت دارند. قبل از هر down یا پاک‌سازی، خروجی config و نام پروژه را بررسی کنید. نام واقعی volume ممکن است prefix پروژه داشته باشد. برای production به حافظه اپراتور تکیه نکنید؛ runbook مشخص با backup تازه و target صریح بنویسید.

چگونه مصرف واقعی Volume را پیدا کنیم؟

از تعریف Compose شروع کنید و سپس mountهای container در حال اجرا را به‌صورت read-only inspect کنید. مسیر داخل container، نام واقعی volume، mode خواندن/نوشتن و سرویس‌های متصل را ثبت کنید. حجم ظاهری به‌تنهایی کافی نیست؛ تعداد inode، فایل حذف‌شده‌ای که process هنوز باز نگه داشته و نرخ رشد را هم بررسی کنید. اگر نام volume شبیه پروژه قدیمی است، قبل از حذف با containerهای متوقف‌شده و jobهای backup تطبیق دهید. وجود نداشتن container فعال ثابت نمی‌کند داده بی‌استفاده است.

مهاجرت Volume به Host دیگر

نسخه image و schema را ثبت، نوشتن را freeze و بکاپ سازگار بگیرید. در مقصد Volume تازه بسازید، مالکیت و فضای آزاد را کنترل و داده را Restore کنید؛ سپس stack آزمایشی را بدون اتصال به سرویس‌های بیرونی بالا بیاورید. بعد از health و صحت داده، DNS یا proxy را cutover کنید. کپی خام هم‌زمان با نوشتن، به‌خصوص برای دیتابیس، روش مهاجرت مطمئن نیست.

Volume Backup نیست

خرابی host، حذف اشتباه، باج‌افزار یا corruption می‌تواند خود volume را از بین ببرد. snapshot همان storage نیز در برابر همه failureها مستقل نیست. نسخه خارج host، retention، checksum و Restore Test لازم است. برای دیتابیس زنده، archive خام فایل‌ها ممکن است crash-consistent یا ناسازگار باشد؛ ابزار native دیتابیس یا توقف/فریز کنترل‌شده را استفاده کنید. راهنمای بکاپ Volumeهای Docker مسیر امن را توضیح می‌دهد.

قبل از mount کردن چه بپرسیم؟

  1. این داده state اصلی است یا cache قابل‌بازسازی؟
  2. چه process و UID باید بخواند یا بنویسد؟
  3. پس از حذف container چه باید بماند؟
  4. RPO/RTO و روش Restore چیست؟
  5. آیا چند host یا replica به داده نیاز دارند؟
  6. حجم و نرخ رشد چگونه مانیتور می‌شود؟
  7. در migration نسخه برنامه، schema داده چه تغییری می‌کند؟

اشتباه‌های رایج

  • ذخیره دیتابیس در writable layer
  • تصور اینکه volume به معنی backup است
  • mount کل filesystem host برای رفع یک نیاز کوچک
  • استفاده از permission عمومی
  • مشترک کردن volume میان برنامه‌های ناسازگار
  • نادیده‌گرفتن inode و فضای Disk
  • prune بدون فهرست owner و restore point

چه زمانی کمک تخصصی لازم است؟

اگر داده میان چند volume پخش شده یا انتقال host باید بدون از دست‌رفتن تراکنش انجام شود، ابتدا dependency داده و نقطه consistency را مشخص کنید. داکرایز اپلیکیشن می‌تواند storage، مجوز، lifecycle و مسیر انتقال را همراه برنامه طراحی کند.

پرسش‌های متداول

آیا حذف container، volume را حذف می‌کند؟

نه همیشه؛ به نوع volume و فرمان حذف بستگی دارد. رفتار دقیق را روی پروژه خود بررسی کنید.

Volume بهتر است یا bind mount؟

برای داده managed معمولاً volume مناسب‌تر است؛ برای ارتباط صریح با فایل host، bind mount. نیاز عملی معیار است.

آیا دو container می‌توانند یک volume را mount کنند؟

از نظر فنی ممکن است، ولی ایمنی نوشتن هم‌زمان به برنامه و filesystem بستگی دارد.

آیا Named Volume روی host دیگر قابل‌دسترسی است؟

Volume محلی معمولاً نه؛ driver یا فرایند مهاجرت/بازیابی جدا لازم است.

مدیریت Secretها در Docker؛ از Build تا Runtime، Rotation و جلوگیری از افشا
Secretهای Docker را از کد و image جدا کنید، در BuildKit موقت mount کنید، در Compose فقط به سرویس لازم بدهید و rotation، audit و پاسخ به افشا داشته باشید.