لنفرض أن لديك سيرفراً Server تعمل عليه خمس خدمات Services أو ست، فسوف تجد نفسك بعد فترة قصيرة تسأل أسئلة صغيرة ولكنها مزعجة: أين رابط لوحة المراقبة Monitoring؟ وما هو النطاق الفرعي Subdomain الخاص بقاعدة المعرفة Knowledge Base؟ وهل ال Container الخاص بـ Gitea يعمل الآن أصلاً؟ والحل الأول الذي يخطر على البال هو أن تحفظ هذه الروابط في المفضلة Bookmarks داخل المتصفح Browser، وهذا الحل يعمل في اليوم الأول، ولكنه يفشل بسرعة لأن المفضلة تبقى على جهازك وحدك فلا يراها زميلك، ولا تخبرك هل الخدمة تعمل أم متوقفة، فتضغط على الرابط ثم تكتشف أن ال Container متوقف منذ يومين.
لذلك فالحل الأنسب هو لوحة بداية Dashboard تجمع روابط خدماتك في صفحة واحدة يفتحها كل الفريق، وتعرض بجانب كل رابط حالته. ومن أشهر اللوحات مفتوحة المصدر Open Source Homarr وDashy وHomepage، وسوف نشرح في هذا الدليل Homepage، وهي صفحة سريعة تعرض بجانب كل خدمة حالتها Status واستهلاكها للموارد Resources، وتضيف في أعلاها أدوات صغيرة Widgets لموارد السيرفر والبحث والوقت، وتتكامل مع أكثر من مئة تطبيق عبر واجهاتها البرمجية APIs.
وقد يتساءل البعض: لماذا Homepage وليس Homarr أو Dashy؟ والإجابة أن إعداد Homepage كله ملفات YAML، ولا توجد فيها واجهة لتحرير اللوحة UI Editor، وهذا يعني أنك تحفظ هذه الملفات في Git وتراجعها وتنسخها نسخاً احتياطياً Backup كأي نص، وهو ما يناسب من يدير سيرفره بنفسه ويفضل أن يكون الإعداد كوداً Configuration as Code. أما إذا أردت لوحة يعدلها زملاء غير تقنيين بالسحب والإفلات Drag and Drop، فإن Homarr أقرب إلى حاجتك.
وتذكر أن Homepage تعمل دون تسجيل دخول Authentication في إعدادها الافتراضي، فكل من يصل إلى رابطها يرى خدماتك، لذلك فحمايتها مسؤوليتك كما سوف نشرح لاحقاً.
وسوف نناقش في هذا المقال ما يلي:
- تثبيت Homepage بملف Compose مع Socket Proxy للقراءة فقط، ولماذا لا نركب
/var/run/docker.sockداخلها مباشرة. - ملفات الإعداد الخمسة، ثم الاكتشاف التلقائي للخدمات عبر وسوم Docker، وأدوات الخدمات مع حماية مفاتيحها.
- الوصول عبر نطاق وحماية اللوحة، لأنها لا تطلب تسجيل دخول في إعدادها الافتراضي.
- التحقق من النجاح والنسخ الاحتياطي والتحديث وأشهر المشكلات وحلولها.
ما تحتاجه قبل أن تبدأ Requirements
- سيرفر عليه Docker وCompose، وإذا لم يكن مثبتاً فابدأ بدليل تثبيت Docker على Ubuntu.
- الموارد: تستهلك Homepage قرابة 120 ميجابايت من الذاكرة RAM، والـ Socket Proxy قرابة 25 ميجابايت، وهذا يعني أنها تعمل بجانب خدماتك دون أن تشعر بها.
- نطاق فرعي مثل
home.example.com، وReverse Proxy مثل Nginx Proxy Manager. - لا تحتاج إلى فتح أي منفذ Port على الإنترنت، والسبب أن الوصول كله يمر عبر ال Reverse Proxy.
تثبيت Homepage Installation
لماذا نضع Socket Proxy بدلاً من تركيب ال socket مباشرة؟
لكي تعرض Homepage حالة ال Containers فهي تحتاج إلى أن تسأل Docker عنها Query، والطريقة الأبسط التي تجدها في أغلب الأمثلة هي أن تركب Mount الملف /var/run/docker.sock داخلها، والمشكلة في هذه الطريقة أن من يصل إلى هذا الملف يستطيع أن يطلب من Docker إنشاء Container بصلاحيات Permissions حساب root على السيرفر، كما يشرح توثيق أمان Docker Security، وبالتالي تصبح أي ثغرة في اللوحة باباً إلى السيرفر كله. وقد تظن أن العلامة :ro تحل المشكلة، ولكنها لا تغير شيئاً هنا، والسبب أنها تمنع تعديل الملف نفسه ولا تمنع إرسال الأوامر عبره، بالإضافة إلى أن Homepage تحتاج عندها إلى العمل بـ root حتى تقرأ ال socket.
لذلك فالحل الأنسب أن نضع بينهما docker-socket-proxy، وهو Container صغير يركب ال socket ويقدم للشبكة الداخلية Internal Network واجهة Docker محدودة الصلاحيات، حيث نسمح فيه بقراءة ال Containers فقط (CONTAINERS=1) ونمنع كل طلبات الكتابة Write Requests (POST=0)، وهما الإعدادان اللذان يكفيان Homepage، أما SERVICES وTASKS التي تراها في أمثلة التوثيق فلا تحتاج إليها إلا في Docker Swarm. وبما أن Homepage لا تتصل بال socket مباشرة، فنستطيع تشغيلها بمستخدم عادي Non-root User وليس بـ root.
ملف Compose
الآن سوف نقوم بإنشاء مجلد الإعداد ونجعله ملكاً للمستخدم 1000:
sudo mkdir -p /opt/homepage/config
sudo chown -R 1000:1000 /opt/homepage/config
cd /opt/homepageثم أنشئ الملف /opt/homepage/compose.yaml كما يلي، حيث إن الشبكة proxy هي الشبكة الخارجية External التي يعمل عليها ال Reverse Proxy، وإذا لم تكن موجودة فأنشئها بالأمر docker network create proxy، أما الشبكة internal فهي شبكة داخلية بين Homepage وال Socket Proxy فقط ولا تتصل بالإنترنت:
services:
dockerproxy:
image: tecnativa/docker-socket-proxy:v0.5.0
container_name: homepage-dockerproxy
restart: unless-stopped
environment:
CONTAINERS: 1
POST: 0
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- internal
homepage:
image: ghcr.io/gethomepage/homepage:v2.4.0
container_name: homepage
restart: unless-stopped
environment:
HOMEPAGE_ALLOWED_HOSTS: home.example.com
PUID: 1000
PGID: 1000
volumes:
- ./config:/app/config
networks:
- internal
- proxy
depends_on:
- dockerproxy
networks:
internal:
internal: true
proxy:
external: trueفي الإعداد أعلاه لاحظ التالي:
- المتغير
HOMEPAGE_ALLOWED_HOSTSإلزامي منذ الإصدار 1.0 حتى تفتح اللوحة باسم غير localhost، وتكتب فيه أسماء المضيف Hostnames التي تفتح بها اللوحة مفصولة بفواصل دون مسافات، مع المنفذ إن وجد، وأي اسم آخر ترفضه Homepage بالرمز400، والسبب أن هذا الفحص يحمي واجهتها الداخلية من هجمات DNS rebinding. ولاحظ أنlocalhost:3000و127.0.0.1:3000مسموحان دائماً، لذلك لا تحتاج إلى إضافتهما للاختبار المحلي Local Testing. - المتغيران
PUIDوPGIDيشغلان العملية Process بالمستخدم 1000 وليس بـ root، ولهذا جعلنا مجلد الإعداد ملكاً لهذا المستخدم، ولاحظ أن Homepage تصحح ملكية المجلد بنفسها عند التشغيل وتكتب ذلك في السجل بالعبارةFixing ownership of /app/config. - ثبتنا الوسم Tag بالرقم الكامل بدلاً من
latestالذي تستخدمه أمثلة التوثيق، والسبب أن الإصدار لن يتغير دون علمك عند أولdocker compose pull. - لم ننشر أي منفذ لا لـ Homepage ولا لل Socket Proxy، فالوصول إلى اللوحة عبر ال Reverse Proxy فقط، وال Socket Proxy لا يراه أحد غير Homepage على الشبكة
internal. وفي ال Image فحص صحة Healthcheck جاهز على المسار/api/healthcheck.
بعد ذلك شغل الخدمة وراجع السجل Log:
docker compose up -d
docker compose ps
docker compose logs --tail 20 homepageوالمخرج سوف يكون كما يلي:
NAME STATUS
homepage Up 30 seconds (healthy)
homepage-dockerproxy Up 31 seconds
...
✓ Ready in 0ms
[info]: settings.yaml was copied to the config folderوفي التشغيل الأول تنسخ Homepage ملفات إعداد نموذجية إلى config/، وسوف نضع ملفاتنا مكانها في القسم التالي.
ملفات الإعداد Configuration Files
كل ملف مسؤول عن جزء من الصفحة، وتقرأ Homepage الملفات من جديد كلما حدثت الصفحة، وبالتالي لا تحتاج إلى إعادة تشغيل Restart ال Container بعد كل تعديل. والشكل التالي يبين النتيجة التي سوف نصل إليها:

