SSD Nodes Learn 🎉 VPS من $5.50/شهر
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-15

استضافة LinkBreeze ذاتياً كبديل لـ Linktree

شغّل LinkBreeze على VPS باستخدام Docker Compose وCaddy، مع تثبيت وسوم الصور، وتتبع نقرات بلا ملفات تعريف ارتباط، ومعرفة المجلد الوحيد الذي يحفظ موقعك بالكامل.

ماهية LinkBreeze

LinkBreeze بديل مستضاف ذاتياً لـLinktree. وهو حاوية Docker واحدة تعرض صفحة عامة للروابط في السيرة الذاتية ولوحة تحكم إدارية، وتخزّن كل حالة التطبيق في ملف SQLite واحد. يخضع المشروع لترخيص MIT، وكُتب بلغة TypeScript باستخدام Next.js، ويُنشر باسم ghcr.io/manak-hash/linkbreeze. لتشغيله، تحتاج إلى VPS، ونطاق يحتوي على سجل A يشير إلى ذلك الـVPS، وفتح المنفذين 80 و443، إضافة إلى Docker Engine مع إضافة Compose.

يغطي هذا الدليل أسلوب النشر الذي يدعمه المستودع فعلياً: Docker Compose خلف reverse proxy يتولى الحصول على الشهادات بنفسه. كما يوضح ما الذي يتعطل، لأن الرابط الموجود في السيرة الذاتية هو URL عام ينقر عليه الآخرون، وتعطل هذا الرابط يعني فقدان الزيارة.

قبل كل ذلك، انتبه إلى حداثة هذا المشروع.

هل أصبح LinkBreeze ناضجاً بما يكفي لرابط ملف شخصي عام؟

حتى أغسطس 2026، يضم المستودع 178 نجمة و17 تفرعاً، ويتولى صيانته شخص واحد. الإصدار الأول الموسوم، v1.0.0، مؤرخ في 1 يوليو 2026. هذا مشروع عمره بضعة أسابيع، وليس بضعة أعوام.

ChartLinkBreeze tagged releases per week, v1.0.0 to v1.2.7
The data behind this chart
[
  {
    "week": "2026-06-29",
    "releases": 3,
    "cumulative": 3
  },
  {
    "week": "2026-07-06",
    "releases": 3,
    "cumulative": 6
  },
  {
    "week": "2026-07-13",
    "releases": 1,
    "cumulative": 7
  },
  {
    "week": "2026-07-20",
    "releases": 2,
    "cumulative": 9
  },
  {
    "week": "2026-07-27",
    "releases": 3,
    "cumulative": 12
  },
  {
    "week": "2026-08-03",
    "releases": 2,
    "cumulative": 14
  },
  {
    "week": "2026-08-10",
    "releases": 3,
    "cumulative": 17
  }
]

منذ v1.0.0، أطلق المشروع 17 إصداراً موسوماً عبر 7 أسابيع تقويمية. كان الأسبوع الأخير في ذلك المخطط لا يزال جارياً عند كتابة هذا الدليل، وقد تضمّن بالفعل 3 من هذه الإصدارات.

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

تحميك الرخصة من أسوأ الاحتمالات. فترخيص MIT، مع صورة حاوية وملف SQLite على قرصك، يعني أنه إذا توقف التطوير فسيستمر ما لديك في العمل. لكنها لا تحميك من تطبيق ويب متاح للعامة يتوقف عن تلقي إصلاحات الأمان، إذ سيصبح عبئاً بمرور الوقت. انشره على أساس أنك ستواصل تحديثه، واحرص على أن يعمل روتين النسخ الاحتياطي أدناه منذ اليوم الأول.

ثبّت وسم الصورة، ولا تستخدم latest

تدفع عملية الإصدار وسمين بالضبط لكل إصدار: latest، ورقم الإصدار بعد إزالة v في بدايته. لذلك يكون الوسم المثبّت للإصدار v1.2.7 هو ghcr.io/manak-hash/linkbreeze:1.2.7. أما كتابة :v1.2.7 فلا تسحب أي شيء، ويعرض Docker الرسالة manifest unknown، لأن هذا الوسم لم يُدفع مطلقاً.

ثبّت الوسم لأن latest يتغير. وفق الوتيرة الموضحة في المخطط أعلاه، يُعدّ تنفيذ docker compose pull على latest ترقية غير خاضعة للمراجعة لصفحة يستخدمها جمهورك. عند استخدام وسم مثبّت، تحدث الترقية عندما تعدّل الملف.

