# OmniRoute Fly.io Deployment Guide (العربية) 🌐 **Languages:** 🇺🇸 [English](../../../../ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇹 [am](../../../am/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇦🇿 [az](../../../az/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../../da/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../../de/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇬🇷 [el](../../../el/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../../es/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇪 [et](../../../et/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../../he/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../../id/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../../it/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../../ja/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇭 [km](../../../km/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [kn](../../../kn/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇲 [my](../../../my/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../../no/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [or](../../../or/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../../ro/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../../ru/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇰 [si](../../../si/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [te](../../../te/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../../th/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) --- يصف هذا المستند عملية النشر الفعلية لـ OmniRoute على Fly.io، ويغطي السيناريوهات التالية: - نشر المشروع الحالي على Fly.io للمرة الأولى - نشر تحديثات الكود اللاحقة - المشاريع الجديدة التي تتبع سير عمل النشر نفسه يستند هذا الدليل إلى إعداد عامل تم التحقق منه للمشروع الحالي. اسم التطبيق هو `omniroute`. --- ## 1. أهداف النشر - المنصة: Fly.io - طريقة النشر: النشر المباشر محليًا باستخدام `flyctl` - بيئة التشغيل: استخدام ملفَي `Dockerfile` و`fly.toml` الموجودين في المستودع - استمرارية البيانات: تركيب Fly Volume على `/data` - رابط الوصول: `https://omniroute.fly.dev/` --- ## 2. الإعدادات الأساسية للمشروع الحالي تم التأكد من أن ملف `fly.toml` في المستودع الحالي يحتوي على العناصر الأساسية التالية: ```toml app = 'omniroute' primary_region = 'sin' [[mounts]] source = 'data' destination = '/data' [processes] app = 'node run-standalone.mjs' [http_service] internal_port = 20128 [env] TZ = "Asia/Shanghai" HOST = "0.0.0.0" HOSTNAME = "0.0.0.0" BIND = "0.0.0.0" ``` ملاحظات: - يحدد `app = 'omniroute'` تطبيق Fly الذي يستهدفه النشر - يحدد `destination = '/data'` دليل تركيب وحدة التخزين الدائمة - يجب أن يضبط هذا المشروع `DATA_DIR=/data`، وإلا فستُكتب قاعدة البيانات والمفاتيح في الدليل المؤقت للحاوية --- ## 3. المتطلبات الأساسية ### 3.1 تثبيت Fly CLI Windows PowerShell: ```powershell pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex" ``` إذا فشل برنامج التثبيت النصي في بيئتك، فيمكنك أيضًا تنزيل الملف الثنائي `flyctl` يدويًا وإضافته إلى `PATH`. ### 3.2 تسجيل الدخول إلى حساب Fly ```powershell flyctl auth login ``` ### 3.3 التحقق من حالة تسجيل الدخول ```powershell flyctl auth whoami flyctl version ``` --- ## 4. نشر المشروع الحالي للمرة الأولى ### 4.1 استنساخ الكود والدخول إلى الدليل ```powershell git clone https://github.com/diegosouzapw/OmniRoute.git cd OmniRoute ``` ### 4.2 تأكيد اسم التطبيق افتح `fly.toml` وتحقق من السطر التالي: ```toml app = 'omniroute' ``` إذا كنت تنشر إلى تطبيق جديد خاص بك، فيمكنك تغييره إلى اسم فريد عالميًا، على سبيل المثال: ```toml app = 'omniroute-yourname' ``` ملاحظة: - تأكد من أن التطبيق الذي تراه في لوحة التحكم يطابق قيمة `app` في `fly.toml` - إذا كنت قد استخدمت سابقًا اسمًا مختلفًا، مثل `oroute`، فلا تخلط بينه وبين `omniroute` ### 4.3 إنشاء التطبيق إذا لم يكن التطبيق موجودًا بعد: ```powershell flyctl apps create omniroute ``` إذا غيّرت اسم التطبيق، فاستبدل `omniroute` بالاسم الذي اخترته. ### 4.4 النشر الأول ```powershell flyctl deploy ``` --- ## 5. المعلمات المطلوبة يوصي هذا المشروع بإعداد المعلمات التالية على الأقل في Fly.io. ### 5.1 المعلمات التي تم التحقق منها استُخدمت هذه المعلمات في عمليات نشر فعلية على تطبيق `omniroute` الحالي: - `API_KEY_SECRET` - `DATA_DIR` - `JWT_SECRET` - `MACHINE_ID_SALT` - `NEXT_PUBLIC_BASE_URL` - `OMNIROUTE_WS_BRIDGE_SECRET` (مطلوب في بيئة الإنتاج — يُستخدم لمصادقة جسر WebSocket) - `STORAGE_ENCRYPTION_KEY` ### 5.2 حول `INITIAL_PASSWORD` لا يضبط المشروع الحالي `INITIAL_PASSWORD` لأن عملية النشر هذه لا تتطلبه. إذا لم يتم ضبطه: - سيشير سجل بدء التشغيل إلى أن كلمة المرور الافتراضية هي `CHANGEME` - ينبغي عليك تغيير كلمة مرور تسجيل الدخول في إعدادات النظام في أقرب وقت ممكن بعد النشر إذا أردت تهيئة كلمة مرور الواجهة الخلفية دون تدخل يدوي، فيمكنك إضافتها لاحقًا: - `INITIAL_PASSWORD` --- ## 6. المعلمات الموصى بها ### 6.1 إعداد الأسرار يوصى باستخدام المتغيرات التالية في Fly Secrets: | المتغير | التوصية | الوصف | | ------------------------------ | --------------------- | --------------------------------------------------------- | | `API_KEY_SECRET` | مطلوب | يُستخدم لإنشاء مفتاح API والتحقق منه | | `JWT_SECRET` | مطلوب | يُستخدم لجلسات تسجيل الدخول وتوقيع JWT | | `OMNIROUTE_WS_BRIDGE_SECRET` | مطلوب في بيئة الإنتاج | سر مصادقة جسر WebSocket | | `STORAGE_ENCRYPTION_KEY` | موصى به بشدة | يشفّر معلومات الاتصال الحساسة عند تخزينها | | `MACHINE_ID_SALT` | موصى به | ينشئ معرّفًا ثابتًا للجهاز | | `INITIAL_PASSWORD` | اختياري | يعيّن كلمة مرور الواجهة الخلفية الأولية عند أول عملية نشر | | بيانات اعتماد OAuth/API الخاصة | حسب الحاجة | إعداد مصادقة المنصة الخارجية | ### 6.2 القيم الموصى بها للمشروع الحالي | المتغير | القيمة الموصى بها | | ---------------------- | --------------------------- | | `DATA_DIR` | `/data` | | `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` | ملاحظات: - يُعد `DATA_DIR=/data` ضروريًا ويجب أن يتطابق مع نقطة تحميل Fly Volume - يُستخدم `NEXT_PUBLIC_BASE_URL` بواسطة المجدول، واستدعاءات الواجهة الأمامية، والسيناريوهات المشابهة ### 6.3 إعداد عنوان URL لاستدعاء OAuth إذا كنت بحاجة إلى تمكين موفري الخدمات المعتمدين على OAuth (مثل Antigravity وGemini وCursor) في عملية النشر على Fly.io، فتأكد من النقطتين التاليتين: 1. **عيّن `NEXT_PUBLIC_BASE_URL` إلى نطاق HTTPS العام الخاص بك** ```powershell flyctl secrets set NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev -a omniroute ``` إذا كنت تستخدم نطاقًا مخصصًا، فاستبدله بالنطاق المقابل (مثل `https://omniroute.yourdomain.com`). 2. **اضبط عنوان URL للاستدعاء في وحدة تحكم موفر الخدمة** تشترك جميع موفري OAuth في مسار الاستدعاء الوحيد `/callback` — ولا يوجد مسار استدعاء منفصل لكل موفر: ```text /callback ``` على سبيل المثال، سواء كان الموفر Gemini أو Antigravity أو Cursor أو GitLab Duo: - `https://omniroute.fly.dev/callback` إذا لم يتطابق `NEXT_PUBLIC_BASE_URL` مع عنوان URL للاستدعاء المسجّل لدى موفر الخدمة، فستفشل عملية OAuth عند خطوة إعادة التوجيه في المتصفح. --- ## 7. إعداد الأسرار بأمر واحد تنشئ الأوامر التالية قيمًا عشوائية آمنة، وتكتب جميع المعلمات المطلوبة للمشروع الحالي إلى Fly Secrets في خطوة واحدة. ملاحظات: - لا يتضمن `INITIAL_PASSWORD` - مخصص للمشروع الحالي `omniroute` ```powershell $apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $wsBridgeSecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() flyctl secrets set ` API_KEY_SECRET=$apiKeySecret ` JWT_SECRET=$jwtSecret ` MACHINE_ID_SALT=$machineIdSalt ` STORAGE_ENCRYPTION_KEY=$storageKey ` OMNIROUTE_WS_BRIDGE_SECRET=$wsBridgeSecret ` DATA_DIR=/data ` NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev ` -a omniroute ``` على Linux / macOS، يمكنك أيضًا استخدام `openssl rand -hex 32`: ```bash flyctl secrets set OMNIROUTE_WS_BRIDGE_SECRET=$(openssl rand -hex 32) -a omniroute ``` ملاحظات: - يُعد `OMNIROUTE_WS_BRIDGE_SECRET` مطلوبًا في بيئة الإنتاج؛ وسيؤدي عدم وجوده إلى تعطّل مصافحة جسر WebSocket إذا كنت تريد أيضًا تعيين كلمة مرور أولية: ```powershell flyctl secrets set INITIAL_PASSWORD=your-strong-password -a omniroute ``` --- ## 8. عرض المعلمات الحالية ```powershell flyctl secrets list -a omniroute ``` إذا كانت صفحة `Secrets` في وحدة التحكم لا تعرض المتغيرات المتوقعة، فتحقق مما يلي: - أنك تعرض تطبيق `omniroute` - أن قيمة `app` في `fly.toml` تطابق التطبيق الموجود في وحدة التحكم --- ## 9. التحديثات والإصدارات اللاحقة بعد تحديث الشيفرة، تكون عملية الإصدار مباشرة: ```powershell git pull flyctl deploy ``` إذا كنت تحتاج فقط إلى تحديث المعلمات دون تغيير الشيفرة: ```powershell flyctl secrets set KEY=value -a omniroute ``` ستُجري Fly تلقائيًا تحديثًا متدرجًا للأجهزة. ### 9.1 تتبّع تحديثات المستودع الأساسي مع الحفاظ على ملف `fly.toml` الخاص بتفرّعك إذا كان المستودع الحالي تفرّعًا وكنت تريد مزامنة التحديثات من المستودع الأساسي `https://github.com/diegosouzapw/OmniRoute`، فاتبع سير العمل أدناه. أولًا، تحقق من المستودعات البعيدة: ```powershell git remote -v ``` يجب أن ترى على الأقل: - `origin` يشير إلى تفرّعك الخاص - `upstream` يشير إلى المستودع الأصلي إذا لم يكن `upstream` مهيأً، فأضفه: ```powershell git remote add upstream https://github.com/diegosouzapw/OmniRoute.git ``` قبل المزامنة مع المستودع الأساسي، اجلب أحدث الالتزامات والعلامات: ```powershell git fetch upstream --tags ``` تحقق من الإصدار الحالي وعلامات المستودع الأساسي: ```powershell git describe --tags --always git show --no-patch --oneline v3.4.7 ``` > ملاحظة: إصدار المشروع الحالي هو `v3.8.0`. تم الإبقاء على الإشارات إلى `v3.4.7` أدناه كأمثلة تاريخية فقط. بالنسبة إلى الإصدارات الفعلية، استخدم `:latest` أو علامة الإصدار الحالي (مثل `:v3.8.0`). إذا كنت تريد دمج أحدث فرع `main` من المستودع الأساسي مع الاحتفاظ إجباريًا بملف `fly.toml` الخاص بتفرّعك، فاتبع سير العمل التالي: ```powershell git merge upstream/main git checkout HEAD~1 -- fly.toml git add -- fly.toml git commit -m "chore(deploy): keep fork fly.toml" git push origin main ``` ملاحظات: - يزامن `git merge upstream/main` أحدث شيفرة من المستودع الأصلي - يستعيد `git checkout HEAD~1 -- fly.toml` ملف `fly.toml` الخاص بتفرّعك كما كان قبل الدمج - إذا لم يعدّل المستودع الأساسي ملف `fly.toml`، فلن تُدخل هذه الخطوة أي اختلافات - إذا عدّل المستودع الأساسي ملف `fly.toml`، فتضمن هذه الخطوة عدم استبدال اسم تطبيق Fly، ونقطة تحميل وحدة التخزين، والمنطقة، وإعدادات النشر الأخرى الخاصة بتفرّعك إذا كنت تريد المطابقة مع علامة إصدار محددة (مثل `v3.4.7`)، فتحقق أولًا من أن العلامة مضمنة بالفعل في `upstream/main`: ```powershell git merge-base --is-ancestor v3.4.7 upstream/main ``` تعني النتيجة الناجحة أن `upstream/main` يحتوي بالفعل على ذلك الإصدار؛ ويمكنك ببساطة دمج `upstream/main`. ### 9.2 تسلسل الإصدار القياسي بعد المزامنة مع المستودع الأساسي بعد المزامنة مع المستودع الأصلي، اتبع ترتيب الإصدار الموصى به: 1. `git fetch upstream --tags` 2. `git merge upstream/main` 3. استعد ملف `fly.toml` الخاص بالتفرّع 4. `git push origin main` 5. `flyctl deploy` 6. `flyctl status -a omniroute` 7. `flyctl logs --no-tail -a omniroute` هذا هو سير العمل الفعلي المستخدم عند ترقية المشروع الحالي إلى `v3.4.7` (يشير المثال إلى إصدار تاريخي؛ أما الإصدار الفعلي الحالي فهو `v3.8.0`). --- ## 10. فحوصات ما بعد النشر ### 10.1 التحقق من حالة التطبيق ```powershell flyctl status -a omniroute ``` ### 10.2 عرض سجلات بدء التشغيل ```powershell flyctl logs --no-tail -a omniroute ``` ### 10.3 التحقق من إمكانية الوصول إلى الموقع ```powershell try { (Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode } catch { if ($_.Exception.Response) { $_.Exception.Response.StatusCode.value__ } else { throw } } ``` تشير القيمة المُعادة `200` إلى أن الموقع يستجيب بصورة طبيعية. --- ## 11. مؤشرات النجاح بعد نجاح النشر، يجب أن تعرض السجلات محتوى مشابهًا لما يلي: ```text [bootstrap] Secrets persisted to: /data/server.env [DB] SQLite database ready: /data/storage.sqlite ``` هاتان النقطتان بالغتا الأهمية: - يؤكد `/data/server.env` أن أسرار وقت التشغيل مكتوبة في وحدة التخزين الدائمة - يؤكد `/data/storage.sqlite` أن قاعدة البيانات مكتوبة في وحدة التخزين الدائمة إذا ظهر `/app/data/...` بدلًا من ذلك، فهذا يعني أن `DATA_DIR` مهيأ بصورة غير صحيحة ويجب تصحيحه فورًا. --- ## 12. المشكلات الشائعة ### 12.1 صفحة `Secrets` فارغة يوجد عادةً سببان لذلك: - لم تشغّل `flyctl secrets set` بعد - أنت تعرض تطبيقًا مختلفًا (مثل `oroute` بدلًا من `omniroute`) ### 12.2 يعرض `flyctl deploy` الخطأ `app not found` أنشئ التطبيق أولًا: ```powershell flyctl apps create omniroute ``` ### 12.3 فشل تحليل `fly.toml` تحقق مما يلي: - ما إذا كانت هناك أحرف مشوهة في التعليقات - ما إذا كانت علامات الاقتباس والمسافات البادئة في TOML صحيحة ### 12.4 البيانات لا تُحفَظ بشكل دائم تحقق من الأمرين التاليين: - يحتوي `fly.toml` على `destination = '/data'` - تم تعيين `DATA_DIR` إلى `/data` ### 12.5 هل يمكن تشغيله دون `INITIAL_PASSWORD`؟ نعم، يمكن تشغيله. سيعود إلى كلمة المرور الافتراضية `CHANGEME`. يُوصى بتغيير كلمة مرور الواجهة الخلفية في بيئة الإنتاج في أقرب وقت ممكن. --- ## 13. إعادة الاستخدام للمشروعات الجديدة إذا كنت تنشر مشروعًا جديدًا باتباع هذا المستند، فما عليك سوى تغيير العناصر التالية: 1. غيّر قيمة `app` في `fly.toml` 2. غيّر `NEXT_PUBLIC_BASE_URL` 3. أبقِ `DATA_DIR=/data` 4. أعد إنشاء `API_KEY_SECRET` و`JWT_SECRET` و`MACHINE_ID_SALT` و`STORAGE_ENCRYPTION_KEY` 5. بعد النشر الأول، تحقق من أن السجلات تُكتب إلى `/data` لا تُعِد استخدام مفاتيح من مشروع سابق. --- ## 14. قائمة التحقق الدنيا لإصدار المشروع الحالي الأوامر الأكثر استخدامًا للإصدارات اللاحقة هي: ```powershell flyctl auth whoami flyctl status -a omniroute flyctl secrets list -a omniroute flyctl deploy flyctl logs --no-tail -a omniroute ``` بالنسبة إلى الإصدار العادي، يكون الأمر الأساسي ببساطة: ```powershell flyctl deploy ``` بالنسبة إلى النشر لأول مرة في بيئة جديدة، تكون الخطوات الأساسية كما يلي: 1. `flyctl auth login` 2. `flyctl apps create omniroute` 3. `flyctl secrets set ... -a omniroute` 4. `flyctl deploy` 5. `flyctl logs --no-tail -a omniroute`