settings.yaml: العنوان والسمة وترتيب المجموعات
نبدأ بالملف الذي يحدد عنوان الصفحة Title وسمتها Theme وتخطيطها Layout:
title: بوابة الفريق
theme: dark
color: slate
headerStyle: boxed
statusStyle: dot
layout:
Applications:
style: row
columns: 3
Infrastructure:
style: row
columns: 3في الإعداد أعلاه لاحظ أن القسم layout يحدد ترتيب المجموعات وشكلها، والأسماء فيه يجب أن تطابق أسماء المجموعات في services.yaml حرفاً بحرف.
docker.yaml: الاتصال بـ Docker
في هذا الملف نعرف خادم Docker باسم نستخدمه في بقية الملفات، ونوجهه إلى ال Socket Proxy باسم ال Container الخاص به على الشبكة الداخلية، كما في توثيق إعداد Docker:
my-docker:
host: dockerproxy
port: 2375وإذا فضلت تركيب ال socket مباشرة في ال Container الخاص بـ Homepage، وقبلت المخاطرة التي شرحناها وتشغيلها بـ root، فاكتب socket: /var/run/docker.sock مكان host وport، ولكننا لا ننصح بذلك. ولإضافة سيرفر ثان، أضف تعريفاً آخر يشير إلى Socket Proxy على ذلك السيرفر عبر شبكة خاصة Private Network، ولا تنشر المنفذ 2375 على عنوان عام، والسبب أن أي منفذ يجيب عن Docker API هو نافذة على كل ما يعمل في السيرفر.
services.yaml: الخدمات
هذا الملف مقسم إلى مجموعات، وفي كل مجموعة عدد من الخدمات، ولكل خدمة اسم ورابط ووصف Description وأيقونة Icon، وتستطيع ربطها بـ Container حتى تعرض حالته:
- Applications:
- Git:
href: https://git.example.com
description: مستودعات الشيفرة
icon: gitea.svg
- Wiki:
href: https://wiki.example.com
description: قاعدة معرفة الفريق
icon: outline.svg
- Infrastructure:
- Portainer:
href: https://portainer.example.com
description: إدارة الحاويات
icon: portainer.svg
- Nginx Proxy Manager:
href: https://npm.example.com
description: النطاقات والشهادات
icon: nginx-proxy-manager.svg
- Homepage:
href: https://home.example.com
description: هذه اللوحة
icon: homepage.png
server: my-docker
container: homepageفي الإعداد أعلاه لاحظ التالي:
- الأيقونات: إذا كتبت اسم ملف مثل
gitea.svgفسوف تجلبه Homepage من مجموعة dashboard-icons، وهي تقبل أيضاً البادئة Prefixmdi-لأيقونات Material Design، والبادئةsi-لأيقونات Simple Icons (مثلsi-github)، أو رابطاً كاملاً لملف أيقونة. وانتبه إلى الامتداد Extension، والسبب أن بعض الأيقونات متوفر بصيغةpngفقط، ومنها أيقونة Homepage نفسها. - server وcontainer: هذان الحقلان يربطان البطاقة Card بـ Container، فتظهر شارة الحالة Badge (
RUNNING، أوHEALTHYإذا كان لل Container فحص صحة)، ومعها زر يعرض استهلاك المعالج CPU والذاكرة والشبكة.

