Relayium

الاستضافة الذاتية لـ Relayium: شغّل خادم نقل الملفات والنصوص الخاص بك

آخر تحديث: 2026-08-06

‏Relayium مرخَّص بموجب AGPL-3.0 ومفتوح المصدر، والخادم صورة واحدة مكتفية بذاتها — بلا قاعدة بيانات خارجية، بلا حاوية تخزين لطرف ثالث، ولا شيء للتسجيل فيه. إن كنت تفضّل تشغيل كل شيء بنفسك بدل الاعتماد على relayium.com، فهذا الدليل يشغّل خادمًا بـ Docker ويوجّه الـ CLI إليه.

تمنحك الاستضافة الذاتية تحكمًا كاملًا في مكان بياناتك، ونطاقك الخاص وشهادة TLS خاصة بك، وبلا اعتماد على بنية أحد آخر. كل ما يلي مبني على ملفات موجودة فعلًا في المستودع — docker-compose.yml وserver/.env.example وdocs/self-hosting.md — فلا شيء هنا عبارة عن راية أو إعداد غير موجود فعلًا.

لماذا الاستضافة الذاتية

عمليات النقل الفوري في Relayium مشفَّرة من الطرف إلى الطرف. قد يحمل مُرحِّل TURN المستضاف ذاتيًا بايتات مشفَّرة، ويعالج الخادم بيانات الإشارة الوصفية، لكن لا يمكن لأي منهما قراءة النص الصريح للملف أو فك تشفيره؛ ولا يخزّن الخادم أو المُرحِّل نسخة أو سجلًا على الخادم للمحتوى الفوري. ويحتفظ الخادم بحسابك، و — لعمليات النقل المُخزَّنة/المبنية على رابط — بكتل نص مُشفَّر وقاعدة بيانات SQLite صغيرة. الاستضافة الذاتية تعني أن تعيش تلك البيانات على بنية تتحكم فيها أنت، تحت نطاقك الخاص، دون أن تتدخل قرارات تشغيل أحد آخر.

لأن المشروع مرخَّص بموجب AGPL-3.0 ومفتوح المصدر (github.com/relayium/relayium)، يمكنك أن تقرأ بالضبط ما يفعله الخادم قبل أن تأتمنه على أي شيء، وأن تنسخه (fork) أو تعدّله بحرية.

بداية سريعة مع Docker

ما تحتاجه قبل الخطوة 1

  • مضيف عليه Docker Engine وملحق Compose. يطبع docker compose version سطر إصدار؛ أما ظهور «docker: 'compose' is not a docker command» فيعني أن الملحق غير مثبَّت.
  • نسخة من المستودع. يبني ملف compose الصورة من شجرة المصدر هذه، فهو يحتاج إلى Dockerfile وweb/ بجواره — ولا توجد صورة جاهزة لسحبها.
  • مساحة قرص للوحدة المسماة relayium-data: قاعدة بيانات SQLite إضافةً إلى ما تحتفظ به من نص مشفَّر للنقل المخزَّن.
  • نطاق ووكيل عكسي ينهي TLS إن كان سيستخدمه أحد غيرك. الحاوية لا تتحدث إلا HTTP صريحًا، ولا تنشر افتراضيًا إلا على واجهة الاسترجاع المحلية.
  • ولا شيء آخر. لا قاعدة بيانات خارجية، ولا دلو تخزين كائنات، ولا حساب لدى طرف ثالث.

جذر المستودع يوفّر Dockerfile وdocker-compose.yml يبنيان صورة واحدة مكتفية بذاتها — ثنائي Go ساكن يقدّم تطبيق الويب المبني مسبقًا، فلا حاجة إلى Node منفصل أو سلسلة أدوات Go أو nginx لمجرد تشغيله.

  1. استنسخ المستودع وانتقل إليه.

    git clone https://github.com/relayium/relayium.git
    cd relayium
  2. ابنِ وشغّل. المفتاح النائب إلزامي حتى مع إيقاف المُرحِّل: يتحقق Compose من المتغير المطلوب لخدمة coturn المعطَّلة بالملف الشخصي وقت تحليل الملف، فيرفض أمر docker compose up المجرَّد أن يبدأ.

    RELAYIUM_TURN_SECRET=placeholder docker compose up -d --build
  3. تأكّد أن الحاوية بقيت قائمة فعلًا بدل أن تدور في حلقة انهيار وإعادة تشغيل.

    docker compose ps
  4. اسأل النسخة إن كانت تستطيع الخدمة فعلًا. استخدم ‎/readyz‎ لا ‎/healthz‎ — الفرق بينهما هو كل مغزى هذا الفحص، وصندوق النتيجة المتوقَّعة أدناه يوضّح السبب.

    curl -s http://127.0.0.1:8080/readyz
  5. انسخ قالب الإعدادات واضبط عنوانك العام. يبني RELAYIUM_BASE_URL الروابط في البريد الصادر ويقرّر أيضًا هل تحمل كعكات الجلسة راية Secure، فلا بد أن يكون عنوان ‎https://‎ الحقيقي الخاص بك.

    cp server/.env.example server/.env
    chmod 600 server/.env
  6. ضع nginx أو Caddy في المقدمة لينهي TLS لنطاقك ويمرّر كل شيء — ‎/‎ و‎/api‎ و‎/ws‎ و‎/admin‎ — إلى المنفذ 8080. ثم أعد التشغيل ليسري مفعول server/.env.

    docker compose up -d

