دليل النشر

نشر Keycloak لتسجيل الدخول الموحّد (SSO) على خادمك VPS

انشر على VPS Cloud ←

دليل عملي

الأمان والمراقبة

نشر Keycloak لتسجيل الدخول الموحّد (SSO) على خادمك VPS

يُعدّ Keycloak المرجع مفتوح المصدر لتسجيل الدخول الموحّد على مستوى المؤسسات، وهو مدعوم من Red Hat ويُستخدم حتى في البيئات الخاضعة لتنظيم صارم. بفضل realms الخاصة به واتحاد LDAP ودعمه الكامل لـ OIDC وSAML، فإنه يلبّي احتياجات لا يبلغها إلا القليل من مزوّدي الهوية (IdP). وعند استضافته ذاتيًا على خادم VPS، يمنحك هذا المستوى من الاحترافية دون أي ترخيص أو اعتماد على السحابة.

10 دقائق للقراءةعدد الخطوات: 15
المحتويات· لماذا تنشر Keycloak على خادمك VPS1/13
  1. 01لماذا تنشر Keycloak على خادمك VPS
  2. 02مزايا Keycloak المستضاف ذاتيًا
  3. 03المتطلبات المسبقة لهذا النشر
  4. 04نشر Keycloak مع PostgreSQL
  5. 05صورة مُحسَّنة مسبقًا: فصل البناء عن التشغيل
  6. 06بناء صورة مُحسَّنة مسبقًا وتشغيلها
  7. 07Keycloak أم Authentik: أيّهما تختار؟
  8. 08النسخ الاحتياطي والترحيل دون فقدان أي realm
  9. 09قائمة تحقق للتشغيل
  10. 10استكشاف الأخطاء: فشل التشغيل مع نظام ملفات للقراءة فقط
  11. 11رسائل الخطأ التي ينبغي التعرف عليها
  12. 12الحل البديل المُبلَّغ عنه في Docker Compose
  13. 13القراءة فقط: تحصين لا توثّقه الجهة المطوّرة

لماذا تنشر Keycloak على خادمك VPS

حيث تسعى بعض مزوّدات الهوية (IdP) إلى البساطة، يسعى Keycloak إلى الشمولية: عزل متعدد المستأجرين عبر realms، واتحاد أدلة LDAP/Active Directory، والوساطة (brokering) نحو مزوّدين خارجيين (Google وGitHub أو OIDC آخر)، وتخصيص كامل لمظهر صفحات تسجيل الدخول، وتفويض دقيق (fine-grained authorization). وبالنسبة إلى وكالة تدير عدة عملاء أو نظام معلومات ذي متطلبات امتثال، فإن هذا المستوى من التحكّم حاسم. تجنّبك الاستضافة الذاتية على خادم VPS التكاليف لكل مستخدم في عروض IdP المُدارة، وتُبقي قاعدة الهويات بأكملها ضمن نطاق سلطتك القضائية، وهي نقطة بالغة الأهمية للبيانات الحساسة التي لا ترغب في تسليمها إلى طرف ثالث.

مزايا Keycloak المستضاف ذاتيًا

  • realms متعددة لعزل عدة عملاء أو بيئات عزلًا كاملًا على نفس النسخة (instance) الواحدة.
  • دعم أصلي وكامل لـ OpenID Connect وOAuth2 وSAML 2.0.
  • اتحاد LDAP / Active Directory لإعادة استخدام دليل قائم دون عملية ترحيل.
  • الوساطة في الهوية (Identity brokering): تسجيل الدخول عبر Google أو GitHub أو أي IdP خارجي ببضع نقرات.
  • صفحات تسجيل دخول قابلة للتخصيص بالكامل (السمات، اللغات، الهوية البصرية لكل realm).
  • سياسات مصادقة دقيقة: مصادقة متعددة العوامل (MFA) مشروطة، ومدة الجلسة، وقيود حسب الدور.

المتطلبات المسبقة لهذا النشر