هناك أمر آخر يتعلق بالصورة. تبني عملية الإصدار الصورة من دون إعداد platforms:، لذلك تكون الصورة المنشورة linux/amd64 فقط. ويفشل السحب على مضيف arm64 مع no matching manifest for linux/arm64/v8 in the manifest list entries. إذا كنت تشغّل خادماً افتراضياً ARM بدلاً من x86، فابنِ الصورة على الخادم نفسه:

git clone --branch v1.2.7 --depth 1 https://github.com/Manak-hash/LinkBreeze.git
cd LinkBreeze
docker build -t linkbreeze:1.2.7 .

ثم استخدم linkbreeze:1.2.7 بوصفه اسم الصورة في ملف compose أدناه.

نشر LinkBreeze خلف Caddy مع TLS تلقائي

يطلب Caddy الشهادات من Let's Encrypt ويجددها تلقائياً، لذلك لا تحتاج إلى خطوة منفصلة لإعداد شهادة TLS (أمان طبقة النقل). يتكون النشر بالكامل من ثلاثة ملفات في دليل واحد.

أنشئ السر أولاً:

mkdir -p ~/linkbreeze && cd ~/linkbreeze
printf 'SECRET_KEY=%s\n' "$(openssl rand -hex 32)" > .env
chmod 600 .env

يوقّع SECRET_KEY ملف تعريف ارتباط جلسة المسؤول، ويضيف قيمة عشوائية إلى تجزئة زائر التحليلات. يضبطه ملف Compose المنشور في المستودع افتراضياً على ${SECRET_KEY:-changeme-in-production}، لذلك يعمل المثيل الذي تتخطى فيه هذه الخطوة باستخدام مفتاح توقيع جلسة منشور علناً على GitHub. اضبطه قبل التشغيل الأول، لأن تغييره لاحقاً يؤدي إلى تسجيل خروجك وإعادة ضبط قيمة التحليلات العشوائية.

اكتب docker-compose.yml:

services:
  linkbreeze:
    image: ghcr.io/manak-hash/linkbreeze:1.2.7
    restart: unless-stopped
    volumes:
      - linkbreeze-data:/app/data
    environment:
      - DATABASE_PATH=/app/data/linkbreeze.db
      - SECRET_KEY=${SECRET_KEY}
      - BASE_URL=https://links.example.com
    networks:
      - linkbreeze-net

  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    networks:
      - linkbreeze-net

networks:
  linkbreeze-net:

volumes:
  linkbreeze-data:
  caddy-data:
  caddy-config:

يُعد BASE_URL اختيارياً، لكن من المفيد ضبطه. فهو يعرّف التطبيق بعنوانه العام الفعلي، بحيث لا يؤدي طلب يصل مع ترويسة Host مزوّرة إلى جعل التطبيق ينشئ روابط إلى نطاق شخص آخر.

اكتب Caddyfile بجانبه، باستخدام نطاقك الخاص:

links.example.com {
    encode zstd gzip
    reverse_proxy linkbreeze:3000
}

يضبط Caddy X-Forwarded-For وX-Forwarded-Proto في الطلبات التي يمررها افتراضياً، وتعتمد التحليلات عليهما. شغّل الحاويات:

docker compose up -d
docker compose ps
docker compose logs -f caddy

يجب أن تعرض docker compose ps حاوية LinkBreeze بالحالة healthy. تتضمن الصورة فحصاً لحالتها، وهو wget --spider -q http://127.0.0.1:3000/api/health، لذلك لا تحتاج إلى إضافة فحص آخر. لا تنسخ فحص الحالة من مثال Caddy الموجود في المستودع، لأنه يستدعي curl، بينما تُبنى الصورة على node:22-alpine الذي يتضمن busybox wget ولا يتضمن curl. وتبلغ تلك الحاوية عن unhealthy رغم أنها تقدم الصفحات بشكل سليم.

افتح https://links.example.com في متصفح. تؤدي الزيارة الأولى إلى معالج الإعداد في /setup، الذي ينشئ حساب المسؤول الوحيد. بعد ذلك تكون لوحة المعلومات في /dashboard، ونموذج تسجيل الدخول في /login. هذا الحساب محلي لهذا المثيل، ولا يوفر التطبيق نقطة تكامل لتسجيل الدخول الموحّد. لذلك، إذا أردت أن تستخدم لوحة المعلومات بيانات تسجيل الدخول نفسها المستخدمة في بقية الخدمات التي تستضيفها، فيجب تنفيذ ذلك بواسطة وكيل مصادقة أمامي مثل Authentik مستضاف ذاتياً.