كيف تبدو نسخة تعمل بشكل صحيح

تُبلِّغ الحاوية عن Up، ويستجيب الطرفان كلاهما. المهم هو ready: إذ يعيد ‎/healthz‎ قيمة ok دون أي شرط وقبل أن يُفتح أي شيء، فينجح حتى على نسخة صارت قاعدة بياناتها أو دليل الكتل غير صالح للاستعمال. أما ‎/readyz‎ فيتحقق من قاعدة بيانات SQLite ومن دليل الكتل، ويعيد 503 متى تعطّل أحدهما.

$ docker compose ps
NAME                IMAGE                     STATUS          PORTS
relayium-server-1   relayium/relayium:local   Up 12 seconds   127.0.0.1:8080->8080/tcp

$ curl -s http://127.0.0.1:8080/healthz
ok
$ curl -s http://127.0.0.1:8080/readyz
ready

أضف مُرحِّل TURN لعمليات النقل عبر الشبكات

عمليات النقل في الشبكة نفسها (LAN) وpush/pull القائم على SSH تعمل بلا أي إضافة. عمليات النقل الفوري عبر الشبكات (جهازان خلف NAT مختلفين) تحتاج أحيانًا مُرحِّل TURN لإنشاء مسار — لا يرى المُرحِّل سوى نص مُشفَّر أبدًا، لا محتوى ملفاتك.

لدى docker-compose.yml ملف تعريف relay اختياري يُشغّل coturn (خادم TURN) ونسخة Redis صغيرة لقياس بايتات الترحيل، إلى جانب الخادم الرئيسي:

ولا بد أن يصل المفتاح السري إلى موضعين مختلفين، والخطأ في ذلك يفشل بلا صوت. يتلقّاه coturn عبر استبدال المتغيرات في Compose، وهو استبدال لا يُحَل إلا من الصدفة أو من ملف ‎.env‎ في جذر المشروع. أما الخادم فيقرأه من بيئته هو — أي من server/.env — والمفتاح الفارغ يعطّل TURN تعطيلًا كاملًا. فإن ضبطت أحدهما فقط، حصلت على coturn يعمل ولا يصدر له الخادم بيانات اعتماد قط: كل الحاويات تُبلِّغ أنها سليمة، ولا شيء يُسجَّل، وتظل عمليات النقل عبر شبكات NAT الصارمة تفشل تمامًا كما كانت قبل إضافة المُرحِّل.

  1. ولّد مفتاحًا سريًا عشوائيًا طويلًا واحدًا. والقيمة نفسها تُستخدم في كل ما يلي.

    openssl rand -hex 32
  2. ضع هذا المفتاح، مع عناوين المُرحِّل التي يشير إليها نطاقك، في server/.env حتى يفعّل الخادم TURN أصلًا.

    RELAYIUM_TURN_SECRET=<the value from step 1>
    RELAYIUM_TURN_URLS=turn:example.com:3478,turns:example.com:5349
  3. صدِّر الملف نفسه إلى الصدفة ليتمكن استبدال Compose من تسليم coturn المفتاح ذاته. واستخدام source يُبقي المصدر واحدًا ويُبعد المفتاح عن سطر الأوامر حيث يكشفه ps.

    set -a; . ./server/.env; set +a
  4. شغّل المنظومة مع الملف الشخصي relay.

    docker compose --profile relay up -d --build
  5. افتح منافذ المُرحِّل على جدار حماية المضيف. يعمل coturn بشبكة المضيف، فهذه قواعد المضيف لا قواعد Docker: UDP 3478 و49152-65535، وTCP 3478 و5349.

  6. تأكّد أن الخادم — لا coturn وحده — أقلع وهو يحمل المفتاح. هذا هو الفحص الذي يلتقط الحالة الصامتة.

    docker compose exec server env | grep RELAYIUM_TURN