يعمل Keycloak على الآلة الافتراضية لجافا JVM (على Quarkus منذ الإصدار v17+) ويظل أكثر استهلاكًا للموارد من مزوّد هوية خفيف. خصّص خادم VPS بـ 2 vCPU و4 غيغابايت من RAM كحدّ أدنى، ويُفضَّل 6 غيغابايت إذا كنت تتوقّع حِملًا أو عدة realms نشطة. يُوصى بشدّة باستخدام قاعدة PostgreSQL خارجية في بيئة الإنتاج (لا تستخدم أبدًا قاعدة H2 المدمجة خارج نطاق الاختبارات). ويكتمل ما يلزم بوجود Docker وDocker Compose ونطاق مخصّص (sso.mydomain.com) ووكيل عكسي (reverse proxy) يتولّى SSL، لأن Keycloak يحتاج إلى إعلامه بأنه يُقدَّم خلف وكيل HTTPS.

نشر Keycloak مع PostgreSQL

  1. تعريف Keycloak وPostgreSQL في Compose

    في ملف docker-compose.yml، عرّف خدمة postgres (الصورة postgres:16) وخدمة keycloak (الصورة quay.io/keycloak/keycloak). اربط Keycloak بقاعدة البيانات عبر KC_DB=postgres وKC_DB_URL وKC_DB_USERNAME وKC_DB_PASSWORD.

  2. تهيئة وضع الإنتاج والوكيل

    شغّل باستخدام الأمر start (وليس start-dev). عيّن KC_HOSTNAME=sso.mydomain.com وKC_PROXY_HEADERS=xforwarded حتى يُنشئ Keycloak عناوين URL صحيحة خلف الوكيل العكسي. وحدّد المسؤول الأولي عبر KC_BOOTSTRAP_ADMIN_USERNAME / KC_BOOTSTRAP_ADMIN_PASSWORD.

  3. البدء وإتمام عملية البناء (build)

    نفّذ docker compose up -d. عند التشغيل الأول، يُجري Keycloak عملية بناء Quarkus مُحسّنة ثم يُرحّل مخطّط PostgreSQL. تابِع docker compose logs -f keycloak حتى تظهر الرسالة التي تشير إلى أن الخادم في وضع الاستماع.

  4. إعداد الوكيل العكسي مع SSL

    وجّه sso.mydomain.com إلى المنفذ 8080 في حاوية Keycloak عبر Caddy أو Traefik أو Nginx، مع شهادة Let's Encrypt. واحرص على تمرير ترويسات X-Forwarded-* وإلا فستتعطّل عمليات إعادة التوجيه عند تسجيل الدخول.

  5. إنشاء realm وعميل (client)

    سجّل الدخول إلى وحدة تحكّم المسؤول، وأنشئ realm مخصّصًا (لا تستخدم أبدًا realm master لتطبيقاتك)، ثم عميل OIDC. اضبط قيمة Valid redirect URIs لتطبيقك، واحصل على Client ID والسرّ من تبويب Credentials.

  6. ربط تطبيق واختبار التدفّق (flow)

    هيّئ تطبيقك باستخدام عنوان الاكتشاف https://sso.mydomain.com/realms/mon-realm/.well-known/openid-configuration. أنشئ مستخدمًا تجريبيًا في الـ realm، وابدأ عملية تسجيل دخول، وتحقّق من إصدار الرمز (token) في قسم Sessions بوحدة التحكّم.

صورة مُحسَّنة مسبقًا: فصل البناء عن التشغيل

افتراضيًا يتحقق الأمر start عند التشغيل مما إذا كانت مرحلة بناء Quarkus لازمة وينفّذها عند الحاجة: وهذا ما يُطيل التشغيل الأول، وهو ما يكتب داخل شجرة ملفات التثبيت. توصي وثائق الجهة المطوّرة بعكس ذلك في الحاويات: تنفيذ ‎kc.sh build أثناء بناء الصورة، ثم التشغيل بالأمر start --optimized. يُعلم المعامل --optimized برنامج Keycloak بأنه يعمل ضمن صورة مُحسَّنة مسبقًا وأن بإمكانه تخطي ذلك التحقق. أما خيارات البناء، مثل نوع قاعدة البيانات (db) أو تفعيل فحوص الصحة (health-enabled)، فتُثبَّت داخل الصورة: وإذا أُعيدت عند التشغيل بالقيمة نفسها تُتجاهل، وإذا أُعيدت بقيمة مختلفة تسبّبت في خطأ واستلزمت بناءً جديدًا. أما الأسرار، ومنها كلمة مرور القاعدة، فتنتمي إلى خيارات الإعداد وتبقى تُمرَّر وقت التشغيل.