لاحظ ما لا يفعله ملف Compose: فهو لا ينشر المنفذ 3000 مطلقاً. يستمع Caddy وحده على الواجهة العامة. إذا كانت صيغة ملف Compose جديدة عليك، يشرح أساسيات Docker Compose لخادم VPS الأجزاء التي يفترضها هذا الملف. وإذا كنت تشغّل خدمة أخرى أمامه، يوضح مقارنة بين Nginx وCaddy وTraefik ما الذي سيتغير. يتضمن المستودع أمثلة عاملة لـNginx مع Certbot، وTraefik، ونفق Cloudflare.

مكان وجود بياناتك وما يجب أن تتضمنه النسخة الاحتياطية

يشير DATABASE_PATH إلى /app/data/linkbreeze.db. تُكتب الصور الرمزية المرفوعة والصور المصغّرة للروابط بجانبه في /app/data/uploads. يوجد كلاهما في وحدة التخزين المسماة linkbreeze-data، لذلك تكون وحدة النسخ الاحتياطي هي وحدة التخزين، وليس ملف قاعدة البيانات وحده. إذا استعدت الملف من دون مجلد التحميلات، فستُرجع كل صورة في الصفحة الخطأ 404.

كل ما عدا ذلك موجود فعلاً في قاعدة البيانات الواحدة: الصفحات والروابط والإعدادات والقالب ومشتركو البريد الإلكتروني وصفوف التحليلات.

أنشئ النسخة أثناء إيقاف الحاوية:

docker compose stop linkbreeze
docker compose cp linkbreeze:/app/data ./backup-$(date +%F)
docker compose start linkbreeze

أوقف الحاوية أولاً، لأن نسخ قاعدة بيانات SQLite أثناء كتابة عملية إليها قد يلتقط معاملة غير مكتملة، وعندها تُفتح النسخة كملف تالف. تصبح الصفحة غير متاحة أثناء تنفيذ النسخ. والاستعادة هي العملية نفسها بالعكس:

docker compose stop linkbreeze
docker compose cp ./backup-2026-08-14/. linkbreeze:/app/data
docker compose start linkbreeze
docker compose logs -f linkbreeze

توفّر لوحة التحكم أيضاً عملية تصدير بتنسيق JSON، من /api/backup على هيئة linkbreeze-backup-YYYY-MM-DD.json. ويتضمن التصدير الملف التعريفي والروابط والإعدادات والقوالب المحفوظة. ولا يتضمن سجل التحليلات أو مشتركي البريد الإلكتروني أو الصور المرفوعة، كما أن استعادته تحذف الصفوف الحالية في هذه الجداول الأربعة قبل إدراج صفوف الملف. تعامل معه كنسخة من الإعدادات عند نقل الاستضافة أو التراجع عن خطأ في التحرير. أما نسخة وحدة التخزين فهي النسخة الاحتياطية.

تنطبق هنا قاعدتا تخزين كما تنطبقان في أي مكان آخر عند تشغيل SQLite في بيئة إنتاج على VPS. احتفظ بقاعدة البيانات على قرص محلي، لأن آلية القفل في SQLite غير موثوقة على نظام ملفات شبكي، وستعرف ذلك عند تلف إحدى الصفحات. وإذا استبدلت وحدة التخزين المسماة بعملية ربط لمجلد من المضيف، فنفّذ chown على مجلد المضيف أولاً: تعمل الحاوية بالمستخدم غير الجذر node، ومعرّفه 1000 في node:22-alpine، ولا يكون المجلد الذي أنشأه root قابلاً للكتابة من هذا المستخدم، لذلك لا يستطيع التطبيق فتح قاعدة البيانات وتخرج الحاوية عند بدء التشغيل. يشرح استخدام عمليات الربط مع وحدات التخزين المسماة في Compose هذا المفاضلة بالكامل.

التحليلات ولافتة الموافقة التي لا تحتاج إليها

هذه هي الميزة التي تبرر استضافة صفحة ذاتياً، بينما يمكنك الحصول عليها مجاناً من مكان آخر.