كيف يبدو مُرحِّل يعمل بشكل صحيح

يعود المفتاحان كلاهما بقيمة غير فارغة من داخل حاوية الخادم. وكون coturn يعمل لا يثبت شيئًا بذاته — فالمتصفح لا يحصل إلا على بيانات اعتماد مُرحِّل أصدرها الخادم.

$ docker compose exec server env | grep RELAYIUM_TURN
RELAYIUM_TURN_SECRET=3f7a…
RELAYIUM_TURN_URLS=turn:example.com:3478,turns:example.com:5349

ثبّت CLI على جهازك

تُشغّل هذه الخطوة الأخيرة relayium CLI على حاسوبك أنت (لا على الخادم)، فثبّته هناك إن لم تكن قد فعلت. على macOS أو Linux:

curl -fsSL https://relayium.com/install.sh | sh

وجّه الـ CLI إلى خادمك

يستخدم Relayium CLI افتراضيًا خادم التعارف الخاص بـ relayium.com لعمليات send/receive وtext عبر الشبكات. مرّر ‎--server‎ لاستخدام خادمك بدلًا منه:

  1. على جهاز يملك أصلًا الـ CLI من القسم السابق، سجّل الدخول إلى خادمك أنت لا إلى relayium.com. سيطبع رابطًا ورمزًا؛ وافق عليه من متصفح مسجَّل الدخول إلى نسختك.

    relayium login --server https://your-domain
  2. تحقّق من الخادم الذي ارتبطت به بيانات الاعتماد المحفوظة. لا يقبل whoami أي رايات — فهو يُبلِّغ بما كتبه تسجيل الدخول فعلًا، وهذا بالضبط ما يجعل تشغيله مفيدًا.

    relayium whoami
  3. مرّر الـ ‎--server‎ نفسه عند الإرسال. فبدونه يُصدر الـ CLI رمز الاقتران على relayium.com، ولن يجده الطرف الآخر على نسختك أبدًا.

    relayium send ./report.pdf --server https://your-domain
  4. استقبل على الجهاز الآخر بالرمز المطبوع وبالـ ‎--server‎ نفسه. وجلسات النص تعمل بالطريقة ذاتها.

    relayium receive 483920 --server https://your-domain
    relayium text --server https://your-domain
    relayium text 483920 --server https://your-domain

كيف تعرف أنه يتحدث إلى نسختك أنت

يطبع whoami الحساب يتبعه بين قوسين الخادم المرتبط به. فظهور نطاقك أنت هناك — لا relayium.com — هو التأكيد.

$ relayium login --server https://your-domain
Open https://your-domain/device and enter code: WDJB-MJHT
logged in as you@example.com