بناء صورة مُحسَّنة مسبقًا وتشغيلها

  1. كتابة Dockerfile على مرحلتين

    تنطلق المرحلة الأولى من ‎quay.io/keycloak/keycloak وتُسمّى builder، وتضبط ENV KC_DB=postgres وENV KC_HEALTH_ENABLED=true، ثم تنفّذ ‎RUN /opt/keycloak/bin/kc.sh build. ثبّت رقم إصدار محددًا بدل latest ليبقى كل بناء جديد قابلًا للتكرار.

  2. نسخ الناتج إلى الصورة النهائية

    تنطلق المرحلة الثانية من الصورة نفسها وتنفّذ COPY --from=builder /opt/keycloak/ /opt/keycloak/. ضع القوالب والمزوّدات المخصّصة قبل البناء كي يأخذها التحسين في الحسبان. وإذا أضفت ملفات بالأمر COPY فأضف --chown=keycloak:keycloak ليتمكن Keycloak من الكتابة في المجلدات المعنية.

  3. التشغيل بالخيار المُحسَّن

    في Compose استبدل الأمر بـ start --optimized. وخلف وكيل عكسي ينهي TLS أضف KC_HTTP_ENABLED=true. تبقى المتغيرات KC_HOSTNAME وKC_PROXY_HEADERS وبيانات الوصول إلى القاعدة إعدادًا وقت التشغيل.

  4. ربط فحوص الصحة

    مع ضبط KC_HEALTH_ENABLED=true وقت البناء، تُقدَّم النقاط /health/started و/health/live و/health/ready على منفذ الإدارة 9000 المنفصل عن المنفذ 8080 الخاص بالتطبيق. لا تنشر هذا المنفذ على الإنترنت: استخدمه فقط في healthcheck الخاص بـ Compose أو في أدوات المراقبة لديك.

Keycloak أم Authentik: أيّهما تختار؟

مرّر الجدول أفقيًا

المعيارKeycloakAuthentik
حالة الاستخدام المستهدفةتسجيل دخول موحّد للمؤسسات، متعدد المستأجرين، الامتثالالاستضافة الذاتية، المختبر المنزلي (homelab)، الوكالات
البروتوكولاتOIDC, OAuth2, SAML, LDAPOIDC, OAuth2, SAML, LDAP, forward auth
Forward auth (الوكيل)غير أصلي (عبر إضافات)أصلي ومحوري في الأداة
استهلاك المواردمرتفع (JVM، 4 غيغابايت+ RAM)معتدل (2-4 غيغابايت RAM)
realms / المستأجرون المتعددونممتاز (realms معزولة)المستأجرون مدعومون، لكن بشكل أقل تطوّرًا
تخصيص التدفّقات (flows)السمات وواجهة SPI بجافاتدفّقات مرئية على شكل خطوات
منحنى التعلّمحادّ، وشامل جدًاأيسر منالًا
اتحاد الأدلةناضج (LDAP/AD)جيّد (LDAP)

النسخ الاحتياطي والترحيل دون فقدان أي realm

تقع حالة Keycloak في مكانين: قاعدة PostgreSQL، وملفات الإعداد لديك (القوالب والمزوّدات وملفات الاستيراد). النسخة المرجعية هي pg_dump مجدول تُنسخ نتيجته خارج الـ VPS؛ جرّب الاستعادة على نسخة مؤقتة، لأن نسخة لم تُستعَد قط تبقى مجرد فرضية. ويكمّل تصدير الـ realm هذا الترتيب دون أن يحل محله: ‎kc.sh export --dir <المجلد>، أو --realm my-realm لـ realm واحد، مع الخيار --users لاختيار استراتيجية تصدير المستخدمين. تنص الوثائق على أن الخادم يجب ألا يكون قيد التشغيل أثناء التصدير، وأن الاتساق لا يُضمن إلا مع إيقاف جميع العقد، وأن الأحداث والجلسات المحفوظة والرموز الملغاة لا تُصدَّر. وعند تجاوز 50 000 مستخدم صدّر إلى مجلد لا إلى ملف واحد. أما عند الاستيراد فيقرأ start --import-realm ملفات ‎.json الموجودة في المجلد /opt/keycloak/data/import ويتجاهل أي realm موجود مسبقًا.

