المستودعات
المستودع هو صورة قرص مشفرة بـ LUKS على خادم بعيد. عند تحميلها، توفر:
- نظام ملفات معزول لبيانات تطبيقك
- عفريت Docker مخصص (منفصل عن Docker على المضيف)
- عناوين IP loopback فريدة لكل خدمة ضمن شبكة /26
إنشاء مستودع
rdc repo create --name my-app -m server-1 --size 10G
| الخيار | مطلوب | الوصف |
|---|---|---|
-m, --machine <name> | نعم | الجهاز المستهدف حيث سيتم إنشاء المستودع |
--size <size> | نعم | حجم صورة القرص المشفر (مثلاً 5G، 10G، 50G) |
--skip-router-restart | لا | تخطي إعادة تشغيل خادم المسارات بعد العملية |
سيعرض الناتج ثلاث قيم يتم إنشاؤها تلقائياً:
- معرف المستودع (GUID) - معرّف UUID يحدد صورة القرص المشفر على الخادم.
- بيانات الاعتماد - عبارة مرور عشوائية تُستخدم لتشفير وفك تشفير حجم LUKS.
- معرف الشبكة - عدد صحيح (يبدأ من 2816، يزيد بمقدار 64) يحدد نطاق IP للخدمات في هذا المستودع.
احفظ بيانات الاعتماد بأمان. هي مفتاح التشفير لمستودعك. إذا فقدتها، لا يمكن استرجاع البيانات. يتم حفظ بيانات الاعتماد في
config.jsonالمحلي لكن لا يتم حفظها على الخادم.
التحميل والإلغاء
التحميل يفك التشفير ويجعل نظام ملفات المستودع متاحاً. الإلغاء يغلق الحجم المشفر.
rdc repo mount --name my-app -m server-1 # فك التشفير والتحميل
rdc repo unmount --name my-app -m server-1 # الإلغاء وإعادة التشفير
| الخيار | الوصف |
|---|---|
--checkpoint | إنشاء نقطة تحقق CRIU قبل التحميل/الإلغاء (للحاويات مع تسمية rediacc.checkpoint=true) |
--skip-router-restart | تخطي إعادة تشغيل خادم المسارات بعد العملية |
التحقق من الحالة
rdc repo status --name my-app -m server-1
سرد المستودعات
rdc repo list -m server-1
عمود النوع ومرآة الحالة
يتضمن جدول الناتج عمود Type بثلاث قيم:
grand. مستودع من المستوى الأعلى مسجل في إعدادات CLI المحلية بدون والد. حالة القاعدة.fork. نسخة copy-on-write من مستودع آخر. يتم تحديده إما عبرgrandGuidفي الإعدادات المحلية أو عبر مرآة renet.interim/stateعلى الجهاز. أي مصدر هو المرجع الموثوق به؛ يجب أن يتفقا بمجرد ملء المرآة.unknown. لا يمكن لأي إشارة تصنيف المستودع. غالباً ما يكون fork وراثي قديم (تم إنشاؤه قبل شحن رمز المرآة ولم يتم إعادة تحميله منذ ذلك الحين)، أوgrandقديم تم حذف إدخاله من الإعدادات المحلية بطريق الخطأ. CLI يرفض التخمين؛ يجب على العامل تشغيل ملء المرآة أو إزالة الدليل إذا كان يتيماً حقاً.
مرآة .interim/state/<guid>/.rediacc.json هي ملف sidecar صغير يُكتب خارج الحجم المشفر بـ LUKS بحيث يمكن لأدوات النسخ الاحتياطي وrepo list قراءة نسب fork دون فتح كل صورة. تحمل نفس شكل .rediacc.json داخل الحجم (is_fork، grand_guid، name، وغيرها) وتُحدث على كل Repository.SaveState. أي كل تحميل وكل طفرة حالة. إنها مصدر الحقيقة لكشف fork في النسخ الاحتياطية المجدولة: fork غير محمل مع مرآة تقول is_fork: true يتم تخطيه بشكل صحيح من عمليات التحميل cold وhot.
للتنظيف الروتيني للإدخالات المجهولة، انظر rdc machine prune --prune-unknown.
تغيير الحجم
اضبط المستودع على حجم دقيق أو وسّع بمقدار معين:
rdc repo resize --name my-app -m server-1 --size 20G # اضبط على حجم دقيق
rdc repo expand --name my-app -m server-1 --size 5G # أضف 5G للحجم الحالي
يجب أن يكون المستودع غير محمل قبل تغيير الحجم.
repo expandيعمل دون توقف. يؤدي تغيير الحجم إلى تعديل الحجم الأقصى للمستودع؛ لإعادة الكتل المحررة إلى التجمع دون تغيير الحد الأقصى، استخدمrepo trimبدلاً من ذلك.
استرداد المساحة (trim)
حذف الملفات داخل مستودع يحرر مساحة لذلك المستودع، وrepo trim يُعيد تلك الكتل المحررة إلى تجمع مخزن البيانات المشترك. يعمل دون توقف ودون أي تأثير على الخدمات:
rdc repo trim -m server-1 # Trim every mounted repository plus the datastore
rdc repo trim -m server-1 --name my-app # Trim one repository
rdc repo trim -m server-1 --report-only # Show reclaimable space without trimming
rdc repo trim -m server-1 --docker # Also clear stopped containers, dangling images, and build cache first
آلية العمل: صور المستودعات ملفات متفرقة (sparse files)، والحجم المشفر يُمرّر طلبات discard. يُخبر trim نظام الملفات داخل المستودع بتحرير كل كتلة غير مستخدمة، مما يثقب ثغرات في الصورة الخلفية ويُقلّص استخدام التجمع فوراً.
ملاحظات:
- يُتخطى trim لنظام الملفات ويُبلَّغ عنه للمستودعات تحت نسخة احتياطية نشطة، لأن لقطة النسخ الاحتياطي لا تزال تُشير إلى الكتل فثقب فجوات فيها لن يحرر مساحة في التجمع. أما استرداد
--dockerفلا يتأثر ويستمر في العمل (انظر أدناه). - تشغيل trim مرتين متتاليتين يُبلّغ بـ 0 بايت في المرة الثانية. نظام الملفات يتذكر مجموعات الكتل التي جرى تنظيفها مسبقاً؛ هذا متوقع وليس عطلاً.
--dockerلا يحذف الصور الموسومة قط، بل فقط الصور المعلقة والحاويات الموقوفة وذاكرة cache للبناء. أضف--docker-volumesلإزالة الأحجام غير المستخدمة أيضاً (هذا يحذف البيانات؛ CLI فقط). وعلى عكس trim لنظام الملفات، يعمل استرداد--dockerحتى أثناء سير نسخة احتياطية، فيمكنك تنظيف ذاكرة cache البناء العالقة دون انتظار انتهاء نافذة النسخ الاحتياطي.
سياسة الحجم التلقائية
بدلاً من تغيير الحجم يدوياً، دع الجهاز يدير أحجام المستودعات. تُفعّل السياسة التوسع التلقائي أثناء التشغيل (يزداد الحجم الأقصى للمستودع عند امتلائه) وعمليات trim المجدولة. يُطبّق الجهاز السياسات كل بضع دقائق عبر مؤقت systemd الخاص بـ rediacc-storage-maintain.
# Machine-wide default: trim every repository daily
rdc repo policy set -m server-1 --auto-trim true
# Per-repository: grow my-app automatically, up to a hard ceiling
rdc repo policy set -m server-1 --name my-app --auto-grow true --max-quota 50G
# Inspect the stored and effective policy
rdc repo policy get -m server-1 --name my-app
حقول السياسة:
| الحقل | المعنى | القيمة الافتراضية |
|---|---|---|
--auto-grow | توسيع المستودع أثناء التشغيل عندما يتجاوز نظام ملفاته الحد | معطّل |
--max-quota | الحد الأقصى لـ auto-grow. مطلوب: تعيينه هو موافقتك الصريحة على over-provision التجمع | بدون |
--grow-threshold | نسبة استخدام نظام الملفات التي تُشغّل التوسع | 85 |
--grow-step | مقدار الإضافة عند كل توسع: مطلق (10G) أو نسبة مئوية من الحجم الحالي (20%) | 20% |
--auto-trim | تشغيل عمليات trim مجدولة | معطّل |
--trim-interval | الحد الأدنى للساعات بين عمليات trim التلقائية | 24 |
ضمانات: يرفض auto-grow عندما تكون المساحة الحرة في التجمع أقل من احتياطي (10 جيجابايت أو 5% من التجمع، أيهما أكبر)، وينتظر 30 دقيقة على الأقل بين كل توسعتين للمستودع ذاته، ولا يتجاوز --max-quota أبداً. لا يوجد تقليص تلقائي: تقليل الحجم الأقصى للمستودع يبقى عملية يدوية وغير متصلة عبر repo resize.
إعدادات المستودع الفردي تتجاوز الإعداد الافتراضي على مستوى الجهاز. استدعاءات policy set المتكررة تُغيّر فقط الرايات التي تمررها.
نسخ (Fork)
إنشاء نسخة من مستودع موجود في حالته الحالية:
rdc repo fork --parent my-app --tag staging -m server-1
النسخ تستخدم نموذج name:tag: النسخة الناتجة تُسمى my-app:staging. ينشئ نسخة مشفرة جديدة بـ GUID ومعرف شبكة خاص بها، مع مشاركة اسم الوالد. تشارك النسخة نفس بيانات اعتماد LUKS مع الوالد.
تشارك النسخ بيانات الوالد عبر BTRFS reflink، بما فيها أي بيانات اعتماد مخزنة على القرص. انظر ما لا يعزله Rediacc لمعرفة الآثار عند تفويض تلك البيانات الاعتماد لخدمات خارجية مثل Stripe أو AWS أو Railway. للحفاظ على بيانات اعتماد وقت النشر بعيداً عن متناول النسخ، استخدم أسرار لكل مستودع بدلاً من وضع القيم في ملفات
.envداخل المستودع.
عند إنشاء نسخة، يكتب repo fork sidecar مرآة الحالة في <datastore>/.interim/state/<fork-guid>/.rediacc.json فوراً. بدون فتح الحجم. لذا يتم تحديد النسخة الجديدة بشكل صحيح كـ is_fork: true من لحظة الإنشاء. هذا يسمح بتخطي النسخ في النسخ الاحتياطية المجدولة (يتم استبعاد النسخ من خط أنابيب التحميل بشكل افتراضي) حتى لو لم يتم تحميلها مطلقاً. عند نسخ نسخة، يتسلسل grand_guid بشكل صحيح: مرآة النسخة الجديدة تشير إلى معرف GUID الوالد الأصلي، وليس النسخة الوسيطة.
النسخ والتشغيل في خطوة واحدة
تقوم --up بإنشاء النسخة وتحميلها وتشغيل خدماتها في عملية بعيدة واحدة متواصلة. أضف --detach لاستعادة الطرفية فور انطلاق الحاويات؛ تكمل فحوصات الجاهزية في الخلفية، ويواصل الوكيل إعادة المحاولة حتى ترتبط كل خدمة بمنفذها:
rdc repo fork --parent my-app --tag staging -m server-1 --up
rdc repo fork --parent my-app --tag scratch -m server-1 --up --detach
في اختباراتنا، تولّت النسخة من مستودع حجمه 128 غيغابايت ووصلت إلى خدمات جاهزة في نحو 57 ثانية، وفي نحو 31 ثانية مع --detach. تطبع العمليات المنفصلة تلميحاً لمتابعة التقدم: rdc machine query --containers --name <machine>.
أين يذهب الوقت
تُختتم العمليات الأطول من بضع ثوانٍ بملخص توقيتات: تفصيل لكل خطوة، ومخطط شلال يُظهر ما جرى بالتوازي، وسطر إسناد يفصل بين خط أنابيب Rediacc وبدء تشغيل خدماتك:
Rediacc pipeline 19.2s (61%) · service startup 12.3s (39%)
بدء تشغيل الخدمات هو وقت إقلاع حاوياتك: الصور والتهيئة وفحوصات الجاهزية كما يعرّفها Rediaccfile الخاص بالمستودع، ويتفاوت من تطبيق لآخر. تُعرض المخططات على الطرفيات التفاعلية؛ عيّن RDC_TIMING_CHART=1 لفرض عرضها في المخرجات الموجّهة.
التحكم في الإصدارات على غرار Git
يمكن للتفريعات أن تعمل كإيداعات git. يُجمِّد rdc repo commit تفريعاً عاملاً في إيداع ثابت وغير قابل للتغيير؛ يُسمي rdc repo branch خطاً من التاريخ؛ يستنسخ rdc repo checkout إيداعاً بنسخة reflink إلى تفريع عمل قابل للكتابة؛ يمشي rdc repo log عبر سلسلة الآباء؛ ويدمج rdc repo merge خطَّين دون التعديل على مستودع حي في مكانه. ينتج rdc repo fork --immutable قاعدة معادلة للإيداع في خطوة واحدة.
rdc repo commit --name my-app:work --message "schema migration applied" -m server-1
rdc repo branch --branch staging --name my-app:work
rdc repo checkout --ref staging --from my-app:work --tag staging-copy -m server-1
راجع مرجع التحكم في الإصدارات على غرار Git للمجموعة الكاملة من الأوامر والخيارات والأمثلة التفصيلية.
الأسرار
أسرار لكل مستودع هي بيانات اعتماد وقت النشر يتم حقنها في الحاويات دون كتابتها إلى صورة المستودع المشفرة. يتم الاحتفاظ بها على طائفة منفصلة عن بيانات المستودع، لذا لا تنتشر من rdc repo fork. تبدأ النسخة بخريطة أسرار فارغة وتبدأ حاوياتها بتحديد نفسها كمبدأ خارجي مختلف عن الوالد.
هل تريد شرح خطوة بخطوة؟ راجع البرنامج التعليمي لإدارة الأسرار لدورة set/list/deploy/verify/rotate الكاملة.
نموذج الكتابة فقط (بنمط GitHub): get يعيد فقط ملخص SHA-256. قيمة النص العادي لا تُرجع مطلقاً لأحد، آدمي أو عامل. إذا نسيت ما هي القيمة، ابحث عنها في مدير كلمات المرور الخاص بك وأدر؛ لا يمكنك قراءتها من Rediacc بالتصميم. هذا يزيل فئة كاملة من التسرب: تسجيلات المحطة الطرفية، سجل shell، إعادة التوجيه العرضية، الكتف المراقب.
نمطي توصيل:
env. يتم تصدير السر كـREDIACC_SECRET_<KEY>في shell renet على الجهاز المستهدف. ارجع إليه منdocker-compose.ymlالخاص بك عبر استيفاء${REDIACC_SECRET_<KEY>}. مرئي داخل بيئة الحاوية، لذا استخدم هذا لقيم على شكل سلسلة اتصال يتوقع التطبيق أن تكون موجودة بالفعل في env.file. يتم كتابة السر إلى/var/run/rediacc/secrets/<networkID>/<KEY>على المضيف (tmpfs، لا يتم الاستمرار). ارجع إليه من ملف التكوين الخاص بك عبر إعلانsecrets:من المستوى الأعلى مع مصدرfile:، بالإضافة إلى قائمةsecrets:لكل خدمة. قراءة الحاويات من/run/secrets/<key>. فضّل هذا النمط لأي شيء حساس. لن يظهر فيdocker inspectأو/proc/<pid>/environ.
# تعيين، قائمة، الحصول (ملخص فقط)، إلغاء التعيين
rdc repo secret set --name my-app --key STRIPE_LIVE_KEY --value sk_live_xxx --mode file --current ""
rdc repo secret set --name my-app --key DB_HOST --value postgres.internal --mode env --current ""
rdc repo secret list --name my-app
rdc repo secret get --name my-app --key DB_HOST # → { key, mode, digest } — no value
rdc repo secret unset --name my-app --key STRIPE_LIVE_KEY --current sk_live_xxx
بوابة الطفرة المتماثلة. كل من البشر والعاملين يحتاجون إلى --current <previous-value> لاستبدال أو إلغاء تعيين سر (شرط مسبق بنمط passwd). للكتابة الأولى لمفتاح جديد، مرّر --current "" (فارغ). للدوران دون التحقق من القيمة السابقة، مرّر --rotate-secret بدلاً من ذلك. يتم تدقيق هذا بشكل واضح كدوران. --current و--rotate-secret متنافيان.
مرّر --value - لقراءة من stdin بدلاً من argv (تجنب كشف سجل shell للكتابات الفردية).
في docker-compose.yml الخاص بك:
services:
api:
image: myapp
environment:
DATABASE_HOST: ${REDIACC_SECRET_DB_HOST}
secrets:
- stripe_live_key
secrets:
stripe_live_key:
file: /var/run/rediacc/secrets/${REDIACC_NETWORK_ID}/STRIPE_LIVE_KEY
مرجع الخدمة من جانب الأحرف الصغيرة (stripe_live_key) هو اسم ملف /run/secrets/<name> داخل الحاوية؛ الذيل العلوي لمسار المضيف (STRIPE_LIVE_KEY) يطابق ما قمت بتعيينه مع --key. ${REDIACC_NETWORK_ID} يتم استيفاء بواسطة renet compose تلقائياً.
عزل متقاطع مفروض: مدقق compose في renet يرفض مسارات
secrets: file:(وconfigs: file:، وenv_file:) التي تشير إلى معرف شبكة مستودع آخر. الرمز الحرفي${REDIACC_NETWORK_ID}(أو عدد صحيح الشبكة الخاص بك) هو النموذج الوحيد المقبول لمراجع/var/run/rediacc/secrets/.... و--unsafeلا يلغي هذا الفحص. صندوق Landlock حول عملية فرعية bash في Rediaccfile ينطاق الوصول إلى نظام الملفات لدليل أسرار شبكتك فقط، لذا محاولةcat /var/run/rediacc/secrets/<other>/Xمن Rediaccfile خبيثة تفشل مع EACCES على مستوى kernel.
النسخ:
rdc repo forkيقوم بعدم نسخ الأسرار. لاستخدام الأسرار في نسخة، شغّلrdc repo secret set --name <fork>على النسخ بوضوح. هذه هي خاصية الأمان الحملة. لا يجب أن تكون حاويات النسخة قادرة على التصرف كمبدأ الإنتاج ضد الخدمات الخارجية.
العاملين (Claude Code، Cursor، إلخ):
repo secret listوrepo secret getيتم كشفهم كأدوات MCP (آمنة للقراءة. الأسماء والملخصات فقط، أبداً القيم).setوunsetهي CLI فقط لأن احتفالية--current/--rotate-secretتتطلب مراقبة العينين على البشر؛ العاملين الذين يستدعونهم عبر shell يحصلون على نفس البوابة مثل البشر. عند فشل الشرط المسبق، يحتوي الغلاف JSON على حقلerrors[].next.options[].runمنظم. يجب على العاملين تمرير هذه الأوامر حرفياً للمستخدم. انظر أمان العاملين في الذكاء الاصطناعي للنموذج الكامل.
التحقق من الصحة
التحقق من سلامة نظام الملفات في مستودع:
rdc repo validate --name my-app -m server-1
الملكية
قم بتعيين ملكية الملف ضمن مستودع للمستخدم العام (UID 7111). يكون هذا ضرورياً عادةً بعد تحميل الملفات من محطة عملك، والتي تصل مع UID المحلي الخاص بك.
rdc repo ownership --name my-app -m server-1
يكشف الأمر تلقائياً عن أدلة بيانات حاوية Docker (bind mounts قابلة للكتابة) ويستبعدها. هذا يمنع كسر الحاويات التي تدير الملفات بـ UIDs الخاصة بها (مثلاً MariaDB=999، www-data=33).
| الخيار | الوصف |
|---|---|
--uid <uid> | قم بتعيين UID مخصص بدلاً من 7111 |
--skip-router-restart | تخطي إعادة تشغيل خادم المسارات بعد العملية |
لفرض الملكية على جميع الملفات، بما فيها بيانات الحاوية:
rdc repo ownership --name my-app -m server-1
انظر دليل الترحيل للحصول على شرح شامل لمتى وكيفية استخدام الملكية أثناء ترحيل المشروع.
النموذج
تطبيق نموذج لتهيئة مستودع بملفات:
rdc repo template apply --name my-template -m server-1 -r my-app --file ./my-template.tar.gz
حذف
حذف نهائي لمستودع وجميع البيانات بداخله:
rdc repo delete --name my-app -m server-1
هذا يدمر نهائياً صورة القرص المشفر. لا يمكن التراجع عن هذا الإجراء.
ترحيل المستودع
ترحيل مستودع مباشر من جهاز إلى آخر مع الحد الأدنى من وقت التوقف.
rdc repo migrate --name my-app --from server-1 --to server-2
| الخيار | الوصف |
|---|---|
--provision | توفير المستودع على الجهاز المستهدف قبل الترحيل (ينشئ صورة LUKS ويسجل الإعدادات) |
--checkpoint | إنشاء نقطة تحقق CRIU من الحاويات قيد التشغيل قبل القطع |
--bwlimit <kbps> | تحديد عرض نطاق rsync بالكيلوبايت في الثانية |
--skip-dns | تخطي تحديث سجلات DNS بعد القطع |
تدفق ثلاث مراحل:
- نسخ ساخن مسبق - rsync ينقل البيانات بينما يبقى المستودع قيد التشغيل على المصدر. يتم نقل الملفات الكبيرة قبل أي وقت توقف.
- القطع - يتم إيقاف المستودع على المصدر، تمرير rsync نهائي يزامن التغييرات المتبقية، ويبدأ المستودع على الهدف.
- البدء على الهدف - renet يحمل وينطلق المستودع على جهاز الهدف. يتم تحديث DNS ما لم يتم تمرير
--skip-dns.
Push مقابل ترحيل:
repo push | repo migrate | |
|---|---|---|
| العملية | نسخ | نقل |
| المصدر بعد ذلك | دون تغيير | موقوف |
| وقت التوقف | لا أحد (نسخ فقط) | نافذة قطع مختصرة |
| تحديث DNS | لا | نعم (ما لم يتم تمرير --skip-dns) |
| حالة الاستخدام | النسخة الاحتياطية، استنساخ التسريع | استبدال الجهاز، نقل الخادم |
التقليص
بعد حذف المستودعات أو الاسترجاع من عمليات فاشلة، قد تبقى أدلة تحميل يتيمة وملفات الأقفال والعلامات الثابتة. يزيل التقليص هذه بأمان:
# معاينة ما سيتم حذفه
rdc machine prune --name server-1 --dry-run
# إزالة الموارد اليتيمة
rdc machine prune --name server-1
تتأثر فقط الموارد التي لا توجد صورة مستودع متطابقة لها. أدلة التحميل غير الفارغة لم تُزل أبداً.