$ relayium whoami
you@example.com (https://your-domain)

حين لا ينجح الأمر

خمسة إخفاقات تغطي تقريبًا كل استضافة ذاتية فاشلة. ولكلٍّ منها سطر تقرؤه أو أمر تشغّله يحسم المسألة، وثلاثة من الخمسة تبدو كالنجاح حتى تُشغِّل الفحص فعلًا.

العَرَض، الفحص، الإصلاح

يرفض docker compose up أن يبدأ من الأساس، قبل أن يُبنى أي شيء.
docker compose up -d --build
# required variable RELAYIUM_TURN_SECRET is missing a value

يستبدل Compose متغيرات الملف كله قبل أن يُرشّح حسب الملفات الشخصية، فيتحقق من المتغير المطلوب لخدمة coturn المعطَّلة حتى مع إيقاف المُرحِّل. ضع أي قيمة نائبة في المقدمة — RELAYIUM_TURN_SECRET=placeholder docker compose up -d --build — ولا تستبدلها بمفتاح حقيقي إلا حين تفعّل الملف الشخصي relay فعلًا.

الحاوية في حالة Up، لكن متصفحًا على جهاز آخر لا يصل إليها.
docker compose ps
# PORTS  127.0.0.1:8080->8080/tcp

الارتباط بواجهة الاسترجاع هو السلوك الافتراضي، حتى لا يعرض مضيف عام HTTP الصريح على الإنترنت. في الإنتاج اتركه كما هو وأنهِ TLS في وكيل عكسي على المضيف نفسه. أما جهاز الشبكة المحلية وحدها بلا وكيل، فانشره أوسع بـ RELAYIUM_BIND=0.0.0.0 docker compose up -d — وهذا متغير يقرؤه compose لا الخادم.

يقول ‎/healthz‎ ok، لكن التسجيل يفشل ولا تظهر الروابط المخزَّنة أبدًا.
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/readyz
# 503

يعيد ‎/healthz‎ قيمة ok دون شرط ولا يثبت إلا أن العملية تستمع. أما ‎/readyz‎ فيتحقق من قاعدة بيانات SQLite ومن دليل الكتل، فيعني الرمز 503 أن أحدهما غير صالح للاستعمال — تحقّق من أن الوحدة relayium-data مُركَّبة وأن RELAYIUM_DB وRELAYIUM_BLOB_DIR يشيران إلى داخلها.

يطبع relayium login رابط تحقّق على localhost لا يمكنك فتحه.
relayium login --server https://your-domain
# Open http://localhost:8080/device and enter code: WDJB-MJHT

يبني الخادم ذلك الرابط من RELAYIUM_BASE_URL، وقيمته الافتراضية ‎http://localhost:8080‎. اضبطه في server/.env على عنوان ‎https://‎ الحقيقي ثم أعد التشغيل. وهو يقرّر أيضًا هل تحمل كعكات الجلسة راية Secure، فتركه خاطئًا ليس مسألة شكلية.

coturn يعمل، ومع ذلك تظل عمليات النقل عبر NAT الصارم تفشل — ودون أي شيء في السجلات.
docker compose exec server env | grep RELAYIUM_TURN
# لا مُخرَجات

وصل المفتاح إلى coturn عبر استبدال Compose ولم يصل إلى الخادم قط، والمفتاح الفارغ لدى الخادم يعطّل TURN تمامًا. ضع RELAYIUM_TURN_SECRET وRELAYIUM_TURN_URLS في server/.env، وحمّله بـ set -a; . ./server/.env; set +a ليرى الاستبدال القيمة نفسها، ثم أعد تشغيل الملف الشخصي relay. ولا بد أن يعود المفتاحان كلاهما بقيمة غير فارغة في ذلك الفحص.

الأسئلة الشائعة

هل أحتاج إلى إعداد TURN؟

فقط إن أردت أن تعمل عمليات النقل الفوري عبر الشبكات عبر أنواع NAT الصارمة. عمليات النقل في الشبكة نفسها، وpush/pull القائم على SSH، وdaemon direct، جميعها تعمل بدونه — TURN مخصّص بحتًا لاجتياز NAT على مسار رمز الاقتران عبر الشبكات.

هل يبقى الـ CLI مجانيًا إن استضفتُ ذاتيًا؟

نعم. يبقى الـ CLI مجانيًا مع relayium.com أو خادمك. يحتاج send أو text بلا رمز إلى حساب على الخادم المستهدف لإصدار رمز، ويحتاجه up لتخزين ملف. أما receive وdown وtext مع الرمز المطبوع فلا تحتاج إلى تسجيل دخول.

هل يمكنني استخدام نطاقي الخاص وشهادة TLS خاصة بي؟

نعم. تستمع صورة Docker على HTTP عادي على ‎:8080؛ ضع nginx أو Caddy أمامها بنطاقك الخاص وشهادتك (مثلًا عبر certbot/Let's Encrypt). يغطّي docs/self-hosting.md ما ينبغي توجيهه عبر البروكسي؛ تهيئة nginx الخاصة ببيئة إنتاج Relayium نفسها غير منشورة، لذا عليك كتابة تهيئتك الخاصة.

ما البيانات التي يخزّنها خادمي المُستضاف ذاتيًا؟

قاعدة بيانات SQLite (الحسابات، الجلسات) في RELAYIUM_DB، و — لعمليات النقل المُخزَّنة/المبنية على رابط — كتل مشفَّرة في RELAYIUM_BLOB_DIR لا يستطيع الخادم نفسه فكّ تشفيرها. لا يحفظ الخادم ملفات النقل الفوري أو أجسام الرسائل، بل يرحّل مصافحة الإشارة فقط؛ ويمكن للطرف المستلم حفظ الملفات أو الاحتفاظ بالنص.

ثبّت Relayium CLI المجاني ووجّهه إلى خادمك الخاص بـ ‎--server‎.

احصل على الـ CLI

تابع القراءة