التحليلات لا تستخدم ملفات تعريف الارتباط. لا يُنشأ أي ملف تعريف ارتباط للزائر، ولا يُحمَّل أي برنامج نصي تابع لجهة خارجية على الصفحة العامة. يُعرَّف الزائر باستخدام تجزئة SHA-256 لعنوان IP وسلسلة وكيل المستخدم وقيمة salt، ثم تُقتطع النتيجة إلى 16 حرفاً سداسياً عشرياً. وتكون قيمة salt نفسها تجزئة للتاريخ الحالي بتوقيت UTC ولـ SECRET_KEY، لذلك تتغير عند منتصف الليل بتوقيت UTC، ولا يمكن مطابقة تجزئات الأمس بتجزئات اليوم. لا يُكتب عنوان IP الخام في قاعدة البيانات مطلقاً.

تُحتسب النقرات على الخادم. يشير كل رابط http في الصفحة العامة إلى /go/<id> على نطاقك، حيث تُسجَّل النقرة ثم يُرسَل رد بإعادة توجيه 302 إلى الوجهة الفعلية. لذلك يعمل احتساب النقرات لدى القراء الذين عطّلوا JavaScript، وكذلك داخل المتصفحات المضمّنة في التطبيقات التي تحظر الطلبات في الخلفية. وتُسجَّل مشاهدات الصفحة عبر /api/track.

هناك استثناءان تجدر معرفتهما. يُتخطى أي طلب يتضمن جلسة admin صالحة، لذلك لا تؤدي عملية تحرير صفحتك إلى زيادة الأرقام. كما يُتخطى وكلاء المستخدم المعروفون للزواحف.

أما الموافقة، فلا يُخزَّن أي شيء على جهاز القارئ، وملف تعريف الارتباط المخزَّن على جهاز القارئ هو تحديداً الشيء الذي تطلب لافتة ملفات تعريف الارتباط الإذن بشأنه. مع ذلك، تعتمد التزاماتك على أماكن إقامة قرائك، لذا تحقّق منها، لكن لا يوجد هنا ملف تعريف ارتباط للتتبع يجب الإفصاح عنه، ولا جهة خارجية تتلقى البيانات.

هناك ملاحظة قد تفاجئ البعض: عند تدوير SECRET_KEY تتغير قيمة salt اليومية معها، لذلك يُحتسب كل زائر عائد بوصفه زائراً جديداً منذ تلك اللحظة.

لماذا يكون عمود الدولة فارغاً في التحليلات؟

لأن أياً من مكونات حزمة البرامج لديك لا يضبط ترويسة الدولة. يستخرج LinkBreeze الدولة من ترويسات الوكيل مثل cf-ipcountry وx-vercel-ip-country. عند تشغيله على VPS خلف Caddy أو Nginx الخاص بك، لا تكون أي من هذه الترويسات موجودة، لذلك تُسجَّل الدولة كقيمة null ويبقى التقسيم فارغاً. لا توجد قاعدة بيانات GeoIP داخل الحاوية.

هناك طريقتان لملء العمود. ضع Cloudflare أمام النطاق، إذ يضيف cf-ipcountry إلى كل طلب يمرره. أو اضبط إحدى هذه الترويسات في الـreverse proxy الخاص بك باستخدام بحث GeoIP محلي.

المشكلة المرتبطة بذلك أخطر، فتحقق منها. تقرأ معالجات النقرات وعمليات العرض عنوان العميل من X-Forwarded-For أولاً، ثم X-Real-IP، وتستخدم 0.0.0.0 كقيمة احتياطية عند غياب الترويستين. إذا نشرت المنفذ 3000 مباشرة على الإنترنت من دون proxy أمامه، فسيُحوَّل كل زائر إلى القيمة نفسها بعد التجزئة. وهذا يعني أن عدد الزوار الفريدين سيبقى 1 إلى الأبد، وأن حد المعدل لكل IP، والبالغ 60 حدثاً في الدقيقة، سيُطبَّق على جمهورك بأكمله دفعة واحدة. عند وجود توجيه reverse_proxy المذكور أعلاه، يضبط Caddy الترويسة نيابةً عنك وتختفي المشكلتان.

الاستيراد من Linktree وما لا ينتقل

يقبل معالج الترحيل في لوحة التحكم عنوان URL لملف شخصي عام أو ملفاً مُصدَّراً. ويتعرّف على صفحات linktr.ee وbento.me وlnk.bio وtap.link وhopp.bio وbeacons.ai وsolo.to وlinkfly وmssg.me وLittleLink، إضافةً إلى ملفات HTML وJSON المُصدَّرة العامة. عند استخدام عنوان URL من Linktree أو Bento، يقرأ معالج الترحيل بيانات JSON ‏__NEXT_DATA__ التي تضمّنها تلك الصفحات. أما الصفحة الثابتة، فيقرأ وسوم الارتباط فيها.