الاكتشاف التلقائي للخدمات Auto Discovery بوسوم Docker
كتابة كل خدمة في services.yaml تعمل جيداً عندما تكون الخدمات قليلة، ولكنك سوف تنسى مع الوقت أن تحذف خدمة أزلتها أو تضيف خدمة جديدة، فتصبح اللوحة غير مطابقة لما يعمل فعلاً. لذلك تستطيع الخدمة أن تعلن عن نفسها بوسوم Labels في ملف Compose الخاص بها، فتظهر في اللوحة ما دامت تعمل وتختفي عندما تحذفها. لنأخذ مثالاً بالتطبيق whoami، حيث أضفنا إليه الخيار siteMonitor الذي يطلب الرابط بشكل دوري ويعرض زمن الاستجابة Latency:
services:
whoami:
image: traefik/whoami:v1.11.0
container_name: whoami
restart: unless-stopped
labels:
homepage.group: Applications
homepage.name: Whoami
homepage.icon: traefik.svg
homepage.href: https://whoami.example.com
homepage.description: تطبيق اختبار الوكيل
homepage.server: my-docker
homepage.container: whoami
homepage.siteMonitor: http://whoami:80
networks:
- homepage_internal
networks:
homepage_internal:
external: trueفي الإعداد أعلاه لاحظ التالي:
- الوسمان
homepage.serverوhomepage.containerاختياريان هنا، والسبب أن Homepage تستنتجهما تلقائياً من ال Container الذي يحمل الوسوم، ولكننا كتبناهما للوضوح. - لكي يصل
siteMonitorإلى ال Container باسمه، يجب أن يكون ال Container على شبكة تصل إليها Homepage، واسم الشبكة الداخلية من ملفنا يصبحhomepage_internal، لأن Compose يضيف اسم المشروع Project Name في أوله. وإذا كان الرابط العام يعمل، فيكفيكsiteMonitor: https://whoami.example.comدون مشاركة الشبكة. - في لقطة الشاشة Screenshot الأولى سوف ترى بطاقة Whoami وعليها
3 MSوRUNNING.
widgets.yaml: أدوات المعلومات
هذا الملف يحدد الشريط العلوي في الصفحة، وفيه موارد السيرفر وصندوق البحث Search Box والتاريخ والوقت:
- resources:
cpu: true
memory: true
disk: /
- search:
provider: duckduckgo
target: _blank
- datetime:
text_size: xl
format:
timeStyle: short
dateStyle: longولاحظ أن أداة resources تقيس الموارد كما يراها ال Container، فالقرص / هنا هو نظام الملفات Filesystem الخاص بال Container، وغالباً هو قرص Docker على السيرفر. ولكي تقيس قرص بيانات آخر، قم بتركيبه في ال Container للقراءة فقط Read-only (مثل /srv:/srv:ro)، ثم اكتب disk: /srv.
bookmarks.yaml: الإشارات المرجعية
وهنا تضع الروابط التي كنت تحفظها في مفضلة المتصفح، ولكنها الآن في مكان يراه كل الفريق:
- Docs:
- Docker:
- abbr: DK
href: https://docs.docker.com/
- Ubuntu Server:
- abbr: UB
href: https://ubuntu.com/server/docs
- Community:
- ArabRoot:
- abbr: AR
href: https://example.com/
- GitHub:
- icon: github.svg
href: https://github.com/وكل إشارة تحمل اختصاراً Abbreviation من حرفين (abbr) أو أيقونة.
أدوات الخدمات Service Widgets والأسرار Secrets
لكل تطبيق مدعوم أداة تعرض أرقامه داخل البطاقة، مثل عدد ال Containers في Portainer أو عدد المضيفين في Nginx Proxy Manager، وتحتاج الأداة عادة إلى رابط داخلي ومفتاح API. ولا تكتب المفاتيح في YAML مباشرة، والسبب أن ملفات YAML تذهب إلى Git وإلى النسخ الاحتياطية، وإنما مررها كمتغيرات بيئة Environment Variables تبدأ بـ HOMEPAGE_VAR_، ثم أشر إليها بين قوسين مزدوجين. والمثال التالي من التوثيق الرسمي لأداة Portainer:
- Portainer:
href: https://portainer.example.com
icon: portainer.svg
widget:
type: portainer
url: https://portainer:9443
env: 1
key: "{{HOMEPAGE_VAR_PORTAINER_KEY}}"بعد ذلك أضف في compose.yaml السطر HOMEPAGE_VAR_PORTAINER_KEY: ${PORTAINER_KEY} تحت environment، وضع القيمة في ملف .env بالصلاحية 600، وأنشئ للأداة مستخدماً أو مفتاحاً بصلاحية قراءة فقط، والسبب أن هذا المفتاح سوف يكون محفوظاً في اللوحة، فإذا تسرب فلن يستطيع من يملكه أن يغير شيئاً.
وتتكيف اللوحة مع شاشة الهاتف Mobile تلقائياً، فتصطف المجموعات عمودياً كما في الشكل التالي:

الوصول عبر نطاق Domain وحماية اللوحة
أنشئ في Nginx Proxy Manager مضيفاً Proxy Host للنطاق home.example.com يوجه الطلبات Requests إلى http://homepage:3000، والسبب أن ال Containers الاثنين على الشبكة proxy، ثم اطلب شهادة Certificate من Let's Encrypt وفعل Force SSL. بعد ذلك تأكد أن الاسم نفسه موجود في HOMEPAGE_ALLOWED_HOSTS، وإلا ظهرت لك صفحة فارغة أو الرمز 400.
وقد تسأل: ألا توجد في Homepage حماية خاصة بها؟ والإجابة أن الإصدار 2.0 أضاف بوابة دخول بسيطة بكلمة مرور أو عبر OIDC، ولكنها معطلة حتى تضيف المتغير HOMEPAGE_AUTH_ENABLED=true ومعه HOMEPAGE_AUTH_SECRET وHOMEPAGE_EXTERNAL_URL وكلمة المرور في HOMEPAGE_AUTH_PASSWORD. ويجدر الإشارة هنا أن التوثيق نفسه ما زال يوصي بوضع اللوحة خلف Reverse Proxy يفرض الدخول أو خلف VPN، والسبب أن هذه البوابة لا تحد من عدد محاولات كلمة المرور Rate Limiting، لذلك اعتبرها طبقة إضافية وليست بديلاً عن Forward Auth أو VPN.
كيف تتأكد أن كل شيء يعمل؟ Verification
- الأمر
docker compose psيعرض ال Containerhomepageبالحالةhealthy. - اللوحة تفتح على
https://home.example.com، والطلب باسم غير مسموح يعود بالرمز400، ويمكنك اختبار ذلك من Container على الشبكة نفسها بالأمرcurl -s -o /dev/null -w '%{http_code}' -H 'Host: other.example.net' http://homepage:3000/. - البطاقات المرتبطة بـ Containers تظهر بالحالة
RUNNINGأوHEALTHY، وإذا أوقفت Container للتجربة فسوف ترى الشارة تتغير. - العملية تعمل بمستخدم غير root، حيث يعرض الأمر
docker compose exec homepage ps -o user,commالمستخدمnodeأمامnext-server. - ال Socket Proxy يرفض طلبات الكتابة، ويمكنك أن تتأكد من ذلك من داخل ال Container الخاص بـ Homepage بطلب إيقاف Container:
docker compose exec homepage wget -q -O- --post-data="" http://dockerproxy:2375/containers/whoami/stopوالمخرج سوف يكون كما يلي:
wget: server returned error: HTTP/1.0 403 Forbiddenبل حتى طلب قائمة ال Images (/images/json) يعود بالرمز 403، والسبب أننا سمحنا بال Containers وحدها، وبهذا الشكل نكون قد تأكدنا أن ثغرة في اللوحة لن تمنح المخترق تحكماً في Docker.
النسخ الاحتياطي والاستعادة Restore
كل ما تحتاجه Homepage موجود في المجلد config/ والملف compose.yaml، والملف .env إن وجد، ولا توجد فيها قاعدة بيانات Database، لذلك لا تحتاج إلى إيقاف الخدمة قبل النسخ:
cd /opt
sudo tar czf homepage-$(date +%F).tar.gz --exclude=homepage/config/logs homepageوالأفضل أن تجعل /opt/homepage مستودع Git خاصاً Repository، وتستثني .env وconfig/logs في .gitignore، فيبقى لديك سجل بكل تعديل ومن قام به. ثم انقل الأرشيف Archive إلى خارج السيرفر، والسبب أن النسخة المحفوظة على نفس القرص لن تنفعك إذا فقدت القرص نفسه. وللاستعادة فك الأرشيف في /opt، وتأكد أن ملكية Ownership المجلد config/ هي 1000:1000، ثم نفذ docker compose up -d.
التحديث Upgrade إلى إصدار أحدث
- راجع صفحة الإصدارات Releases، خاصة عندما يتغير رقم الإصدار الرئيسي Major Version، والسبب أن بعض الأدوات تغير أسماء حقولها بين الإصدارات.
- خذ نسخة من
config/كما في القسم السابق. - غير الوسم في
compose.yaml، وغير وسم ال Socket Proxy إذا صدر له إصدار أحدث، ثم نفذ:
cd /opt/homepage
docker compose pull
docker compose up -d
docker compose logs --tail 30 homepageبعد ذلك ابحث في السجل عن أخطاء في قراءة YAML أو تحذيرات عن حقول لم تعد مدعومة، وإذا ظهرت مشكلة فالرجوع إلى الإصدار السابق Rollback سهل، حيث تعيد الوسم القديم وتنفذ docker compose up -d من جديد.
مشكلات شائعة وحلولها Troubleshooting
صفحة فارغة أو الرسالة Host validation failed
السبب أن اسم المضيف الذي فتحت به اللوحة، ومعه المنفذ إن كتبته، غير موجود في HOMEPAGE_ALLOWED_HOSTS، وسوف تجد الاسم المرفوض في السجل بعد العبارة Host validation failed for:، فأضفه كما هو وأعد إنشاء ال Container بالأمر docker compose up -d. وتجد حالات أخرى في صفحة استكشاف الأخطاء.
لماذا تعرض بطاقة ال Container خطأ أو لا تظهر حالتها؟
- قيمة
containerيجب أن تطابق اسم ال Container كما يظهر فيdocker ps، وليس اسم الخدمة في Compose، ولهذا نستخدمcontainer_name. - قيمة
serverيجب أن تطابق اسماً معرفاً فيdocker.yaml. - تأكد أن Homepage وال Socket Proxy على الشبكة نفسها، حيث يجب أن يعيد الأمر
docker compose exec homepage wget -q -O- http://dockerproxy:2375/versionبيانات JSON. - الرمز
403في السجل يعني أن ال Socket Proxy يمنع ما تطلبه Homepage، ولاحظ أن الإعدادCONTAINERS=1يكفي لعرض الحالة والإحصاءات، فلا تفتح صلاحيات أخرى لحل هذه المشكلة.
لماذا لا تظهر الخدمات المعرفة بالوسوم؟
الاكتشاف يحتاج إلى ملف docker.yaml معرف، وإلى Container يحمل على الأقل الوسمين homepage.group وhomepage.name، ويمكنك أن تتحقق من الوسوم بالأمر docker inspect whoami --format '{{json .Config.Labels}}'. وتذكر أن Docker يقرأ الوسوم عند إنشاء ال Container فقط، لذلك فأي تعديل عليها يحتاج إلى docker compose up -d لل Container المعني.
لا تظهر الأيقونات
السبب إما أن الاسم أو الامتداد غير موجود في مجموعة الأيقونات (مثل homepage.svg مكان homepage.png)، وإما أن متصفح المستخدم لا يصل إلى شبكة CDN التي تأتي منها الأيقونات. وفي البيئات المعزولة Air-gapped ضع الأيقونات في مجلد تركبه على /app/public/icons (مثل ./icons:/app/public/icons:ro)، ثم أشر إليها بـ /icons/اسم-الملف.svg.
خطأ في YAML يعطل الصفحة
مسافة زائدة واحدة أو علامة تبويب Tab واحدة تكفي لتعطيل الصفحة، لذلك افحص الملف قبل الحفظ بالأمر docker run --rm -v "$PWD/config":/c:ro mikefarah/yq:4.53.6 '.' /c/services.yaml (أداة yq)، أو بأي أداة فحص Linter لملفات YAML في المحرر Editor الذي تستخدمه، ثم راجع docker compose logs homepage.
الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- المفضلة في المتصفح لا يراها الفريق ولا تخبرك بحالة الخدمات، أما Homepage فتجمع الروابط وحالة ال Containers في صفحة واحدة، وكل إعدادها ملفات YAML تحفظها في Git.
- لا تركب
/var/run/docker.sockداخل اللوحة، وإنما ضع بينهما Socket Proxy بالإعدادCONTAINERS=1وPOST=0على شبكة داخلية، وشغل Homepage بمستخدم غير root. - المتغير
HOMEPAGE_ALLOWED_HOSTSإلزامي، وأي اسم غير موجود فيه يعود بالرمز400. - لا تطلب Homepage تسجيل دخول في إعدادها الافتراضي، لذلك ضعها خلف Forward Auth أو VPN أو قائمة وصول، ومرر مفاتيح الأدوات عبر متغيرات
HOMEPAGE_VAR_بصلاحية قراءة فقط. - انسخ
config/وcompose.yamlو.envإلى خارج السيرفر، وثبت الوسم بالرقم الكامل وراجع صفحة الإصدارات قبل كل تحديث.
سجل التحديثات (Changelog)
- سبتمبر 2026: كتابة الدليل واختباره على Homepage v2.4.0.
- أكتوبر 2026: مراجعة الدليل واختباره من جديد على الإصدار نفسه، وتصحيح ما يخص تسجيل الدخول (بوابة الدخول التي أضافها الإصدار 2.0 ومعطلة افتراضياً)، وتوضيح أن
localhost:3000مسموح دائماً، وأن وسميserverوcontainerاختياريان في الاكتشاف التلقائي، وإضافة رابط دليل WireGuard.