قائمة تحقق للتشغيل

  • إصدار مثبَّت — ثبّت رقم إصدار الصورة، واقرأ ملاحظات الإصدار قبل تغيير الفرع الرئيسي، وأعد بناء الصورة المُحسَّنة عند كل ترقية.
  • قاعدة منسوخة احتياطيًا — pg_dump مجدول، ونسخة خارج الـ VPS، واستعادة مُجرَّبة على نسخة مؤقتة.
  • ذاكرة محدودة — حدّد دائمًا سقفًا لذاكرة الحاوية: تحسب JVM حجم الكومة (heap) منه، بنسبة 70 % كحد أقصى و50 % كحجم ابتدائي افتراضيًا.
  • فحوص مراقَبة — تابع /health/ready على المنفذ 9000 غير المنشور من أدوات المراقبة لديك.
  • ترويسات الوكيل تحت السيطرة — يجب أن يستبدل الوكيل العكسي ترويسات X-Forwarded-* الواردة من العميل لا أن يُضاف إليها، وألا يُتجاوز أبدًا.
  • الأحداث مفعَّلة — سجّل عمليات الدخول وإجراءات الإدارة في كل realm لمعرفة من دخل ومن عدّل ماذا.

استكشاف الأخطاء: فشل التشغيل مع نظام ملفات للقراءة فقط

غالبًا ما يمرّ تحصين الحاوية عبر read_only: true في Compose أو readOnlyRootFilesystem: true في Kubernetes. ومع Keycloak فالموضوع مفتوح منذ أبريل 2022 في المسألة رقم 11286 من المستودع keycloak/keycloak ("Keycloak does not work with Docker read_only: true")، وكانت لا تزال نشطة في نهاية أكتوبر 2026. المثبَت من جهة المشروع: أعاد أحد المساهمين في Keycloak إنتاج الفشل على الإصدار 19.0.2 في سبتمبر 2022، وصُنّفت المسألة تحسينًا بوسم "help wanted"، وأُضيفت إلى لوحة مشروع في المستودع في سبتمبر 2026. وغير المثبَت: لا تصف الوثائق الرسمية حتى اليوم أي وضع للقراءة فقط (صفحة الحاويات لا تذكره)، ولم يعتمد أي مشرف حلًّا بديلًا. الحلول أدناه صادرة عن مشاركين في النقاش؛ نجحت عندهم وفي إصداراتهم، دون ضمان بعد أي ترقية. وفي 26 أكتوبر 2026 عرض أحد المساهمين كتابة الوثائق الناقصة بعد التحقق بنفسه من هذه الحلول.

رسائل الخطأ التي ينبغي التعرف عليها

  • sed: couldn't open temporary file /opt/jboss/keycloak/bin/seduHoQM0: Read-only file system — رسالة التقرير الأول على صورة WildFly القديمة (الإصدار 16.1.1 في المسألة): الأمر sed -i في سكربت التشغيل لا يستطيع إنشاء ملفه المؤقت. أما في توزيعة Quarkus فتختلف الأعراض، انظر الأسطر التالية.
  • ‎KC-SERVICES0075: Failed to get theme request: java.lang.RuntimeException: Temporary directory /opt/keycloak/bin/../data/tmp does not exist and it was not possible to create it. — أُبلغ عنها أثناء الترقية إلى 20.0.1: يبدأ الخادم ثم يفشل عند أول صفحة تخدم قالبًا. وأفاد أحد المشاركين بأن تركيب وحدة تخزين قابلة للكتابة على /opt/keycloak/data/tmp يعالج هذه الحالة.
  • تشغيل بطيء أو فشل كتابة في /opt/keycloak/lib/quarkus — قارن أحد المشاركين الحاوية قبل التشغيل وبعده بالأمر docker diff: تتغير ثلاثة مجلدات هي /tmp و/opt/keycloak/data و/opt/keycloak/lib/quarkus. يحتوي الأخير على ناتج البناء الذي يعيد start توليده ما لم تكن الصورة مُحسَّنة مسبقًا.
  • مجلد data للقراءة فقط بعد COPY — يذكر أحد المشاركين أن نسيان --chown=keycloak:keycloak عند نسخ ملف realm يترك /opt/keycloak/data مملوكًا لـ root، فلا يستطيع Keycloak الكتابة فيه.
  • نسخ /opt/keycloak إلى وحدة تخزين عند التشغيل — حل بحاوية تهيئة أُبلغ عنه في Kubernetes: يعمل، لكن عدة مشاركين يخشون اضطرارهم إلى إعادة اختباره عند كل ترقية.

