استضافة Rakazo ذاتياً على VPS: المتطلبات والطريقة
شغّل Rakazo على VPS مع Node 22 وpnpm وPostgres وGraphile Worker عبر Docker Compose، واختر sandbox المناسب وأدر المفاتيح واعرف الحجم المطلوب فعلياً.
ما الذي يشغّله استضافة Rakazo ذاتياً فعلياً
تعني استضافة Rakazo ذاتياً تشغيل خمسة مكونات على خادم Linux واحد: PostgreSQL، وعملية Graphile Worker، وواجهة API، وتطبيق الويب، وحاوية sandbox واحدة لكل bot نشط. Rakazo بديل مفتوح المصدر عن Grok Bot، نشره elie222 بموجب ترخيص Apache 2.0. يحصل كل bot على thread خاص به، وcomputer خاص به، وذاكرة خاصة به، وسجل خاص به، ويمكنه إنشاء bots نظيرة أو subagents قصيرة العمر.
لهذا السبب يجب تشغيله على VPS (خادم افتراضي خاص)، لا على جهاز مكتبي. يجب أن يبقى bot الذي يحتفظ بالذاكرة وينفّذ المهام المجدولة قابلاً للوصول أثناء نومك. عندما يدخل laptop في وضع السكون، يتوقف queue.
ما يزال Rakazo في مرحلة beta المبكرة حتى August 2026، لذلك تعامل معه باعتباره إعداداً عملياً لا appliance مكتملة. تعتمد الحزمة بالكامل على TypeScript: يستخدم تطبيق الويب React 19 وVite، وتستخدم API Hono، ويستخدم Postgres مع Prisma، وتستخدم الحسابات Better Auth، بينما يتولى Graphile Worker المهام الخلفية. يخزّن Graphile Worker queue داخل Postgres، لذلك لا تحتاج إلى تشغيل Redis أو مخزن بيانات ثانٍ. يضبط .env.example القيمة WAKEUP_DRIVER=graphile، ما يعني أن استيقاظ bot هو job مدعوم بواسطة Postgres. أوقف Postgres، وستتوقف معه كل إجراءات bot المجدولة. إذا كنت تفضّل تركيب agent من مكونات منفصلة بدلاً من تشغيل منتج أنشأه طرف آخر، فالمسار الآخر هو إنشاء agent خاص بك من مكونات منفصلة.
لماذا لن تتحمل خطة بسعة 1 GB هذا الحمل
احسب عدد العمليات. Postgres عملية واحدة. التطبيق البرمجي API هو عملية Node. العامل هو العملية الثانية. تطبيق الويب هو العملية الثالثة. مشرف sandbox هو العملية الرابعة. بعد ذلك، يحصل كل bot قيد التشغيل على حاوية تحتوي على سطح مكتب Linux رسومي ومتصفح.
تذكر وثائق الاستضافة الذاتية للمشروع رقماً واضحاً: يكفي خادم بسعة 2 vCPU و4 GB لتشغيل API والعامل وPostgres عندما تتولى E2B استضافة أسطح مكتب bot. هذا الرقم يخص طبقة التحكم وحدها، مع استضافة الجزء ذي الحمل المرتفع في مكان آخر. عند ضبط SANDBOX_PROVIDER=docker، تنتقل أسطح المكتب هذه إلى VPS الخاص بك، لذلك تصبح سعة 4 GB حداً أدنى لا سعة مستهدفة. ابدأ بسعة 8 GB إذا كنت تخطط لإبقاء أكثر من bot واحد قيد التشغيل، وقِس القيمة الفعلية باستخدام docker stats أثناء عمل bot. المتصفح داخل sandbox هو العامل الذي يرفع استهلاك الذاكرة، لذلك لن تمنحك ورقة المواصفات هذه الإجابة. لمعرفة الطريقة العامة لتحديد حجم خادم مناسب لتشغيل الوكلاء، يشرح مقدار RAM وCPU الذي يحتاج إليه VPS لوكيل فعلياً عملية القياس بالتفصيل.
يمنع إعداد واحد تفاقم هذا الوضع. يوفّر .env.example الإعداد SANDBOX_IDLE_MS=600000 مع تعليق يوضح أنّه يوقف أجهزة E2B أو يوقف أجهزة Docker بعد مرور عدد الملليثواني المحدد من الخمول. بعد 10 دقائق من الخمول، يزول الجهاز. القيمة الدنيا المقبولة هي 30000. من دون هذا الإعداد، سيحتفظ كل bot فتحته بالذاكرة إلى أجل غير مسمى.
تُحتسب مساحة القرص أيضاً. تشترك صورة sandbox ووحدات Node ووحدة تخزين Postgres في قرص واحد، لذلك تُعد سعة 40 GB نقطة بداية مناسبة.
ثبّت الإصدار قبل الاستنساخ
يتطور Rakazo بسرعة، وmain ليس إصداراً. حتى 16 August 2026، يحتوي المستودع على وسم واحد فقط، وهو v0.1.0-beta، وقد نُشر في 13 August 2026 ووُسِم بأنه إصدار تجريبي.
git clone https://github.com/elie222/rakazo.git
cd rakazo
git checkout 53b119a68d9ef843d23aa3b7e3719b6be7b51fdb
git log -1 --format='%H %ci'ذلك هو الالتزام الذي يشير إليه v0.1.0-beta. ثبّت الالتزام بدلاً من الفرع أو الوسم. يتغير الفرع في عملية git pull التالية، والوسم تسمية قابلة للتغيير يمكن للمشرف إعادة توجيهها، لذلك لا يحدد أيٌّ منهما شجرة يمكنك العودة إليها. لا يمكن تغيير معرّف الالتزام. دوّن معرّفك بجانب معلومات الخادم الأخرى، لأن الحل السريع والرخيص عند تعطل الترقية هو git checkout <old commit> وإعادة البناء، ولا ينجح ذلك إلا إذا كنت تعرف الالتزام الذي كان يعمل.
المتطلبات: Node 22 وpnpm 9 وDocker
node -v
pnpm -v
docker --versionيعلن package.json عن "engines": { "node": ">=22" } و"packageManager": "pnpm@9.15.0"، لذلك يجب أن يعرض node -v القيمة v22 أو قيمة أعلى. تكون حزمة Node في مستودع Ubuntu أقدم من ذلك عادةً، لذا ثبّتها من NodeSource أو عبر nvm. يأتي pnpm مع Node من خلال corepack:
corepack enable
corepack prepare pnpm@9.15.0 --activateيغطي Docker Engine مع إضافة compose بقية المتطلبات، ويجب أن يتمكن مستخدمك من الوصول إلى البرنامج الخفي. إذا أجاب docker ps بالقيمة permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock، فأضف مستخدمك إلى مجموعة docker وافتح جلسة shell جديدة لتسجيل الدخول. اعرف أولاً ما الذي يمنحه ذلك: العضوية في docker تعادل root على الجهاز، لأن أي مستخدم في هذه المجموعة يستطيع تشغيل حاوية تُجري mount لنظام ملفات المضيف.
اضبط ملف .env، ثم شغّل Postgres
cp .env.example .env
chmod 600 .envيجب تغيير قيمتين قبل تعريض أي مكوّن للشبكة. يوفّر .env.example كلاً من BETTER_AUTH_SECRET=replace-with-32-plus-character-secret وENCRYPTION_KEY=replace-with-64-char-hex-or-passphrase. يرفض Rakazo قيم العناصر النائبة هذه خارج بيئة التطوير، لذلك يفشل النشر غير المكتمل بوضوح بدلاً من التشغيل باستخدام سر منشور في المستودع.
openssl rand -base64 48
openssl rand -hex 32بعد ذلك، شغّل قاعدة البيانات وحدها ونفّذ عمليات الترحيل.
docker compose --env-file .env -f infra/compose/docker-compose.yml up postgres -d
pnpm install
pnpm db:generate
pnpm db:migrate
pnpm sandbox:buildينشئ pnpm sandbox:build صورة حاسوب الروبوت، والمحددة في package.json باسم docker build -t rakazo/computer:local infra/sandboxes/computer. هذه صورة رسومية، لذلك يجلب البناء الأول كمية كبيرة من البيانات ويستغرق وقتاً. تأكد من اكتمالها باستخدام docker image ls rakazo/computer، الذي يجب أن يطبع صفاً واحداً.
ينشر ملف Compose Postgres على 127.0.0.1:5433:5432، وهو متاح عبر loopback فقط. اتركه بهذه الطريقة. بيانات اعتماد التطوير هي rakazo:rakazo، وهي موجودة في المستودع، ويمكن لماسحات الشبكة اكتشاف منفذ Postgres المتاح من الإنترنت مع كلمة مرور منشورة خلال ساعات. يقرأ ملف Compose الخاص بالإنتاج POSTGRES_PASSWORD بدلاً من ذلك، لذا عيّنها إلى سلسلة عشوائية عند الوصول إلى تلك المرحلة.
التشغيل الأول
pnpm devيبدأ ذلك أربعة مكوّنات: واجهة API على المنفذ 3100، وGraphile Worker، وتطبيق الويب Vite على المنفذ 5173، ومشرف sandbox على المنفذ 7091. يتوفر التطبيق على http://127.0.0.1:5173، ومن المفترض أن تظهر لك صفحة تسجيل الدخول.
في VPS، لا تكون جالساً أمام الجهاز نفسه، ولا ينبغي أن تنشر المنفذ 5173 للوصول إليه. بدلاً من ذلك، مرّر المنافذ عبر SSH (secure shell) من جهازك.
ssh -L 5173:127.0.0.1:5173 -L 3100:127.0.0.1:3100 you@your-serverانتبه إلى الفرق بين طريقتَي التشغيل. يشغّل pnpm dev Vite على المضيف، مع ربطه محلياً. وتنشر خدمة web في ملف Compose المنفذ 5173:5173 على جميع الواجهات. إذا شغّلت حزمة Compose الكاملة للتطوير على VPS عام، فسيصبح التطبيق مكشوفاً. لذلك استخدم ملف الإنتاج وReverse Proxy الخاص به لأي مكوّن تتركه قيد التشغيل.
أي موفّر للعزل آمن على الخادم؟
هذا هو الإعداد الوحيد الذي يجب ضبطه بشكل صحيح. يقبل SANDBOX_PROVIDER في .env أربع قيم.
dockerهي القيمة الافتراضية. يحصل كل روبوت على حاوية خاصة به على جهازك، وتُبنى هذه الحاوية من الصورة التي ينتجهاpnpm sandbox:build. هذا هو أسرع إعداد للاستضافة الذاتية.e2bيشغّل أجهزة الكمبيوتر الخاصة بالروبوتات على E2B ويتطلبE2B_API_KEY. يوصي المشروع به لعمليات النشر العامة أو متعددة المستخدمين، لأنه يفصل أجهزة الكمبيوتر الخاصة بالروبوتات عن المضيف الذي يشغّل API وقاعدة البيانات.desktopيشغّل أوامر الروبوت مباشرة على مضيف API وworker. وتعليمات المستودع واضحة: لا تستخدمه على خادم عام أو مشترك.fakeهو محاكي داخل العملية مخصص للاختبارات. وليس بيئة تشغيل.
خذ تحذير وضع سطح المكتب حرفياً. في وضع سطح المكتب لا يوجد أي حد للعزل، لذلك يشغّل الروبوت أوامر shell بصفته المستخدم الذي يشغّل عملية API، مع الدليل الرئيسي لذلك المستخدم، ومفاتيح SSH الخاصة به، وبيانات اعتماد cloud الخاصة به، و.env الخاص به. يتحول النص الموجود في صفحة ويب يقرأها الروبوت إلى أمر على خادمك. استخدام وضع سطح المكتب على خادم هو الطريقة التي ينتهي بها الأمر بالروبوت حائزاً على بيانات اعتمادك. استخدمه على جهاز تجلس أمامه، أو لا تستخدمه إطلاقاً.
docker هو حد عزل فعلي، لكنه غير كامل. لا يستطيع روبوت قراءة ملفات روبوت آخر، لأن لكل روبوت حاويته الخاصة. لكن المشرف الذي ينشئ تلك الحاويات يركّب /var/run/docker.sock، والسيطرة على مقبس Docker الخاص بالمضيف تعني السيطرة على المضيف. لذلك أبقِ المشرف خاصاً. توثّق .env.example أن SANDBOX_SUPERVISOR_TOKEN هو اعتماد خدمة منفصل اختياري، وتكون قيمته الافتراضية BETTER_AUTH_SECRET عند تركه فارغاً. وهذا يعني أن ترك هذا السر على قيمته النائبة يحمي خدمة إنشاء الحاويات بسلسلة يمكن لأي شخص قراءتها على GitHub. اضبط القيمتين معاً. ولأقوى فصل متاح هنا، استخدم e2b، أو امنح Rakazo جهازاً لا يحتوي على أي شيء آخر. وهذا هو المنطق نفسه وراء تشغيل وكلاء البرمجة في آلة افتراضية مؤقتة: أرخص طريقة لتحمّل ارتكاب وكيل لخطأ هي ألا تكون قيمة جهازه تساوي شيئاً.
أين توضع مفاتيح واجهة برمجة النماذج؟
لا تتولى Rakazo إدارة فوترة النماذج. عليك توفير المفتاح. يضبط .env.example قيمة PI_DEFAULT_PROVIDER=openrouter، لذلك يُعد OPENROUTER_API_KEY المكان المعتاد، وتعمل مفاتيح المزوّدين عبر الإعداد نفسه.
احتفظ بالمفتاح في .env، ولا تضعه في أي ملف تلتزم به في Git. يمرّر أمرا Compose في المستودع --env-file .env، لذلك تصل القيم إلى الحاويات من دون كتابتها في ملفات YAML التي يتتبعها Git. ويمكنك أيضاً ترك OPENROUTER_API_KEY فارغاً ولصق مفتاح في التطبيق أثناء الإعداد الأولي، وهذا سبب إضافي يجعل ENCRYPTION_KEY بحاجة إلى قيمة عشوائية فعلية بدلاً من القيمة النائبة المضمّنة.
عيّن حداً للإنفاق على المفتاح لدى المزوّد قبل أن يستخدمه أي روبوت. فالروبوت الذي يدخل في حلقة يواصل الإنفاق، والحد الخاص بكل مفتاح هو الإجراء الوحيد الذي لا يعتمد على مراقبتك. امنح هذا المفتاح اسماً مستقلاً حتى تتمكن من إلغائه وحده.
الانتقال من وضع التطوير إلى إعداد يمكن تركه قيد التشغيل
يتضمن المستودع ملف Compose مخصصاً للإنتاج، ويشغّل Postgres وواجهة API والعامل وتطبيق الويب وCaddy للحصول تلقائياً على شهادات TLS (أمان طبقة النقل). ويتطلب E2B لأجهزة الروبوت.
sudo DEPLOY_USER=deploy bash infra/compose/harden-host.sh
docker compose --env-file .env -f infra/compose/docker-compose.prod.yml up -d --buildيعطّل harden-host.sh تسجيل الدخول عبر كلمة مرور SSH، ويضبط قواعد UFW (جدار الحماية غير المعقد) لـSSH وHTTP وHTTPS، ويفعّل fail2ban، ويطبّق ملفات تعريف AppArmor. اقرأه قبل تشغيله لأنه يغيّر طريقة تسجيل الدخول. أبقِ جلسة SSH ثانية مفتوحة أثناء تشغيله.
يتطلب .env للإنتاج إعدادات أكثر من إعداد التطوير. يذكر مستند الاستضافة الذاتية الحد الأدنى المطلوب.
NODE_ENV=production
RAKAZO_HOST=app.example.com
BETTER_AUTH_URL=https://app.example.com
WEB_ORIGIN=https://app.example.com
API_URL=https://app.example.com
POSTGRES_PASSWORD=<random>
BETTER_AUTH_SECRET=<random>
ENCRYPTION_KEY=<random>
E2B_API_KEY=<your key>
OPENROUTER_API_KEY=<your key>
SANDBOX_PROVIDER=e2b
AGENT_RUNTIME=pi
DATA_DIR=/dataوجّه سجل A إلى الخادم قبل تشغيل up لأول مرة. يطلب Caddy شهادة للاسم الموجود في RAKAZO_HOST، ويفشل الطلب إذا لم يُحل الاسم إلى هذا الخادم أو إذا كان المنفذ 80 مغلقاً أمام الاتصالات الخارجية.
اضبط أيضاً SIGNUP_ALLOWLIST=you@example.com. القيمة الافتراضية لـSIGNUPS_ENABLED=true تسمح لأي شخص يعثر على مثيل منشور باسم عام بالتسجيل، ويحصل كل حساب جديد على جهاز. أضف قائمة السماح أولاً. ويمكنك تخفيف هذا القيد لاحقاً إذا أردت.
اعتبر docs/self-host.md في المستودع المرجع المعتمد لإعدادات الإنتاج، لأنه يتغير مع الشيفرة بينما لا يتغير هذا الدليل. وبما أن Compose يتولى التشغيل، تنطبق القواعد المعتادة، وتوضح أساسيات Docker Compose لخادم VPS سبب ازدياد أهمية --env-file ووحدات التخزين المسماة عندما تترك المكدس دون تدخل لأشهر.
النسخ الاحتياطية
يشكّل Postgres ودليل data/ كامل المثيل.
./scripts/backup.sh
./scripts/restore.sh backups/BACKUP_TIMESTAMPينشئ backup.sh نسخة تفريغ من Postgres، ويؤرشف data/. بالنسبة إلى جهاز تعتمد عليه، ثبّت infra/compose/backup-prod.sh بوصفه /usr/local/sbin/rakazo-backup باستخدام المؤقت الذي يوفّره المستودع، كي تتم إدارة تدوير النسخ تلقائياً. النسخة الاحتياطية الموجودة على القرص نفسه الذي توجد عليه قاعدة البيانات ليست نسخة احتياطية فعلية، لذلك انسخها خارج الجهاز. ثم استعدها مرة واحدة على خادم احتياطي قبل أن تحتاج إليها.
سبب الفشل وما ستراه
لا يستطيع pnpm db:migrate الوصول إلى قاعدة البيانات. تشير عملية الترحيل إلى تعذّر الوصول إلى خادم قاعدة البيانات في 127.0.0.1:5433. إما أن حاوية Postgres لا تعمل، أو أنها تعمل لكنها لم تصبح جاهزة بعد. شغّل docker compose --env-file .env -f infra/compose/docker-compose.yml ps وابحث عن ظهور خدمة postgres بحالة healthy، لأن ملف compose يعرّف لها فحص صحة يُجرى كل ثلاث ثوانٍ. تعني إعادة تشغيل الحاوية في حلقة غالباً أن وحدة التخزين pgdata أُنشئت ببيانات اعتماد مختلفة. يمسحها docker compose ... down -v، ويحذف البيانات الموجودة فيها أيضاً.
المنفذ مستخدم بالفعل. يفشل تشغيل Postgres مع bind: address already in use عندما يشغل شيء آخر المنفذ 5433، وغالباً يكون ذلك مكدس Rakazo سابقاً نسيت إيقافه. يحدد sudo ss -lntp | grep 5433 العملية التي تستخدمه.
لا تحصل إحدى وحدات bot على حاسوب أبداً. عند استخدام SANDBOX_PROVIDER=docker من دون صورة rakazo/computer:local، لا يوجد شيء يمكن تشغيله. يجيب docker image ls rakazo/computer عن ذلك في سطر واحد، ويعالجه pnpm sandbox:build. إذا تعذّر على المشرف الوصول إلى Docker socket، فلن يستطيع إنشاء الحاويات أيضاً، وتذكر الرسالة المسار: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock.
يتوقف أمر طويل في منتصف التنفيذ. يضبط .env.example القيمة SANDBOX_COMMAND_TIMEOUT_MS=300000، لذلك يتوقف أي أمر واحد داخل حاسوب bot بعد خمس دقائق. ارفع هذه القيمة للعمليات البطيئة بدلاً من افتراض تعطل sandbox.
يتعطل pnpm install بطرق مربكة. افحص node -v قبل أي شيء آخر. يعلن workspace عن >=22، بينما يفشل إصدار Node الأقدم داخل شيفرة التبعيات بدلاً من عرض رسالة عن الإصدارات.
يعمل تسجيل الدخول محلياً، لكنه لا يعمل عبر النطاق. يجب أن تتطابق BETTER_AUTH_URL وWEB_ORIGIN وAPI_URL مع الأصل العام الظاهر في شريط العنوان، بما في ذلك المخطط. ويكون وجود قيمة قديمة في http://127.0.0.1:5173 داخل أحدها هو السبب المعتاد لعدم استمرار الجلسة.
تحديث نسخة مثبتة
مسار الترقية في وثيقة التشغيل الذاتي قصير: اسحب المصدر الجديد، وشغّل ترحيل قاعدة البيانات، ثم أعد تشغيل API والعامل.
./scripts/backup.sh
git fetch --all
git checkout NEW_COMMIT_SHA
pnpm install
pnpm --filter @rakazo/db migrate
docker compose --env-file .env -f infra/compose/docker-compose.prod.yml up -d --buildأنشئ نسخة احتياطية أولاً. تتحرك عمليات الترحيل إلى الأمام، ولا تمنحك النسخة التجريبية مسار تراجع يمكنك الاعتماد عليه. اقرأ الالتزامات بين SHA المثبت لديك وSHA الجديد قبل تطبيقها، لأن مشروعاً حديثاً إلى هذا الحد يعيد تسمية متغيرات البيئة من دون إعلان، ويظهر المتغير المفقود على شكل خدمة تبدأ ثم تتوقف. إذا كنت لا تزال تقرر ما إذا كان Rakazo مناسباً للتشغيل أصلاً، فسيغطي الملخص الخاص بوكلاء الذكاء الاصطناعي المستضافين ذاتياً البدائل الأخرى ضمن هذه الفئة وتكلفة إبقاء كل منها قيد التشغيل.
FAQ
هل يمكنني تشغيل Rakazo على VPS بسعة 1 GB؟
لا. تعمل Postgres وواجهة API والعامل والمشرف على sandbox وتطبيق الويب في الوقت نفسه. ومع SANDBOX_PROVIDER=docker يضيف كل bot نشط حاوية تحتوي على سطح مكتب رسومي ومتصفح. توضح وثائق المشروع أن 2 vCPU و4 GB تكفي لواجهة API والعامل وPostgres فقط عندما يستضيف E2B أسطح مكاتب bots. اعتبر 4 GB الحد الأدنى لطبقة التحكم، واستخدم سعة أكبر عندما تعمل أسطح المكاتب على جهازك.
هل موفّر sandbox لسطح المكتب آمن على الخادم؟
لا. يشغّل desktop أوامر bot مباشرة على مضيف API والعامل، بامتيازات المستخدم الذي يشغّل العملية، مع إمكانية الوصول إلى ملفات ذلك المستخدم وبيانات اعتماده. ينص المستودع على عدم استخدامه على خادم عام أو مشترك. استخدم docker لإنشاء حاوية لكل bot، أو e2b عندما يسجّل أكثر من شخص الدخول.
ما إصدار Rakazo الذي ينبغي تثبيته؟
اعتباراً من 16 August 2026 يوجد tag واحد هو v0.1.0-beta، وقد نُشر في 13 August 2026 وصُنّف إصداراً تجريبياً قبل النشر. نفّذ checkout للـcommit الذي يشير إليه، وهو 53b119a68d9ef843d23aa3b7e3719b6be7b51fdb، بدلاً من تتبّع main. قد يتغير branch أثناء عملك، ويمكن إعادة توجيه tag، لذلك لا يحدد أي منهما شجرة مصدر يمكنك العودة إليها. سجّل commit، لأن التراجع لا يكون ممكناً إلا عندما تعرف الإصدار الذي عمل بنجاح.
أين أضع OpenRouter API key؟
ضعه في .env باسم OPENROUTER_API_KEY، ولا تضعه مطلقاً في compose file تحفظه في commit. يمرر أمرا compose في المستودع كلاهما --env-file .env، لذلك تصل القيمة إلى الحاويات من دون كتابتها في YAML خاضع للتتبع. يمكنك أيضاً تركه فارغاً ولصق المفتاح في التطبيق أثناء الإعداد الأولي. عيّن حدّاً للإنفاق على المفتاح لدى الموفّر، لأن bot عالقاً في حلقة سيواصل استدعاء النموذج إلى أن يوقفه شيء ما.
هل أحتاج إلى اسم نطاق وTLS؟
نعم، لأي استخدام يتجاوز الاختبار الأولي. يشغّل compose file الخاص بالإنتاج Caddy ويحصل على الشهادات تلقائياً، ويجب أن تحمل RAKAZO_HOST وBETTER_AUTH_URL وWEB_ORIGIN وAPI_URL جميعها origin العام نفسه عبر HTTPS. ولإجراء اختبار أولي، يمكنك تجاوز اسم النطاق: شغّل pnpm dev وأعد توجيه المنفذ 5173 عبر SSH بدلاً من نشره.