كيف تحول حاسوبك القديم إلى خادم سحابي Home Server باستخدام Docker؟

هل لديك حاسوب قديم يجمع الغبار في المنزل؟ بدلًا من ترك القرص الصلب بداخله بلا استخدام، يمكنك تحويله إلى خادم منزلي يوفر لك مساحة تخزين خاصة تصل إليها من أجهزتك المختلفة، دون دفع اشتراك شهري لخدمات التخزين السحابي. في هذا الدليل سنبني Home Server بسيطًا باستخدام Ubuntu + Docker + Nextcloud، بحيث تحصل في النهاية على سحابة شخصية شبيهة بـ Google Drive أو OneDrive، ولكن البيانات تكون مخزنة على جهازك.
مهم: الخادم المنزلي ليس بديلًا كاملًا للنسخ الاحتياطي. إذا تعطل القرص الصلب أو تعرض الجهاز للتلف أو السرقة، فقد تفقد بياناتك. لذلك سنوضح أيضًا كيف تتعامل مع هذه المشكلة.
ماذا سنبني؟
المخطط النهائي سيكون بسيطًا:
الحاسوب القديم → Ubuntu → Docker → Nextcloud → ملفاتك
وسيكون بإمكانك:
- رفع الملفات وتنزيلها.
- إنشاء مجلدات وتنظيمها.
- الوصول إلى الملفات من الهاتف والكمبيوتر.
- مشاركة الملفات.
- مزامنة مجلدات محددة.
- الاحتفاظ ببياناتك على قرصك بدلًا من خدمة تخزين مدفوعة.
والأهم أن Docker سيجعل تشغيل Nextcloud وإدارته أسهل، بدل تثبيت كل مكون يدويًا على نظام التشغيل.
1. هل جهازك القديم مناسب؟
لا تحتاج إلى جهاز قوي جدًا لهذا المشروع.
للاستخدام الشخصي، جهاز قديم بمعالج 64-bit وذاكرة RAM مناسبة يمكن أن يكون كافيًا، خصوصًا إذا كان الاستخدام الأساسي هو تخزين الملفات.
لكن هناك فرق مهم:
إذا كان الجهاز يحتوي على SSD، استخدمه لنظام التشغيل وDocker.
أما ملفاتك الكبيرة، فيمكن تخزينها على HDD إضافي.
مثال عملي:
SSD 120GB ├── Ubuntu ├── Docker └── Nextcloud HDD 2TB └── ملفات المستخدمين
ولا تحتاج إلى بطاقة رسومية لهذا المشروع.
2. لماذا Ubuntu بدل Windows؟
يمكن تشغيل Docker على Windows، لكن إذا كان هدفك تحويل الجهاز إلى خادم يعمل 24/7، فأنا أفضل Linux.
السبب بسيط:
- استهلاك موارد أقل.
- إدارة أسهل عن طريق SSH.
- مناسب أكثر للخوادم.
- Docker Engine يعمل بشكل مباشر.
- لا تحتاج إلى تشغيل واجهة رسومية باستمرار.
سنستخدم Ubuntu 24.04 LTS في هذا الدليل.
Docker يدعم حاليًا Ubuntu 24.04 LTS رسميًا، إلى جانب إصدارات Ubuntu الأخرى المدعومة.
3. ثبّت Ubuntu على الجهاز القديم
قم بتثبيت Ubuntu 24.04 LTS على الجهاز.
أثناء التثبيت، إذا كان الجهاز سيستخدم كخادم فقط، فلا تحتاج إلى تثبيت بيئة سطح المكتب الكاملة.
يمكنك اختيار إعداد خادم بسيط ثم إدارة الجهاز من جهاز آخر باستخدام SSH.
بعد انتهاء التثبيت، حدّث النظام:
sudo apt update sudo apt upgrade -y
ثم أعد تشغيل الجهاز:
sudo reboot
بعد عودة الجهاز، أصبح لدينا نظام تشغيل نظيف يمكن بناء الخادم فوقه.
4. أعطِ الخادم عنوان IP ثابتًا
هذه خطوة مهمة جدًا.
لنفرض أن الراوتر أعطى جهاز الخادم العنوان:
192.168.1.50
لا نريد أن يتغير هذا العنوان غدًا إلى:
192.168.1.72
لذلك الأفضل أن تدخل إلى إعدادات الراوتر وتعمل DHCP Reservation للجهاز.
مثال:
Home Server IP: 192.168.1.50
بهذه الطريقة سيحصل الجهاز على نفس العنوان داخل الشبكة.
5. تثبيت Docker
هنا سنستخدم الطريقة الرسمية لتثبيت Docker Engine.
أولًا:
sudo apt update sudo apt install ca-certificates curl -y
أنشئ مجلد مفاتيح Docker:
sudo install -m 0755 -d /etc/apt/keyrings
ثم أضف مفتاح Docker الرسمي:
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ -o /etc/apt/keyrings/docker.asc
واجعل المفتاح قابلًا للقراءة:
sudo chmod a+r /etc/apt/keyrings/docker.asc
ثم أضف مستودع Docker:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
حدّث المستودعات:
sudo apt update
ثم ثبّت Docker والـ Compose:
sudo apt install docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin -y
هذه هي الحزم التي توصي بها وثائق Docker الرسمية للتثبيت عبر مستودع Ubuntu.
6. تأكد من أن Docker يعمل
نفّذ:
sudo systemctl status docker
إذا كان كل شيء صحيحًا، يجب أن ترى أن الخدمة تعمل.
ثم اختبر Docker:
sudo docker run hello-world
إذا ظهرت رسالة الترحيب، فـ Docker يعمل بشكل صحيح.
7. اجعل Docker يعمل بدون sudo
لتسهيل إدارة الخادم، أضف المستخدم الحالي إلى مجموعة Docker:
sudo usermod -aG docker $USER
بعد ذلك سجّل الخروج ثم ادخل مرة أخرى.
اختبر:
docker ps
إذا عمل الأمر بدون sudo، فأنت جاهز.
8. لماذا نستخدم Docker Compose؟
بدل تشغيل كل Container بأوامر منفصلة، سنستخدم ملفًا واحدًا يسمى:
compose.yaml
يحتوي على الخدمات التي نريد تشغيلها وإعداداتها.
وبعد ذلك يكفي تنفيذ:
docker compose up -d
لتشغيل النظام بالكامل.
هذه إحدى نقاط قوة Docker Compose: يمكنك تعريف الخدمات والشبكات والتخزين في ملف واحد وإدارة المجموعة بأكملها من خلاله.
9. إنشاء مشروع الخادم
أنشئ مجلد المشروع:
mkdir -p ~/home-server cd ~/home-server
سنضع داخله إعدادات الخدمات:
home-server/ ├── compose.yaml └── data/
أنشئ مجلد البيانات:
mkdir -p data
10. تشغيل Nextcloud
الآن نصل إلى الجزء المهم.
سنستخدم Nextcloud كواجهة السحابة الشخصية.
لكن هناك نقطة مهمة جدًا:
لا أنصح بتشغيل Nextcloud مع قاعدة بيانات داخل Container بدون تخزين دائم.
لأن الـ Container نفسه قابل للحذف والاستبدال.
Docker يوضح أن البيانات المكتوبة داخل الطبقة القابلة للكتابة الخاصة بالـ Container لا ينبغي الاعتماد عليها كآلية تخزين دائمة؛ لذلك نستخدم Volumes أو Bind Mounts للبيانات التي نريد الاحتفاظ بها.
سنجهز لذلك تخزينًا دائمًا.
أنشئ ملف:
nano compose.yaml
ثم ضع فيه:
services:
nextcloud:
image: nextcloud:latest
container_name: nextcloud
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./data/nextcloud:/var/www/html
depends_on:
- db
db:
image: mariadb:11
container_name: nextcloud-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: CHANGE_THIS_ROOT_PASSWORD
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: CHANGE_THIS_DATABASE_PASSWORD
volumes:
- ./data/db:/var/lib/mysql
لا تستخدم كلمات المرور الموجودة في المثال كما هي.
غيّر:
CHANGE_THIS_ROOT_PASSWORD
و:
CHANGE_THIS_DATABASE_PASSWORD
إلى كلمات مرور قوية.
11. تشغيل الخادم
احفظ الملف ثم نفّذ:
docker compose up -d
تحقق من الحاويات:
docker compose ps
يجب أن ترى:
nextcloud nextcloud-db
وتكون حالتهما:
Up
إذا أردت مشاهدة السجلات:
docker compose logs -f
وللخروج من عرض السجلات:
CTRL + C
لن تتوقف الحاويات عند الضغط على CTRL + C إذا كنت شغلتها باستخدام:
docker compose up -d
12. افتح Nextcloud
من أي جهاز داخل نفس الشبكة، افتح المتصفح:
http://192.168.1.50:8080
استبدل:
192.168.1.50
بعنوان IP الخاص بخادمك.
ستظهر لك شاشة إعداد Nextcloud.
اختر:
اسم المستخدم
و:
كلمة مرور قوية
ثم إعداد قاعدة البيانات:
Database user: nextcloud Database password: كلمة المرور التي وضعتها في compose.yaml Database name: nextcloud Database host: db
لاحظ شيئًا مهمًا:
لا تكتب:
localhost
في خانة Database Host.
نحن نستخدم Docker Network، ولذلك اسم الخدمة:
db
هو عنوان قاعدة البيانات من داخل شبكة Docker.
13. الآن أصبح لديك Cloud خاص بك
بعد إتمام الإعداد، يمكنك تسجيل الدخول إلى:
http://192.168.1.50:8080
وستجد واجهة Nextcloud.
يمكنك الآن:
📁 إنشاء مجلدات.
⬆️ رفع الملفات.
⬇️ تنزيل الملفات.
🔗 مشاركة الملفات.
📱 الوصول إليها من الهاتف.
💻 مزامنة الملفات مع الكمبيوتر.
وهنا يبدأ الجهاز القديم فعليًا في أداء وظيفة تشبه Google Drive، ولكن التخزين موجود على جهازك.
⚠️ لكن لا تفعل هذه الخطوة بعد
قد تفكر الآن:
ممتاز، سأفتح المنفذ 8080 في الراوتر وأصل إلى الملفات من الإنترنت.
لا تفعل ذلك.
فتح Nextcloud مباشرة على الإنترنت بهذه الطريقة ليس التصميم الذي أوصي به.
أنت الآن لديك خدمة تحتوي على ملفات شخصية، وبالتالي يجب أن نفصل بين:
الوصول المحلي
و
الوصول الآمن من الإنترنت.
في الجزء التالي من الدليل سنضيف:
Internet ↓ HTTPS ↓ Reverse Proxy ↓ Nextcloud ↓ Database
وسنحتاج أيضًا إلى التفكير في:
- اسم نطاق Domain.
- HTTPS وشهادة TLS.
- الوصول من الهاتف خارج المنزل.
- DDNS إذا كان عنوان الإنترنت متغيرًا.
- حماية الراوتر.
- النسخ الاحتياطي.
- ماذا يحدث إذا انقطع الإنترنت.
- ماذا يحدث إذا مات القرص الصلب.
وهذه النقطة بالذات هي التي تحول المشروع من "جهاز قديم يشغل Docker" إلى Home Server يمكن الاعتماد عليه فعليًا.
الخلاصة حتى الآن
إذا نفذت الخطوات السابقة، أصبح لديك:
[Old PC]
│
├── Ubuntu
│
└── Docker
│
├── Nextcloud
│
└── MariaDB
│
└── Persistent Storage
المرحلة التالية التي أنصح أن نبنيها في المقال:
تأمين الوصول من الإنترنت باستخدام Cloudflare Tunnel بدل فتح منافذ الراوتر مباشرة؛ هذا أبسط وأقل خطورة للمستخدم المنزلي، وسنجعل الوصول مثل:
https://cloud.example.com
بدل:
http://IP:8080
13. الوصول إلى السحابة من الإنترنت بأمان
حتى الآن يعمل Nextcloud داخل الشبكة المنزلية:
http://192.168.1.50:8080
لكن هذا العنوان لن يعمل عندما تكون خارج المنزل.
هناك طرق كثيرة لفتح الخادم على الإنترنت، لكننا لن نفتح منفذ 80 أو 443 في الراوتر.
بدلًا من ذلك سنستخدم Cloudflare Tunnel.
الفكرة:
الهاتف / الكمبيوتر
↓
https://cloud.example.com
↓
Cloudflare
↓
Encrypted Tunnel
↓
cloudflared
↓
Docker Network
↓
Nextcloud
ميزة هذا الأسلوب أن الاتصال من الخادم إلى Cloudflare يكون اتصالًا صادرًا، وبالتالي لا تحتاج إلى فتح منفذ وارد في الراوتر.
14. ما الذي تحتاجه؟
قبل البدء تحتاج إلى:
- حساب Cloudflare.
- Domain تمتلكه.
- أن يكون الـ Domain مضافًا إلى Cloudflare.
- أن يكون الخادم متصلًا بالإنترنت.
لا تحتاج إلى IP ثابت من مزود الإنترنت.
ولا تحتاج إلى DDNS عند استخدام Cloudflare Tunnel.
إذا كان لديك مثلًا:
example.com
سنستخدم:
cloud.example.com
للوصول إلى Nextcloud.
15. إنشاء Cloudflare Tunnel
ادخل إلى لوحة Cloudflare.
اذهب إلى:
Networking → Tunnels
ثم اختر:
Create a tunnel
اختر:
Cloudflared
وأعطِ الـ Tunnel اسمًا واضحًا، مثل:
home-server
ثم أنشئ الـ Tunnel.
Cloudflare يوفر حاليًا طريقة لإنشاء Tunnel مُدار عن بُعد والحصول على Tunnel Token لتشغيل cloudflared.
بعد إنشاء الـ Tunnel، ستجد أمر تشغيل يحتوي على Token يبدأ عادةً بـ:
eyJ...
لا تنشر هذا الـ Token في مقال أو GitHub أو لقطة شاشة.
امتلاك هذا الـ Token يسمح بتشغيل Tunnel الخاص بك، لذلك اعتبره كلمة مرور. Cloudflare نفسها توصي بتدوير الـ Tokens دوريًا عند الحاجة.
16. لا تشغّل أمر Cloudflare الذي يعطيك إياه الموقع كما هو
Cloudflare قد يعرض لك أمرًا مثل:
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token YOUR_TOKEN
هذا صالح لتشغيل Tunnel، لكننا نريد إدارة كل شيء من خلال Docker Compose.
لذلك سنضع cloudflared داخل ملف compose.yaml الموجود لدينا.
لكن قبل ذلك نحتاج إلى تعديل الشبكة.
17. إنشاء شبكة Docker مخصصة
اذهب إلى مجلد المشروع:
cd ~/home-server
افتح ملف Compose:
nano compose.yaml
استبدل محتوى الملف بالكامل بالنسخة التالية:
services:
nextcloud:
image: nextcloud:latest
container_name: nextcloud
restart: unless-stopped
ports:
- "8080:80"
environment:
- APACHE_DISABLE_REWRITE_IP=1
- TRUSTED_PROXIES=172.20.0.0/16
- FORWARDED_FOR_HEADERS=HTTP_X_FORWARDED_FOR
volumes:
- ./data/nextcloud:/var/www/html
depends_on:
- db
networks:
- homecloud
db:
image: mariadb:11
container_name: nextcloud-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: CHANGE_THIS_ROOT_PASSWORD
MYSQL_DATABASE: nextcloud
MYSQL_USER: nextcloud
MYSQL_PASSWORD: CHANGE_THIS_DATABASE_PASSWORD
volumes:
- ./data/db:/var/lib/mysql
networks:
- homecloud
cloudflared:
image: cloudflare/cloudflared:latest
container_name: cloudflared
restart: unless-stopped
command:
- tunnel
- --no-autoupdate
- run
- --token
- ${TUNNEL_TOKEN}
networks:
- homecloud
networks:
homecloud:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
لماذا أضفنا هذه الإعدادات؟
لأن cloudflared أصبح داخل نفس شبكة Docker التي يوجد فيها Nextcloud.
وبالتالي يستطيع الوصول إليه باستخدام:
http://nextcloud:80
وليس:
http://localhost:8080
وهذه نقطة مهمة جدًا.
داخل حاوية cloudflared:
localhost
يعني حاوية cloudflared نفسها، وليس جهاز Ubuntu وليس حاوية Nextcloud.
18. ضع الـ Tunnel Token في ملف منفصل
لا أنصح بوضع الـ Token مباشرة داخل compose.yaml.
أنشئ ملف:
nano .env
ضع فيه:
TUNNEL_TOKEN=ضع_التوكن_الذي_أعطاك_إياه_Cloudflare_هنا
مثال شكلي فقط:
TUNNEL_TOKEN=eyJxxxxxxxxxxxxxxxxxxxxxxxx
ثم احفظ الملف.
أعطِ الملف صلاحيات مناسبة:
chmod 600 .env
والآن أصبح لدينا:
home-server/
├── compose.yaml
├── .env
└── data/
├── nextcloud/
└── db/
19. تأكد من إعدادات Docker قبل تشغيلها
هذه خطوة أريد منك ألا تتجاوزها.
نفّذ:
docker compose config
إذا كانت الصياغة صحيحة، سيعرض Docker الـ configuration النهائي.
إذا ظهر:
yaml: ...
أو أي خطأ، توقف هنا ولا تنفذ up.
إذا لم يظهر خطأ في الصياغة، ننتقل للخطوة التالية.
20. إعادة تشغيل الخدمات
نفّذ:
docker compose up -d
ثم:
docker compose ps
المفترض أن ترى الخدمات الثلاث:
nextcloud nextcloud-db cloudflared
وحالتها:
Up
إذا أردت التأكد من Tunnel تحديدًا:
docker logs cloudflared
ابحث عن رسالة تشير إلى أن الـ Tunnel أصبح متصلًا.
يمكنك أيضًا:
docker logs cloudflared --tail 50
لعرض آخر 50 سطرًا فقط.
21. اختبار الاتصال بين Cloudflare وNextcloud
قبل أن نربط الـ Domain، نختبر أن cloudflared يستطيع الوصول إلى Nextcloud.
نفّذ:
docker exec cloudflared wget -qO- http://nextcloud:80/status.php
المفترض أن تحصل على JSON قريب من:
{
"installed": true,
"maintenance": false,
"needsDbUpgrade": false
}
إذا ظهر هذا، فهذا يعني أن:
cloudflared
↓
Docker Network
↓
Nextcloud
يعمل بشكل صحيح.
22. ربط الـ Domain بـ Nextcloud
ارجع إلى Cloudflare Dashboard.
افتح الـ Tunnel الذي أنشأناه.
اذهب إلى:
Routes → Add route → Published application
ثم:
Hostname
اختر الـ Domain الخاص بك واكتب:
cloud
بحيث يصبح:
cloud.example.com
Service
اكتب:
http://nextcloud:80
وليس:
http://localhost:8080
وليس:
http://192.168.1.50:8080
لأن cloudflared يتصل بـ Nextcloud من داخل شبكة Docker.
Cloudflare يعرّف الـ Published Application كربط بين hostname عام وخدمة داخلية، ويمكن أن تكون الخدمة مثل http://localhost:8080 عندما يكون الطرفان على نفس الـ host؛ في حالتنا نحن نستفيد من شبكة Docker، لذلك يكون اسم الخدمة nextcloud:80 هو العنوان الصحيح من داخل الـ network.
23. لا تفتح أي Port في الراوتر
هذه النقطة يجب أن تكون واضحة في المقال.
لا تعمل Port Forwarding لـ:
80 443 8080
Cloudflare Tunnel مصمم للعمل بدون فتح منافذ inbound على الخادم.
اتصال الخادم سيكون:
Home Server
│
│ outbound
↓
Cloudflare
وليس:
Internet
│
│ inbound
↓
Home Router
↓
Home Server
وهذا يقلل سطح التعرض للخادم بشكل كبير.
24. إضافة الـ Domain إلى Nextcloud
هناك خطوة أخرى مهمة.
Nextcloud لديه حماية تسمى:
trusted_domains
وهي تحدد أسماء النطاقات المسموح باستخدامها للوصول إلى الخادم. إذا لم تضف cloud.example.com، فقد تحصل على:
Access through untrusted domain
وثائق Nextcloud توضح أن كل hostname مستخدم للوصول إلى الخادم يجب أن يكون موجودًا في trusted_domains.
نفّذ:
docker exec --user www-data nextcloud php occ config:system:set trusted_domains 1 --value=cloud.example.com
استبدل:
cloud.example.com
بالـ Domain الحقيقي.
ثم تحقق:
docker exec --user www-data nextcloud php occ config:system:get trusted_domains
يجب أن ترى عنوان الـ Domain ضمن القائمة.
25. أخبر Nextcloud أن الاتصال الخارجي HTTPS
هنا توجد نقطة مهمة جدًا.
المستخدم يتصل:
https://cloud.example.com
لكن Cloudflare Tunnel يرسل الطلب داخليًا إلى:
http://nextcloud:80
لذلك Nextcloud قد يعتقد أن المستخدم يستخدم HTTP.
وهذا قد يؤدي إلى:
- Redirect خاطئ.
- روابط HTTP بدل HTTPS.
- تحذيرات أمنية.
- مشاكل في بعض الـ cookies.
Nextcloud يوفر overwriteprotocol تحديدًا لهذه الحالات.
نفّذ:
docker exec --user www-data nextcloud php occ config:system:set overwriteprotocol --value=https
ثم:
docker exec --user www-data nextcloud php occ config:system:set overwrite.cli.url --value=https://cloud.example.com
واستبدل الـ Domain بالطبع.
26. ضبط الـ Reverse Proxy بشكل صحيح
نحن أضفنا:
TRUSTED_PROXIES=172.20.0.0/16
لأن cloudflared موجود داخل الشبكة:
172.20.0.0/16
ووضعنا:
FORWARDED_FOR_HEADERS=HTTP_X_FORWARDED_FOR
حتى يستطيع Nextcloud التعامل مع عنوان العميل الذي يصل عبر الـ proxy.
وثائق Nextcloud تحذر تحديدًا من أن إعداد trusted_proxies بشكل خاطئ يمكن أن يسمح بتزييف عناوين IP، ولذلك لا ينبغي استخدام 0.0.0.0/0 أو فتح الثقة لأي Proxy عشوائي.
27. اختبار الموقع من خارج المنزل
الآن افتح من هاتفك باستخدام بيانات الهاتف وليس Wi-Fi المنزل:
https://cloud.example.com
إذا ظهرت صفحة تسجيل دخول Nextcloud، فقد نجح الجزء الأصعب.
اختبر:
- تسجيل الدخول.
- رفع ملف صغير.
- تنزيل الملف.
- إنشاء مجلد.
- مشاركة ملف.
- فتح الرابط من جهاز آخر.
28. اختبار HTTPS
يجب أن يكون العنوان:
https://cloud.example.com
وليس:
http://cloud.example.com
ولا تحتاج إلى تركيب شهادة SSL يدويًا داخل Nextcloud في هذا التصميم؛ Cloudflare يتولى اتصال HTTPS من المستخدم إلى Cloudflare، بينما Tunnel ينقل الطلب إلى الخدمة الداخلية. إعداد overwriteprotocol=https يجعل Nextcloud يولّد الروابط باعتبار الاتصال الخارجي HTTPS.
29. ماذا لو ظهر "Access through untrusted domain"؟
تحقق من:
docker exec --user www-data nextcloud php occ config:system:get trusted_domains
إذا لم تجد:
cloud.example.com
أضفه:
docker exec --user www-data nextcloud php occ config:system:set trusted_domains 1 --value=cloud.example.com
ثم أعد تحميل الصفحة.
30. ماذا لو حدث Redirect لا نهائي؟
تحقق من:
docker exec --user www-data nextcloud php occ config:system:get overwriteprotocol
يجب أن تكون النتيجة:
https
وتحقق أيضًا:
docker exec --user www-data nextcloud php occ config:system:get overwrite.cli.url
يجب أن تكون:
https://cloud.example.com
هذا الإعداد مهم لأن Nextcloud قد لا يستطيع اكتشاف البروتوكول الخارجي بنفسه عندما تكون طبقة HTTPS موجودة أمامه.
31. اختبار حالة الخدمات
نفّذ:
docker compose ps
ثم:
docker logs cloudflared --tail 50
ثم:
docker logs nextcloud --tail 50
وأخيرًا:
docker logs nextcloud-db --tail 50
إذا كانت الخدمات تعمل بدون أخطاء واضحة، فالبنية الأساسية أصبحت:
INTERNET
│
▼
┌──────────────┐
│ Cloudflare │
│ HTTPS │
└───────┬──────┘
│
Cloudflare Tunnel
│
▼
┌──────────────┐
│ cloudflared │
└───────┬──────┘
│
Docker Network
│
┌──────┴──────┐
▼ ▼
Nextcloud MariaDB
│
▼
Persistent Storage
⚠️ 32. لكن لدينا مشكلة أكبر يجب حلها قبل اعتبار الخادم جاهزًا
في هذه المرحلة لا أنصح بكتابة عبارة "استغنِ عن خدمات التخزين المدفوعة" في المقال وكأن المشكلة انتهت.
لأننا حتى الآن لدينا:
نسخة واحدة من البيانات
↓
HDD واحد
إذا مات الـ HDD:
قد تختفي ملفاتك.
إذا سُرق الجهاز:
قد تختفي ملفاتك.
إذا حدث تلف في نظام الملفات:
قد تختفي ملفاتك.
إذا أصاب الجهاز Ransomware ووصل إلى الملفات:
قد تتضرر النسخة الأصلية والنسخ المتصلة بها.
لذلك الجزء التالي في الدليل ليس اختياريًا.
سنضيف:
المرحلة التالية — Backup حقيقي
سننشئ:
Nextcloud
│
▼
Main Disk
│
┌───────┴───────┐
▼ ▼
Local Backup External Backup
وسنشرح تحديدًا:
- كيف نعمل Backup لقاعدة MariaDB.
- كيف ننسخ بيانات Nextcloud.
- لماذا لا يكفي نسخ مجلد
dataفقط. - كيف نستخدم قرص USB خارجي.
- كيف نجعل النسخ الاحتياطي تلقائيًا.
- كيف نختبر أن النسخة الاحتياطية قابلة للاستعادة فعلًا.
وهنا بالذات لن نستخدم أمرًا عشوائيًا مثل cp -r ونقول للمستخدم إن لديه Backup. سنبني استراتيجية استعادة حقيقية؛ لأن الهدف من الـ Backup ليس أن يكون لديك ملف اسمه backup، بل أن تستطيع استعادة
الخادم عندما يحدث عطل.
33. لا تعتمد على القرص الأصلي فقط
وصلنا الآن إلى أهم جزء في المشروع: النسخ الاحتياطي.
وجود Nextcloud على جهازك لا يعني أن بياناتك أصبحت آمنة. أنت فقط نقلت البيانات من خوادم شركة إلى جهاز تملكه أنت.
إذا تعطل القرص، فستحتاج إلى نسخة أخرى.
ووفقًا لوثائق Nextcloud، النسخة الاحتياطية الصحيحة يجب أن تشمل على الأقل:
- ملفات الإعدادات
config. - مجلد البيانات
data. - الـ themes.
- التطبيقات المخصصة إذا كنت تستخدمها.
- قاعدة البيانات.
وبما أن إعدادنا يستخدم:
./data/nextcloud:/var/www/html
فإن مجلد:
data/nextcloud
يحتوي على تثبيت Nextcloud وملفاته المهمة، بما فيها config وdata.
أما قاعدة MariaDB، فلا ننسخ مجلد قاعدة البيانات كبديل عن Backup حقيقي؛ سنأخذ منها Dump يمكن استعادته.
34. أضف قرصًا خارجيًا للنسخ الاحتياطي
أفضل بداية لهذا المشروع هي استخدام قرص USB خارجي.
مثال:
الجهاز القديم
│
├── قرص النظام
│
└── قرص USB خارجي
│
└── Backup
إذا كان لديك قرص 2TB مثلًا، فلا يلزم أن يكون بنفس حجم قرص البيانات تمامًا إذا كانت بياناتك الفعلية أقل من ذلك.
مهم: لا تجعل قرص النسخ الاحتياطي متاحًا دائمًا للكتابة من جميع الأجهزة. كلما كان منفصلًا عن الخادم عند عدم الحاجة إليه، كان ذلك أفضل ضد بعض سيناريوهات التلف أو البرمجيات الخبيثة.
35. معرفة اسم القرص الخارجي
بعد توصيل القرص، نفّذ:
lsblk
ستظهر قائمة بالأقراص.
مثال:
NAME SIZE TYPE MOUNTPOINTS sda 120G disk ├─sda1 512M part /boot/efi └─sda2 119G part / sdb 2T disk └─sdb1 2T part
في هذا المثال:
sda
هو قرص Ubuntu.
و:
sdb
هو القرص الخارجي.
لا تفترض أن جهازك يستخدم sdb.
قد يظهر القرص باسم مختلف.
36. تحذير مهم قبل تهيئة القرص
إذا كان القرص يحتوي بالفعل على ملفات مهمة، لا تنفذ أي أمر mkfs.
أمر مثل:
sudo mkfs.ext4 /dev/sdb1
سيؤدي إلى تهيئة القسم وحذف البيانات الموجودة عليه.
لذلك إذا كان القرص جديدًا أو لا يحتوي على بيانات مهمة، يمكننا تهيئته.
أما إذا كان مستخدمًا بالفعل، احتفظ بنظام الملفات الموجود واستخدمه بعد التأكد من القسم الصحيح.
37. إنشاء مكان للقرص
سنستخدم:
sudo mkdir -p /mnt/backup
ثم نركب القرص:
sudo mount /dev/sdb1 /mnt/backup
استبدل /dev/sdb1 بالقسم الصحيح الذي ظهر عندك في lsblk.
تحقق:
df -h /mnt/backup
يجب أن ترى مساحة القرص الخارجي.
مثال:
Filesystem Size Used Avail Use% /dev/sdb1 1.8T 20G 1.7T 2%
38. اجعل القرص يُركب تلقائيًا
هناك مشكلة إذا اعتمدنا على:
/dev/sdb1
لأن اسم الجهاز قد يتغير في بعض الظروف.
الأفضل استخدام UUID.
احصل عليه:
sudo blkid /dev/sdb1
مثال:
/dev/sdb1: UUID="8f4c7e21-..." TYPE="ext4"
انسخ الـ UUID.
ثم افتح:
sudo nano /etc/fstab
وأضف في آخر الملف:
UUID=8f4c7e21-XXXXXXXX-XXXXXXXX /mnt/backup ext4 defaults,nofail 0 2
استبدل الـ UUID بالقيمة الفعلية.
بعد ذلك اختبر ملف fstab:
sudo mount -a
ثم:
df -h /mnt/backup
إذا ظهر القرص بدون أخطاء، فالإعداد صحيح.
39. أنشئ مجلد النسخ الاحتياطية
سنرتب النسخ بهذا الشكل:
/mnt/backup/
└── nextcloud/
├── 2026-10-06/
├── 2026-10-07/
└── ...
أنشئ المجلد:
sudo mkdir -p /mnt/backup/nextcloud
ثم اجعل المستخدم الحالي قادرًا على الكتابة إليه:
sudo chown -R $USER:$USER /mnt/backup/nextcloud
40. قبل النسخ: فعّل Maintenance Mode
لا نريد أن يكتب المستخدمون ملفات جديدة أثناء أخذ النسخة.
Nextcloud يوصي باستخدام Maintenance Mode أثناء النسخ لمنع حدوث عدم اتساق بين الملفات وقاعدة البيانات.
من مجلد المشروع:
cd ~/home-server
ثم:
docker compose exec -T nextcloud php occ maintenance:mode --on
تحقق:
docker compose exec -T nextcloud php occ maintenance:mode
يجب أن تظهر حالة تشير إلى أن Maintenance Mode مفعّل.
41. أخذ نسخة من ملفات Nextcloud
أنشئ مجلدًا بتاريخ اليوم:
BACKUP_DIR="/mnt/backup/nextcloud/$(date +%F)" mkdir -p "$BACKUP_DIR"
ثم انسخ ملفات Nextcloud:
sudo tar -C data/nextcloud -czf "$BACKUP_DIR/nextcloud-files.tar.gz" .
سيشمل هذا النسخة الكاملة من مجلد Nextcloud، بما في ذلك:
config/ data/ apps/ themes/
وهذا يتوافق مع مبدأ Nextcloud في الاحتفاظ بمجلدات التثبيت والإعدادات والبيانات المطلوبة للاستعادة.
42. أخذ نسخة من قاعدة البيانات
الآن نأخذ Database Dump من MariaDB.
سنستخدم:
docker compose exec -T db sh -c \ 'mariadb-dump --single-transaction --default-character-set=utf8mb4 -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE"' \ > "$BACKUP_DIR/nextcloud-database.sql"
لاحظ أننا لم نكتب كلمة مرور قاعدة البيانات داخل الأمر نفسه.
كما أننا استخدمنا:
--single-transaction
و:
--default-character-set=utf8mb4
وهما متوافقان مع توصيات Nextcloud لنسخ MariaDB، خصوصًا مع دعم Unicode/emoji.
43. تحقق من أن النسخة موجودة
نفّذ:
ls -lh "$BACKUP_DIR"
يجب أن ترى شيئًا شبيهًا:
nextcloud-database.sql nextcloud-files.tar.gz
تحقق من حجم الملفات:
du -h "$BACKUP_DIR"/*
لا تنتقل للخطوة التالية إذا كان أحد الملفات حجمه 0 بايت.
44. أعد تشغيل Nextcloud
بعد انتهاء النسخ:
docker compose exec -T nextcloud php occ maintenance:mode --off
ثم:
docker compose exec -T nextcloud php occ maintenance:mode
يجب أن تكون Maintenance Mode معطلة.
افتح Nextcloud وتأكد أن الملفات ما زالت موجودة.
45. لا تعتبر النسخة الاحتياطية ناجحة بعد
هذه نقطة مهمة جدًا.
وجود:
nextcloud-files.tar.gz
و:
nextcloud-database.sql
لا يعني أن النسخة الاحتياطية صالحة.
الاختبار الحقيقي هو الاستعادة.
وثائق Nextcloud نفسها توضح أن استعادة النظام تحتاج إلى قاعدة البيانات وملفات البيانات والإعدادات، وأنه لا يمكن إكمال الاستعادة بدونها.
لذلك يجب أن نختبر النسخة.
46. اختبار سلامة ملف النسخة
أولًا اختبر أرشيف الملفات:
tar -tzf "$BACKUP_DIR/nextcloud-files.tar.gz" > /dev/null
إذا لم يظهر خطأ، فهذا يعني أن الأرشيف قابل للقراءة.
يمكنك أيضًا:
echo $?
إذا ظهرت:
0
فالعملية نجحت.
47. اختبار قاعدة البيانات
يمكننا اختبار أن ملف SQL ليس فارغًا:
ls -lh "$BACKUP_DIR/nextcloud-database.sql"
ثم:
head -n 20 "$BACKUP_DIR/nextcloud-database.sql"
يجب أن ترى أوامر SQL ومعلومات مرتبطة بقاعدة البيانات.
لا تعدّل الملف.
48. احتفظ بنسخ متعددة
لا نريد:
Backup واحد
بل:
Backup اليوم Backup أمس Backup الأسبوع الماضي
مثلًا:
/mnt/backup/nextcloud/ ├── 2026-10-04/ ├── 2026-10-05/ └── 2026-10-06/
لكن هناك مشكلة:
إذا امتلأ القرص بعد عدة أشهر، سيتوقف النسخ الاحتياطي.
لذلك يمكننا لاحقًا إضافة سياسة احتفاظ مثل:
آخر 7 نسخ يومية + 4 نسخ أسبوعية + 3 نسخ شهرية
وهذا أفضل بكثير من حذف كل شيء عشوائيًا بعد عدد معين من الأيام.
49. اجعل النسخ الاحتياطي تلقائيًا
بعد أن تأكدنا يدويًا أن العملية تعمل، يمكن تحويلها إلى Cron Job.
لكن لا أنصح بوضع Cron الآن قبل اختبار النسخة يدويًا.
الترتيب الصحيح هو:
Manual Backup
↓
Verify
↓
Test Restore
↓
Automation
وليس:
Automation
↓
اكتشف بعد شهر أن النسخ كانت تفشل
وهذه نقطة مهمة جدًا في أي نظام Backup.
50. ماذا لو تعطل الجهاز؟
لنفترض أن القرص الداخلي مات.
لدينا:
Backup ├── nextcloud-files.tar.gz └── nextcloud-database.sql
يمكن إعادة تثبيت Ubuntu وDocker ثم إعادة بناء الخدمات واستعادة البيانات.
لكن لا تحاول استعادة قاعدة البيانات الآن على خادمك العامل كاختبار.
لأن استعادة قاعدة البيانات فوق قاعدة البيانات الحالية قد تتطلب حذف وإعادة إنشاء قاعدة البيانات، وهي عملية مدمرة إذا نُفذت على الخادم الخطأ. وثائق Nextcloud نفسها تنص على ضرورة حذف الجداول/إعادة إنشاء قاعدة البيانات قبل استعادة النسخة.
51. قاعدة ذهبية: لا تختبر Restore على الخادم الإنتاجي
إذا أردت اختبار الاستعادة فعليًا، استخدم:
- جهازًا ثانيًا، أو
- VM، أو
- خادمًا مؤقتًا.
ثم:
Backup ↓ New Server ↓ Restore ↓ Test Login ↓ Test Files ↓ Test Sharing
إذا نجحت العملية، أصبح لديك دليل حقيقي أن الـ Backup صالح.
52. بعد الاستعادة: تحديث بصمة الملفات
إذا تمت استعادة Backup قديم، يوفر Nextcloud أمر:
docker compose exec -T nextcloud php occ maintenance:data-fingerprint
وهو مهم بعد استعادة ملفات أو قاعدة البيانات حتى تستطيع تطبيقات المزامنة اكتشاف التغييرات بشكل صحيح.
53. تحديث Nextcloud بأمان
هنا أيضًا يجب ألا نرتكب خطأ شائعًا:
docker compose pull docker compose up -d
ثم نأمل أن كل شيء يعمل.
لا أنصح بهذا كإجراء تحديث أعمى.
قبل أي تحديث:
Backup ↓ Check compatibility ↓ Update ↓ Database migration ↓ Test
وثائق Nextcloud توصي بوجود Backup حديث قبل كل Upgrade، وتحذر من أن عملية التحديث لا تعتبر Backup لقاعدة البيانات أو مجلد البيانات. كما أن الرجوع إلى إصدار أقدم غير مدعوم وقد يؤدي إلى تلف البيانات.
54. لا تستخدم latest بلا تفكير
في ملفنا السابق استخدمنا:
image: nextcloud:latest
وهنا أريد تصحيحًا مهمًا للمقال.
للتجربة المنزلية البسيطة يمكن أن يعمل، لكن للدليل الذي نريد أن يكون موثوقًا وقابلًا للتكرار، تثبيت Major Version محدد أفضل من ترك Docker يسحب أي إصدار مستقبلي.
Docker Official Image يوضح الإصدارات والعلامات المتاحة، كما يشير إلى أن صورة Docker الرسمية لـ Nextcloud موجهة أكثر للمستخدمين الخبراء، بينما يوفر مشروع Nextcloud أيضًا All-in-One كخيار أبسط لمن يريد تجربة متكاملة.
لذلك في نسخة المقال النهائية سأتعامل مع إدارة الإصدار والتحديث كجزء من التشغيل، وليس مجرد أمر docker pull.
55. فحص حالة Nextcloud
من لوحة Nextcloud اذهب إلى:
Administration settings → Overview
راقب:
- Security & setup warnings.
- Database.
- Background jobs.
- PHP.
- Storage.
- HTTPS.
- Apps.
إذا ظهرت تحذيرات، لا نتجاهلها لمجرد أن الموقع يعمل.
الهدف ليس:
"الموقع فتح."
الهدف:
"الخادم يعمل بطريقة صحيحة ويمكن استعادته."
56. تأكد من عدم فتح منافذ غير ضرورية
على Ubuntu:
sudo ss -tulpn
ويمكنك أيضًا:
sudo ufw status
في تصميم Cloudflare Tunnel، لا نحتاج إلى فتح:
80 443
في الراوتر للوصول إلى Nextcloud.
ولا ينبغي فتح:
3306
لـ MariaDB على الإنترنت.
قاعدة البيانات يجب أن تبقى داخل شبكة Docker.
57. ماذا أصبح لدينا الآن؟
بعد إكمال هذا الجزء، البنية أصبحت:
INTERNET
│
▼
┌───────────────┐
│ Cloudflare │
│ HTTPS / WAF │
└───────┬───────┘
│
Tunnel
│
▼
┌───────────────┐
│ cloudflared │
└───────┬───────┘
│
Docker Network
│
┌─────────────┴─────────────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Nextcloud │ │ MariaDB │
└──────┬──────┘ └─────────────┘
│
▼
Internal Storage
│
│ Backup
▼
┌──────────────┐
│ External HDD │
└──────────────┘
وهنا أصبح لدينا بالفعل Private Cloud وليس مجرد Docker Container.
58. هل استغنينا فعلًا عن Google Drive وOneDrive؟
جزئيًا، وليس 100%.
أنت لم تعد مضطرًا لدفع اشتراك تخزين شهري فقط لكي تمتلك مساحة شخصية.
لكن في المقابل أصبحت مسؤولًا عن:
- الجهاز.
- الكهرباء.
- الإنترنت.
- القرص.
- النسخ الاحتياطي.
- التحديثات.
- الأمان.
- الاستعادة عند حدوث مشكلة.
وهذه هي المفاضلة الحقيقية في الـ Self-Hosting.
الخدمة السحابية المدفوعة تبيعك الراحة والإدارة.
أما الـ Home Server فيعطيك التحكم والخصوصية وتقليل التكلفة الشهرية، مقابل مسؤولية الإدارة.
59. قبل أن تعتبر المشروع مكتملًا
استخدم هذه القائمة:
الخادم
- Ubuntu يعمل.
- Docker يعمل.
- Nextcloud يعمل.
- MariaDB تعمل.
- البيانات محفوظة على Storage دائم.
الوصول
- Domain يعمل.
- HTTPS يعمل.
- Cloudflare Tunnel متصل.
- لا توجد Port Forwarding غير ضرورية.
-
trusted_domainsمضبوط.
Backup
- Backup للـ Nextcloud files.
- Backup لقاعدة البيانات.
- Backup على قرص مختلف.
- أكثر من نسخة محفوظة.
- تم اختبار سلامة الملفات.
- تم اختبار Restore على بيئة منفصلة.
التشغيل
- توجد خطة للتحديث.
- توجد خطة للاستعادة.
- توجد مساحة تخزين كافية.
- لا توجد تحذيرات أمنية مهمة.
الخلاصة
تحويل حاسوب قديم إلى Home Server ليس مجرد تثبيت Docker وتشغيل Nextcloud.
المشروع الحقيقي يتكون من أربع طبقات:
1️⃣ الخدمة
Nextcloud لإدارة الملفات.
2️⃣ البنية
Ubuntu + Docker + MariaDB.
3️⃣ الوصول الآمن
Cloudflare Tunnel + HTTPS + Domain.
4️⃣ الاستمرارية
Backup قابل للاستعادة، وليس مجرد نسخة ملفات.
وهنا تكمن أهم قاعدة في الـ Self-Hosting:
إذا لم تختبر استعادة النسخة الاحتياطية، فلا تفترض أن لديك Backup.
بهذه الطريقة يمكنك إعادة استخدام حاسوب قديم وتحويله إلى سحابة شخصية تصل إليها من هاتفك وكمبيوترك من أي مكان، مع الاحتفاظ بالبيانات على أجهزتك بدل الاعتماد بالكامل على اشتراك تخزين سحابي.
🚀 لم ينتهِ الأمر بعد! في الجزء الثاني سننتقل إلى المستوى الأهم: أتمتة النسخ الاحتياطي، إدارة النسخ القديمة، واختبار استعادة بياناتك فعليًا — لأن امتلاك Backup لا يعني شيئًا إذا لم تكن قادرًا على استعادته.
المراجع الرسمية التي تحققت منها لهذا الجزء: Cloudflare Tunnel Documentation وNextcloud Reverse Proxy Configuration.
كن أول من يعرف بمستقبل التقنية
أهم الأخبار والتحليلات التقنية مباشرة في بريدك.
مقالات قد تهمك

أنشأت سيرفر بريد وتواجه مشكلة السبام؟ إليك خطوات الحل الفعالة (بتقييم 10/10)

إعداد خادم بريد إلكتروني آمن باستخدام Mailcow و Caddy: دليل خطوة بخطوة

كيف تمنع ChatGPT وGemini وClaude من استخدام محادثاتك لتدريب النماذج؟