الحل البديل المُبلَّغ عنه في Docker Compose

  1. الانطلاق من الصورة المُحسَّنة مسبقًا

    أعد استخدام الصورة المبنية أعلاه. يُنفَّذ ‎kc.sh build وقت البناء: فلا يُعاد كتابة /opt/keycloak/lib/quarkus عند التشغيل، ويتم التشغيل بالأمر start --optimized.

  2. تعريف نظام الملفات للقراءة فقط

    أضف read_only: true إلى خدمة keycloak في ملف Compose. من دون أي تغيير آخر تفشل الحاوية: وهذا هو السلوك الذي تصفه المسألة.

  3. توفير المجلدات القابلة للكتابة

    ركّب tmpfs على /tmp ووحدة تخزين مؤقتة على /opt/keycloak/data. في التقرير القائم على صورة مُحسَّنة مسبقًا كفى هذان المجلدان؛ وعلى صورة غير مُحسَّنة أضاف مشاركون آخرون /opt/keycloak/lib/quarkus.

  4. إعادة ما كان داخل data

    تبدأ وحدة التخزين المؤقتة فارغة: فما كانت الصورة تضعه في هذا المجلد، ومنه data/import، لم يعد ظاهرًا فيه. وإذا كنت تستورد realms بالخيار --import-realm فركّب مجلدها بشكل منفصل للقراءة فقط.

  5. التحقق بفتح صفحة تسجيل الدخول

    نفّذ docker compose up -d ثم docker compose logs -f keycloak، ثم افتح صفحة تسجيل الدخول: أول طلب لقالب هو ما أفشل بعض التركيبات. واختم بـ docker diff لسرد ما كتبته الحاوية فعلًا.

القراءة فقط: تحصين لا توثّقه الجهة المطوّرة

احتفظ بهذا الوضع للبيئات التي تفرضه فيها سياسة، كتدقيق أمني أو قاعدة في العنقود، وتقبّل كلفته: إعداد غير موثَّق يجب إعادة اختباره عند كل ترقية، وهو ما يخشاه عدة مشاركين في المسألة. وعلى VPS واحد تعطي إجراءات أخرى مكسبًا أوضح بصيانة أقل: إسقاط قدرات Linux (cap_drop: [ALL])، والخيار no-new-privileges، وعدم نشر منافذ الإدارة، ووضع قاعدة PostgreSQL على شبكة Docker داخلية.

في بيئة الإنتاج، لا تُشغّل Keycloak أبدًا بقاعدة H2 المدمجة ولا تُتِح realm master للعموم: أنشئ realm مخصّصًا لكل تطبيق أو لكل عميل، واحتفظ بـ master للإدارة فقط. ولتحصين النسخة، عطّل التسجيل الحرّ، وفعّل brute force detection في Realm Settings > Security Defenses، وهيّئ كل شيء عبر ملفات استيراد realm (--import-realm) كي تُخضع تهيئتك لإدارة الإصدارات بدلًا من النقر في واجهة المستخدم.

ثبّت Keycloak على خادمك VPS

Keycloak متاح في Marketplace من ServOrbit: صورة رسمية وقاعدة بيانات PostgreSQL وHTTPS وحساب مسؤول جاهز عند التثبيت.