ينتقل عنوان كل رابط وعنوان URL الخاص به ووصفه وصورته، وما إذا كان الرابط يشير إلى ملف شخصي اجتماعي، إضافةً إلى اسم العرض والنبذة والصورة الرمزية. يمكنك اختيار الروابط التي تريد الاحتفاظ بها من بين الروابط التي عثر عليها المعالج قبل كتابة أي شيء في قاعدة البيانات.

لا تنتقل بيانات سجل التحليلات، أو النسق والتخطيط، أو مشتركو البريد الإلكتروني، أو تواريخ النشر المجدولة، أو أي محتوى تُبقيه المنصة القديمة خلف تسجيل الدخول الخاص بها. خطط لإعادة إنشاء المظهر يدوياً، وتقبّل بقاء سجل النقرات القديم في الخدمة القديمة.

يجلب المستورد عنوان URL من خادمك، وليس من متصفحك، ولذلك يرفض العناوين غير العامة. يعني Private/local URLs are not allowed أنك قدّمت عنواناً داخل شبكتك الخاصة، وهذا الرفض مقصود: لولاه، لأمكن لأي شخص لديه صلاحية الوصول إلى لوحة التحكم استخدام خادمك لفحص أجهزة لا يستطيع الوصول إليها إلا خادمك. والرسائل الأخرى التي قد تراها هي Only http and https URLs are allowed وRequest timed out وResponse too large.

يعتمد استخراج البيانات على بنية HTML يحددها طرف آخر. إذا لم يعثر المعالج على شيء في صفحة تحتوي بوضوح على روابط، فهذا يعني أن تلك المنصة غيّرت HTML منذ كتابة محلل الصفحة. أضف الروابط يدوياً بدلاً من انتظار الإصلاح. وإذا كان ما تريده فعلياً هو روابط مختصرة قابلة للقياس بدلاً من صفحة ملف شخصي، فإن أداة تقصير عناوين URL مستضافة ذاتياً مثل Shlink تنفّذ هذه المهمة وتعمل بسهولة على الخادم نفسه.

تحديث عملية نشر مثبتة

# edit the image tag in docker-compose.yml, then
docker compose pull
docker compose up -d
docker compose logs -f linkbreeze

تُشغَّل عمليات ترحيل المخطط تلقائياً عند بدء تشغيل الحاوية. لا توجد طريقة موثقة لتنفيذها بالعكس، لذلك أنشئ نسخة من الـvolume أولاً. لا يكون التحديث الذي لا يمكنك التراجع عنه آمناً إلا إذا كان بإمكانك استعادة الحالة السابقة.

تعرض لوحة التحكم شريطاً عند توفر إصدار أحدث. تتحقق من ذلك بجلب ملف إصدار صغير من مستودع المشروع على GitHub مرة واحدة كل 24 ساعة، ولا ترسل أي معلومات عن مثيلك. اقرأ ملاحظات الإصدار قبل تغيير الـtag، لأن الإصدار الثانوي في هذه المرحلة من المشروع قد يغيّر الإعدادات الافتراضية التي تعتمد عليها.

أوضاع الفشل والعبارات التي ستظهر لك

manifest unknown عند السحب. كُتبت العلامة بالشكل :v1.2.7. لا تحتوي علامات السجل على v، لذا استخدم :1.2.7.

no matching manifest for linux/arm64/v8 in the manifest list entries. الصورة المنشورة مخصّصة لـ amd64 فقط. أنشئها على مضيف ARM من المصدر ذي العلامة.

تُبلغ الحاوية عن unhealthy بينما تُحمَّل الصفحة بشكل سليم. يستدعي فحص الصحة في ملف compose لديك curl، لكن الصورة لا تحتوي عليه. احذفه ودَع فحص الصحة wget المضمّن في الصورة يعمل.

يقدّم Caddy خطأ في الشهادة، أو لا يقدّم شيئاً على الإطلاق. تحقّق من docker compose logs caddy. السبب المعتاد هو أن سجل A لا يشير إلى VPS هذا بعد، أو أن المنفذ 80 مغلق في جدار الحماية، مما يمنع تحدي HTTP الخاص بـ ACME (بيئة إدارة الشهادات تلقائياً) الذي يستخدمه Caddy لإثبات تحكمه في النطاق.

