المستوى: مبتدئ. هذا الشرح مكتوب لحد بيبدأ مع Docker، ومبني على فرضية إنك بتشغّل الحاوية على سيرفر Linux واحد (مش Kubernetes ولا cluster).
لو شغّلت قاعدة بيانات زي PostgreSQL في Docker، سجّلت مستخدمين، وبعد docker restart لقيت القاعدة رجعت فاضية — ده مش باج، وده مش عطل في PostgreSQL. ده سلوك Docker الطبيعي، والحل سطر واحد. هتكسب من المقال ده إنك تخلّي بياناتك تعيش أطول من الحاوية نفسها.
تخزين بيانات Docker الدائم عبر الـ Volumes
المشكلة باختصار
أي بيانات بتكتبها الحاوية جوّه نظام ملفاتها الخاص بتعيش وتموت مع الحاوية. أول ما الحاوية تتشال أو تتبني من جديد، الكتابة دي بتروح. الـ docker restart لوحده مش بيمسح، لكن أي docker rm ثم docker run — وده اللي بيحصل مع كل تحديث صورة أو تغيير إعداد — بيبدأ بطبقة كتابة نضيفة فاضية.
الحاوية زي غرفة فندق
تخيّل إنك نازل فندق. دخلت الغرفة، رصصت هدومك في الدولاب، وكتبت ملاحظات على السبورة اللي في الغرفة. ده مريح ليك طول ما انت ساكن. لكن ساعة ما تعمل تسجيل خروج (checkout)، شغّالة النظافة بتفضّي الدولاب وتمسح السبورة، وتجهّز الغرفة نضيفة للنزيل اللي بعدك.
الحاوية بالظبط كده. طبقة الكتابة بتاعتها زي السبورة في الغرفة: بتكتب فيها وانت شغّال، بس بمجرد ما الحاوية تتشال، الطبقة دي بتتمسح وتتعمل واحدة فاضية للحاوية الجديدة. عشان بياناتك ما تروحش، محتاج تحطها في «خزنة» خارج الغرفة — والخزنة دي اسمها Volume.
التفسير العلمي: طبقة الكتابة والـ Copy-on-Write
صورة Docker (الـ image) مكوّنة من طبقات (layers) للقراءة فقط. لما تشغّل حاوية، Docker بيضيف فوقها طبقة واحدة قابلة للكتابة اسمها الـ writable layer، وبيربط الطبقات كلها بنظام ملفات موحّد اسمه OverlayFS (الـ storage driver الافتراضي overlay2).
الفكرة اسمها Copy-on-Write: أي ملف موجود في طبقات الصورة بيتقرأ من مكانه مباشرة، لكن أول ما تعدّله، Docker بينسخه للطبقة القابلة للكتابة الأول وبعدين يعدّل النسخة. يعني كل كتابة بتحصل في طبقة الحاوية المؤقتة. وعشان الطبقة دي مربوطة بعمر الحاوية، لما الحاوية تتشال بتروح معاها.
الـ Volume بيكسر الحلقة دي. هو مساحة تخزين على قرص المضيف (host) بيديرها Docker، وبتتوصّل لمسار جوّه الحاوية. أي كتابة على المسار ده بتعدّي طبقة الحاوية بالكامل وبتروح على القرص مباشرة، فبتفضل موجودة بعد ما الحاوية تختفي.
الحل: خطوتين وأنت بتكسب
- اعمل named volume باسم واضح.
- اربطه بمسار البيانات جوّه الحاوية بـ
-v.
مثال كامل على PostgreSQL، بيانات القاعدة بتتخزّن في /var/lib/postgresql/data: