التطبيق · فصل ٤

الداتا اللي متموتش — Volumes و Bind mounts

volume mount · bind mount · --mount vs -v · Postgres data
🎯 الهدف: تحفظ داتا الـ database بره الـ container، وتعرف إمتى volume وإمتى bind mount.

المشكلة

مسحت الـ container؟ كل اللي اتكتب جوّاه راح. طب لو الـ container ده Postgres؟ يبقى لازم ملفات الداتا تعيش بره الـ container، والـ container بس يشاور عليها. ده اسمه mount، وفي منه نوعين أساسيين:

📦 Volume mount

Docker هو اللي بيدير المكان. بيتخزّن جوه مساحة Docker نفسه (على Linux تحت /var/lib/docker/volumes، وعلى Desktop جوه الـ VM). إنت تتعامل معاه باسمه بس.

📂 Bind mount

إنت اللي بتحدد فولدر على جهازك بالمسار، والـ container يشوفه زي ما هو. أي تعديل من ناحية يبان في الناحية التانية فورًا.

🧪 Lab: volume

terminal
# أنشئ volume باسمdocker volume create my-volume# شغّل container واربط الـ volume على /my-data جوّاهdocker run -it --rm --mount source=my-volume,destination=/my-data ubuntu:22.04# نفس الكلام بالصيغة القصيرة:# docker run -it --rm -v my-volume:/my-data ubuntu:22.04# جوه الـ container:echo "Hello from the container!" > /my-data/hello.txtexit

الـ container اتمسح بسبب --rm. شغّل واحد جديد بنفس الـ volume واعمل cat /my-data/hello.txt: الملف لسه موجود.

🧪 Lab: bind mount

PWD معناها present working directory، يعني الفولدر اللي إنت فاتح منه الـ terminal.

terminal
mkdir -p my-datadocker run -it --rm --mount type=bind,source="${PWD}"/my-data,destination=/my-data ubuntu:22.04# أو: docker run -it --rm -v "${PWD}"/my-data:/my-data ubuntu:22.04# جوه الـ container:echo "Hello from the container!" > /my-data/hello.txtexit# على جهازك:cat my-data/hello.txt

التطبيق الحقيقي: Postgres

كل database بتخزّن الداتا في مسار معين جوه الـ container، وده اللي لازم تربطه:

الـ databaseمسار الداتا جوه الـ image الرسمية
Postgres (لحد 17)/var/lib/postgresql/data
MySQL/var/lib/mysql
MongoDB/data/db

بـ volume:

terminal
docker run --name my-postgres \  -e POSTGRES_PASSWORD=secret \  -v pgdata:/var/lib/postgresql/data \  -p 5432:5432 \  -d postgres:17

امسح الـ container واعمل واحد جديد بنفس السطر: الـ volume pgdata لسه موجود، فلما تفتح الداتابيز من DataGrip أو أي client هتلاقي الجداول والداتا زي ما هي.

بـ bind mount:

terminal
mkdir -p pgdata   # أنشئ الفولدر لو مش موجودdocker run --name my-postgres \  -e POSTGRES_PASSWORD=secret \  -v "${PWD}/pgdata":/var/lib/postgresql/data \  -p 5432:5432 \  -d postgres:17

إدارة الـ volumes

terminal
docker volume lsdocker volume inspect pgdatadocker volume rm pgdata      # ⚠️ الداتا هتروحdocker volume prune          # امسح كل volume مش مربوط بـ container

خلّصت الفصل لما

🧠 اختبر نفسك
١) مسحت container الـ Postgres. الداتا راحت؟
لأ، طالما كانت على volume أو bind mount. هتروح بس لو مسحت الـ volume نفسه.
٢) عايز تعدّل الكود من VS Code والـ container يشوف التعديل فورًا. أنهي نوع؟
bind mount.
٣) ليه المثال مثبّت على postgres:17 مش postgres بس؟
عشان الـ latest ممكن يتغير (زي ما 18 غيّر مسار الداتا)، والـ tag الثابت بيخلّي السلوك متوقع.