يبقى عدد الزوار الفريدين عند 1. لا يضبط أي Proxy القيمة X-Forwarded-For، لذلك ينتج كل زائر قيمة hash متطابقة.

تخرج الحاوية مباشرة بعد بدء التشغيل، رغم أنها كانت تعمل أمس. إذا انتقلت من volume مسمّى إلى bind mount على المضيف، فإن مجلد البيانات مملوك لـ root، بينما يعمل التطبيق بالمعرّف uid 1000، ولذلك لا يستطيع فتح ملف قاعدة البيانات. sudo chown -R 1000:1000 مجلد المضيف.

أُجيب عن طلبات التتبع برمز HTTP 429. تم بلوغ حد الطلبات لكل IP على /api/track و/go/<id>. ما زال الزوار يُعاد توجيههم إلى وجهتهم، لكن النقر لا يُحتسب.

FAQ

هل LinkBreeze جاهز لاستخدامه كرابط عام في السيرة الذاتية؟

إنه مشروع حديث. اعتباراً من August 2026، يحتوي المستودع على 178 نجمة و17 تفرعاً ومشرف واحد، ويعود تاريخ الإصدار الأول إلى 1 July 2026. تصدر الإصدارات أكثر من مرتين أسبوعياً في المتوسط، لذلك تُصلح الأخطاء بسرعة، لكن السلوك يتغير بسرعة أيضاً. تتيح لك رخصة MIT وملف SQLite المحلي الاحتفاظ بصفحة تعمل حتى إذا توقف التطوير، لكن تطبيق ويب عاماً من دون إصلاحات أمنية يتحول إلى مسؤولية، لذلك تعامل معه كبرنامج ستواصل تحديثه، لا كبرنامج تثبته مرة واحدة.

ما وسم صورة LinkBreeze الذي ينبغي أن أشغّله؟

شغّل وسم الإصدار، مثل ghcr.io/manak-hash/linkbreeze:1.2.7، وغيّره عن قصد. تدفع عملية الإصدار latest ورقم الإصدار المجرد فقط، لذلك لا يوجد :v1.2.7 مع v، ويرد Docker بالخطأ manifest unknown. الصورة مبنية لـ linux/amd64 فقط، لذلك يجب عليك على VPS بمعمارية arm64 استنساخ الوسم وبناؤه محلياً.

لماذا يظل توزيع البلدان فارغاً في تحليلات LinkBreeze؟

يقرأ LinkBreeze بلد الزائر من رؤوس الوكيل مثل cf-ipcountry أو x-vercel-ip-country، ولا يتضمن قاعدة بيانات GeoIP خاصة به. لا يضبط VPS خلف Caddy أو Nginx الخاص بك أياً من هذه الرؤوس، لذلك يُخزَّن البلد بقيمة null. ضع Cloudflare أمام النطاق، أو اجعل الـreverse proxy يضبط أحد هذه الرؤوس بالاعتماد على عملية بحث GeoIP محلية.

ما الذي ينبغي أن أنشئ له نسخة احتياطية تحديداً، وكيف أستعيده؟

أنشئ نسخة احتياطية من وحدة التخزين linkbreeze-data بأكملها، وليس من ملف قاعدة البيانات فقط. يحتوي /app/data/linkbreeze.db على كل الروابط والصفحات والإعدادات والمشتركين وصفوف التحليلات، بينما يحتوي /app/data/uploads على صور avatar وthumbnail التي تشير إليها الصفحة. أوقف الحاوية، ونفّذ docker compose cp linkbreeze:/app/data ./backup-$(date +%F)، ثم شغّلها مجدداً. للاستعادة، انسخ الدليل مرة أخرى إلى الحاوية المتوقفة ثم شغّلها. إن تصدير JSON من لوحة التحكم هو لقطة إعدادات للملف الشخصي والروابط والإعدادات والسمات، ولا يتضمن التحليلات أو الصور.

هل ينقل الاستيراد من Linktree تحليلاتي وسمتي أيضاً؟

لا. يقرأ معالج الترحيل عناوين الروابط وعناوين URL والأوصاف والصور من ملفك الشخصي العام القديم، إضافة إلى اسم العرض والنبذة وصورة avatar. تبقى محفوظات التحليلات والسمة والمشتركون عبر البريد الإلكتروني وتواريخ النشر المجدولة في المنصة القديمة. أعد إنشاء المظهر في محرر السمات بعد الاستيراد، وتوقع أن تظل محفوظات النقرات في المنصة القديمة.